Листинг 14.10. Программа names3.c

590 Глава 14

Ниже показан пример вывода:
Введите свое имя.
Васисуалий
Введите свою фамилию.
Лоханкин
Васисуалий Лоханкин, ваше имя и фамилия содержат 18 букв.
Структуры и другие формы данных 591
Составные литералы и структуры (С99)
Средство составных литералов С99 доступно для структур, а также для массивов. Оно удобно, если требуется всего лишь временное значение структуры. Например, составные литералы можно применять для создания структуры, предназначенной для использования в качестве аргумента функции или для присваивания другой струк туре. Синтаксис составного литерала выглядит как заключенный в фигурные скобки список инициализаторов, которому предшествует имя типа в круглых скобках. Ниже представлен составной литерал типа struct book:
(struct book) {"Идиот", "Федор Достоевский", 6.99}
В листинге 14.11 приведен пример применения составных литералов для предоставления двух альтернативных значений переменной структуры. (На момент написания книги это средство поддерживалось не всеми компиляторами, но со временем ситуация должна поменяться.)
Листинг 14.11. Программа complit.c

Составные литералы можно использовать также как аргументы функций. Если функция ожидает структуру, то ей можно передавать в качестве фактического аргумента составной литерал:
struct rect {double х; double у,();
double rect_area(struct rect r){return r.x * r.y;)
double area;
area = rect_area ( (struct rect) {10.5, 20.0});
592 глава 14
Это приводит к тому, что area присваивается значение 210.0.
Если функция ожидает адрес, то ей можно передать адрес составного литерала:

В результате переменная area получает значение 210.0.
Составные литералы, которые встречаются за пределами любых функций, имеют статическую продолжительность хранения, а те, что находятся внутри блока — автоматическую продолжительность хранения. В отношении составных литералов действуют те же синтаксические правила, что и для обычных списков инициализаторов. Это значит, например, что в составных литералах можно применять назначенные инициализаторы.
Члены с типами гибких массивов (С99)
В стандарте С99 предлагается новое средство, которое называется членам типа гибко го массива. Оно позволяет объявлять структуру, последний член в которой является массивом со специальными свойствами. Одно из специальных свойств заключается в том, что такой массив не существует — во всяком случае, не появляется немедленно. Второе специальное свойство состоит в том, что при наличии корректного кода член типа гибкого массива можно использовать, как если бы он существовал и имел нужное количество элементов. Возможно, это звучит несколько своеобразно, так что давайте рассмот рим таги по созданию и применению структуры с членом типа гибкого массива.
Для начала ниже представлены правила, регламентирующие создание члена типа гибкого массива.
• Член типа гибкого массива должен быть последним в структуре.
• В структуре должен присутствовать, по крайней мере, еще один член другого типа.
• Гибкий массив объявляется подобно обычному массиву, но с пустыми квадратными скобками.
Вот пример, иллюстрирующий эти правила:
struct flex
{
int count;
double average;
double scores!]; // член типа гибкого массива
};
Если вы объявили переменную типа struct flex, то не можете использовать член scores, т.к. память для него не зарезервирована. На самом деле, даже не подразумевается, что вы будете объявлять переменные типа struct flex. Вместо этого предполагается, что вы объявите указатель на тип struct flex, а затем с помощью malloc() выделите область памяти, достаточную для хранения обычного содержимого struct flex, плюс дополнительное пространство, которое необходимо для члена с типом гибкого массива. Например, пусть вы хотите, чтобы член scores представлял массив из пяти значений double. В этом случае понадобится поступить так:
struct flex * pf; // объявление указателя
Структуры и другие формы данных 593
// запрос области памяти для размещения структуры и массива pf = malloc(sizeof(struct flex) + 5 * sizeof(double));
Читать дальше