ПОЛЯКОВ_ПРЕЗЕНТАЦИИ_С++ / prog_c2
.pdfПрограммирование на языке Си |
К. Поляков, 1995-2002 |
71 |
|
void Year2002( Book &b )
{
b.year = 2002;
}
В этом случае фактически в процедуру передается адрес структуры и процедура работает с тем же экземпляром, что и вызывающая программа. При этом все изменения, сделанные в процедуре, остаются в силе. Работа со структурой-параметром внутри процедуры и вызов этой процедуры из основной программы никак не отличаются от предыдущего варианта.
Передача по адресу
Передача по ссылке возможна только при использовании языка Си++ (она не входит в стандарт языка Си). Тем не менее, в классическом Си можно передать в качестве параметра адрес структуры. При этом обращаться к полям структуры внутри процедуры надо через оператор ->.
void Year2002( Book *b ) |
||
{ |
параметр – адрес структуры |
|
b->year = 2002; |
обращение к полю структуры |
|
} |
||
|
||
void main() |
передается адрес структуры |
|
{ |
||
Book b; |
|
|
Year2002 ( &b ); |
|
|
} |
|
|
Сортировка по ключу |
Поскольку в структуры входит много полей, возникает вопрос: а как их сортировать? Это зависит от конкретной задачи, но существуют общие принципы, о которых мы и будем говорить.
Для сортировки выбирается одно из полей структуры, оно называется ключевым полем или просто ключом. Структуры расставляются в определенном порядке по значению ключевого поля, содержимое всех остальных полей игнорируется.
И еще одна проблема – при сортировке элементы массива меняются местами. Структуры могут быть достаточно больших размеров, и копирование этих структур будет занимать очень много времени. Поэтому
Сортировку массива структур выполняют по указателям.
Мы уже использовали этот прием для сортировки массива символьных строк. В памяти формируется массив указателей p, и сначала они указывают на структуры в порядке расположения их в массиве, то есть указатель p[i] указывает на структуру с номером i. Затем остается только расставить указатели так, чтобы ключевые поля соответствующих структур были отсортированы в заданном порядке. Для решения задачи удобно объявить новый тип данных PBook - указатель на структуру Book.
typedef Book *PBook;
Пример ниже показывает сортировку массива структур по году выпуска книг. Основной алгоритм сортировки массива указателей заложен в процедуру SortYear, которая имеет два параметра - массив указателей и число структур.
72II. Хранение и обработка данных |
|
|
|
К. Поляков, 1995-2002 |
|||||
|
|
|
|
|
|
|
|
|
|
|
|
void SortYear ( PBook p[], int n ) |
|
|
|
||||
{ |
|
|
|
|
|
|
|
||
|
временный указатель |
|
|
|
|
||||
|
|
int i, j; |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
PBook temp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
метод пузырька |
|
||
for ( i = 0; i < n-1; i ++ ) |
|
|
||||
for ( j = n-2; j >= i; j -- ) |
сравнение ключевых |
|||||
if ( p[j+1]->year < p[j]->year ) |
полей |
|
||||
|
{ |
|
|
|
|
|
|
temp = p[j]; |
если указатели стоят неправильно, |
||||
|
p[j] = p[j+1]; |
меняем их местами |
|
|
||
|
p[j+1] = temp; |
|
|
|||
|
|
|
|
|||
} |
} |
|
|
|
|
|
|
|
|
|
|
||
Основная программа, которая выводит на экран информацию о книгах в порядке их выхода, |
||||||
выглядит примерно так: |
|
|
|
|
||
#include <stdio.h> |
|
|
|
|||
const N = 20; |
|
|
|
|
||
struct Book { |
|
|
|
|
||
char author[40]; |
новые типы данных |
|
|
|||
char title[80]; |
|
|
|
|||
int year; |
|
|
|
|
||
int pages; |
|
|
|
|
||
}; |
|
|
|
|
|
|
typedef Book *PBook; |
|
|
|
|||
... // здесь надо расположить процедуру SortYear |
|
|||||
void main() |
|
|
|
|
||
{ |
|
массив указателей |
|
|
||
Book B[N]; |
|
|
||||
PBook p[N]; |
|
|
|
|
||
... |
// здесь ввод данных в структуры |
|
|
|||
for ( i = 0; i < N; i ++ ) |
расставить указатели |
|
||||
p[i] = &B[i]; |
|
|
||||
|
|
|
|
|||
SortYear ( p, N ); |
сортировка по указателям |
вывод через |
||||
for ( i = 0; i < N; i ++ ) |
|
|
||||
|
|
указатели |
||||
printf("%d: %s\n", p[i]->year, p[i]->title); |
||||||
|
||||||
} |
|
|
|
|
|