Средство enum предлагает инструмент для определения символических констант, а typedef — средство создания нового идентификатора для базового или производного типа.
Указатели на функции предоставляют инструмент для уведомления одной функции о том, какие функции она должна применять.
620 Глава 14
Резюме
Структуры С служат средством для хранения нескольких элементов данных, обычно разных типов, в одном и том же объекте данных. Для идентификации шаблона структуры и для объявления переменных этого типа можно использовать дескриптор. Операция членства (.) позволяет обращаться к индивидуальным членам структуры с применением меток из шаблона структуры.
Имея указатель на структуру, для доступа к отдельным ее членам можно использовать этот указатель и операцию косвенного членства (->) вместо имени и операции точки. Получить адрес структуры можно с помощью операции &. В отличие от массивов, имя структуры не служит ее адресом.
Традиционно функции, связанные со структурами, принимали в своих аргументах указатели на структуры. Современная версия языка С допускает передачу структур в качестве аргументов, применение структур как возвращаемых значений и присваивание структур одного и того же типа. Тем не менее, передача адреса обычно эффективнее.
Объединения имеют тот же самый синтаксис, что и структуры. Однако члены в объединениях совместно используют одно и то же пространство памяти. Вместо того чтобы одновременно хранить несколько типов данных, как это делает структура, объединение хранит элемент данных одного типа из списка вариантов. Другими словами, структура может хранить, скажем, данные int, double и char, а соответствующее объединение может содержать либо int, либо double, либо char.
Перечисления позволяют создавать группу символических целочисленных констант (перечислимых констант) и определять связанный перечислимый тип.
С помощью средства typedef можно устанавливать псевдонимы или сокращенные представления стандартных типов С.
Имя функции является ее адресом. Такие адреса могут передаваться в виде аргументов функциям, которые в дальнейшем применяют функции, указанные этими адресами. Если pf — указатель на функцию, которому был присвоен адрес конкретной функции, то эту функцию можно вызвать двумя способами:
#include /* объявление функции double sin(double) */
double (* pdf) (double);
double x;
pdf = sin;
x= (*pdf)(1.2); // вызывает sin(1.2)
x = pdf(1.2); // также вызывает sin(1.2)
Вопросы для самоконтроля
Ответы на вопросы для самоконтроля приведены в приложении А.
1. Что неправильно в следующем шаблоне?
structure {
char itable; int num[20]; char * togs
}
2. Ниже приведен фрагмент программы. Что он выведет?
#include
struct house { float sqft;
Структуры и другие формы данных 621
int rooms; int stories; char address[40];
};
int main(void)
{
struct house fruzt = {1560.0, 6, 1, "22 Spiffo Road"}; struct house *sign; sign = &fruzt;
printf("%d %d\n", fruzt.rooms, sign->stories); printf("%s \n", fruzt.address);
printf("%c %c\n", sign->address[3], fruzt.address[4]); return 0;
}
3. Разработайте шаблон структуры, которая будет содержать название месяца, его трехбуквенную аббревиатуру, количество дней в месяце и его номер.
4. Определите массив из 12 структур вида, описанного в вопросе 3, и инициализируйте ее для года, который не является високосным.
5. Напишите функцию, которая после получения номера месяца возвращает общее количество дней с начала года до конца указанного месяца. Предположите, что шаблон структуры, описанный в вопросе 3, и подходящий массив таких структур объявлены внешне.
6. а. Имея показанное ниже определение typedef, объявите 10-элементный массив указанных структур. Затем с помощью присваивания индивидуальных членов сделайте так, чтобы третий элемент этого массива описывал объектив марки Remarkatar с фокусным расстоянием 500 мм и диафрагмой f/2.0.
/* дескриптор структуры lens */ /* фокусное расстояние в миллиметрах */ /* диафрагма */ /* марка производителя */
б. Повторите часть а), но воспользуйтесь в объявлении списком инициализации с назначенным инициализатором вместо написания отдельных операторов присваивания для каждого члена.
7. Взгляните на следующий фрагмент кода:
struct name {
char first[20]; char last[20];
};
struct bem {
int limbs; struct name title; char type[30];
};
struct bem * pb; struct bem deb = {
6,
{"Berbnazel", "Gwolkapwolk"(,
"Arcturan"
};
pb = &deb;
622 глава 14
а. Что выведут приведенные ниже операторы?
printf("%d\n", deb.limbs); printf("%s\n", pb->type); printf("%s\n", pb->type + 2);
б. Как можно было бы представить "Gwolkapwolk" в форме записи для структур (двумя способами)?
Читать дальше