Дорогой Билли,
Благодарю вас за чудесно проведенный вечер, Билли.
Вы однозначно продемонстрировали, что персональный тренер
являет собою особый тип мужчины. Мы обязательно должны встретиться
за восхитительным ужином с запеченными омарами и весело провести время.
До скорой встречи,
Шейла
Во-первых, обратите внимание на то, каким образом вложенная структура устанавливается в объявлении структуры. Она просто объявляется, как если бы это была переменная типа int:
struct names handle;
Такое объявление говорит о том, что handle является переменной типа struct names. Разумеется, файл должен также включать объявление структуры names.
Во-вторых, посмотрите, как получать доступ к члену вложенной структуры; нужно всего лишь два раза воспользоваться операцией точки:
printf("Дорогой %s!\n\n", fellow.handle.hrst);
Если рассматривать эту конструкцию слева направо, она интерпретируется следующим образом:
(fellow.handle).hrst
То есть необходимо найти структуру fellow, затем член handle структуры fellow и, наконец, член first структуры типа names.
Указатели на структуры
Любители указателей будут рады узнать о возможности иметь указатели на структуры. Существуют, по меньшей мере, четыре причины, обусловливающие необходимость в указателях на структуры. Во-первых, точно так же, как манипулировать указателями на массивы проще, чем самими массивами (скажем, в задаче сортировки), с указателями на структуры часто работать легче, чем с самими структурами. Во-вторых, в некоторых старых реализациях структура не может быть передана как аргумент функции, но указатель на структуру — может. В-третьих, несмотря на то, что структуру можно передавать в качестве аргумента, передача указателя зачастую эффективнее.
578 глава 14
И, в-четвертых, многие замысловатые представления данных применяют структуры, содержащие указатели на другие структуры.
Следующий краткий пример (листинг 14.4) демонстрирует определение указателя на структуру и его использование для доступа к членам структуры.
Листинг 14.4. Программа friends.с

Запуск программы дает следующий вывод:
адрес #1: 0x7fff5fbff820 #2: 0x7fff5fbff874 указатель #1: 0x7fff5fbff820 #2: 0x7fff5fbff874 him->income равно $68112.00: (*him).income равно $68112.00 him->favfood равно рыбным фрикасе: him->handle.last равно Стюарт
Мы сначала посмотрим, каким образом создается указатель на структуру guy, а затем объясним, как описать отдельные члены структур с применением этого указателя.
Структуры и другие формы данных 579
Объявление и инициализация указателя на структуру
Объявить указатель на структуру очень просто:
struct guy * him;
Первым идет ключевое слово struct, затем дескриптор структуры guy, звездочка (*) и, наконец, имя указателя. Это тот же самый синтаксис, который используется для объявления других указателей, как было показано ранее.
Объявление не приводит к созданию новой структуры, но указатель him теперь может ссылаться на любую существующую структуру типа guy. Например, если barney — структура типа guy, то можно написать следующий оператор:
him = &barney;
В отличие от массивов, имя структуры не является ее адресом — вы должны применять операцию &.
В нашем примере fellow — массив структур, т.е. fellow [0] представляет собой структуру, поэтому код инициализирует him, делая его указывающим на f el low [0]:
him = &fellow[0];
Первые две строки вывода показывают, что присваивание прошло успешно. Сравнивая эти две строки, мы видим, что him указывает на fellow [0], a him + 1 — на fellow [1]. Обратите внимание, что добавление 1 к him приводит к добавлению значения 84 к адресу. В шестнадцатеричной форме записи 874 - 820 = 54 (шестнадцатеричное) = 84 (десятичное), т.к. каждая структура guy занимает 84 байта памяти: иод names, first отводится 20 байтов, под names, last — 20 байтов, под favfood — 20 байтов, под job — 20 байтов и под income — 4 байта (размер типа float в нашей системе). Кстати, в некоторых системах размер структуры может быть больше суммы размеров ее частей. Причина в том, что требования к выравниванию данных системы могут вызвать появление зазоров. Например, возможно, что система должна размещать каждый член структуры по четному адресу либо по адресу, кратному 4. Такие структуры могут содержать в себе неиспользуемые “бреши”.
Доступ к членам по указателю
Указатель him указывает на структуру fellow [0]. А как с помощью him получить значение члена fellow [0] ? В третьей строке вывода демонстрируются два метода.
Первый и наиболее распространенный метод предусматривает применение новой операции ->. Знак этой операции образован из дефиса (-) и символа “больше” (>). Мы имеем следующие зависимости:
Читать дальше