Имена типов
В двух случаях (для явного указания типа преобразования в конструкции перевода и для аргументов операции sizeof) желательно иметь возможность задавать имя типа данных. Это осуществляется с помощью "имени типа", которое по существу является описанием объекта такого типа, в котором опущено имя самого объекта.
Имя типа: спецификатор-типа абстрактный-описатель абстрактный-описатель: пусто (абстрактный-описатель) * абстрактный описатель абстрактный-описатель () абстрактный-описатель [константное выражение необ]
Во избежании двусмысленности в конструкции
(абстрактный описатель)
требуется, чтобы абстрактный-описатель был непуст. При этом ограничении возможно однозначно определить то место в абстрактном-описателе, где бы появился идентификатор, если бы эта конструкция была описателем в описании. Именованный тип совпадает тогда с типом гипотетического идентификатора. Например, имена типов
int int * int *[3] int (*)[3] int *() int (*)()
именуют соответственно типы "целый", "указатель на целое", "массив из трех указателей на целое", "указатель на массив из трех целых", " функция, возвращающая указатель на целое" и "указатель на функцию, возвращающую целое".
int x[] = {1,3,5};
описывает и инициализирует x как одномерный массив; поскольку размер массива не специфицирован, а список инициализитора содержит три элемента, считается, что массив состоит из трех членов.
Вот пример инициализации с полным использованием фигурных скобок:
float *y[4][3] = { ( 1, 3, 5 ), ( 2, 4, 6 ), ( 3, 5, 7 ), };
Здесь 1, 3 и 5 инициализируют первую строку массива y[0], а именно y[0][0], y[0][1] и y[0][2]. Аналогичным образом следующие две строчки инициализируют y[1] и y[2]. Инициализатор заканчивается преждевременно, и, следовательно массив y[3] инициализируется нулями. В точности такого же эффекта можно было бы достичь, написав
float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
Инициализатор для y начинается с левой фигурной скобки, но инициализатора для y[0] нет. Поэтому используется 3 элемента из списка. Аналогично следующие три элемента используются последовательно для y[1] и y[2]. следующее описание
float y[4][3] = { (1), (2), (3), (4) };
инициализирует первый столбец y (если его рассматривать как двумерный массив), а остальные элементы заполняются нулями.
И наконец, описание
char msg[] = "syntax error on line %s\n";
демонстрирует инициализацию элементов символьного массива с помощью строки.
int x[] = {1,3,5};
описывает и инициализирует x как одномерный массив; поскольку размер массива не специфицирован, а список инициализитора содержит три элемента, считается, что массив состоит из трех членов.
Вот пример инициализации с полным использованием фигурных скобок:
float *y[4][3] = { ( 1, 3, 5 ), ( 2, 4, 6 ), ( 3, 5, 7 ), };
Здесь 1, 3 и 5 инициализируют первую строку массива y[0], а именно y[0][0], y[0][1] и y[0][2]. Аналогичным образом следующие две строчки инициализируют y[1] и y[2]. Инициализатор заканчивается преждевременно, и, следовательно массив y[3] инициализируется нулями. В точности такого же эффекта можно было бы достичь, написав
float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
Инициализатор для y начинается с левой фигурной скобки, но инициализатора для y[0] нет. Поэтому используется 3 элемента из списка. Аналогично следующие три элемента используются последовательно для y[1] и y[2]. следующее описание
float y[4][3] = { (1), (2), (3), (4) };
инициализирует первый столбец y (если его рассматривать как двумерный массив), а остальные элементы заполняются нулями.
И наконец, описание
char msg[] = "syntax error on line %s\n";
демонстрирует инициализацию элементов символьного массива с помощью строки.