собственно-объявитель ( список-типов-параметров )
собственно-объявитель ( список-идентификаторов необ )
указатель :
* список-квалификаторов-типа необ
* список-квалификаторов-типа необуказатель
список-квалификаторов-типа :
квалификатор-типа
список-квалификаторов-типа квалификатор-типа
У структуры объявителя много сходных черт со структурой подвыражений, поскольку в объявителе, как и в подвыражении, допускаются операции косвенного обращения, обращения к функции и получения элемента массива (с тем же порядком применения).
A8.6. Что означают объявители
Список объявителей располагается сразу после спецификаторов типа и указателя класса памяти. Главный элемент любого объявителя - это объявляемый им идентификатор; в простейшем случае объявитель из него одного и состоит, что отражено в первой строке продукции грамматики с именем собственно- объявитель . Спецификаторы класса памяти относятся непосредственно к идентификатору, а его тип зависит от вида объявителя. Объявитель следует воспринимать как утверждение: если в выражении идентификатор появляется в том же контексте, что и в объявителе, то он обозначает объект специфицируемого типа.
Если соединить спецификаторы объявления, относящиеся к типу (A8.2), и некоторый конкретный объявитель, то объявление примет вид "T D", где T - тип, a D - объявитель. Эта запись индуктивно придает тип идентификатору любого объявителя.
В объявлении T D, где D - просто идентификатор, тип идентификатора есть T .
В объявлении T D, где D имеет вид
( D1 )
тип идентификатора в D1 тот же, что и в D . Скобки не изменяют тип, но могут повлиять на результаты его "привязки" к идентификаторам в сложных объявителях.
A8.6.1. Объявители указателей
В объявления T D, где D имеет вид
* список-квалификаторов-типа необ D1
а тип идентификатора объявления T D1 есть " модификатор-типа T ", тип идентификатора D есть " модификатор-типа список-квалификаторов-типа указатель на T ". Квалификаторы, следующие за *, относятся к самому указателю, а не к объекту, на который он указывает. Рассмотрим, например, объявление
int *ap[];
Здесь ap[] играет роль D1 ; объявление int ap[] следует расшифровать (см. ниже) как "массив из int ": список квалификаторов типа здесь пуст, а модификатор типа есть " массив из ". Следовательно, на самом деле объявление ap гласит: "массив из указателей на int ". Вот еще примеры объявлений:
int i, *pi, *const cpi = &i;
const int ci = 3, *pci;
В них объявляются целое i и указатель на целое pi . Значение указателя cpi неизменно; cpi всегда будет указывать в одно и то же место, даже если значение, на которое он указывает, станет иным. Целое ci есть константа, оно измениться не может (хотя может инициализироваться, как в данном случае). Тип указателя pci произносится как "указатель на const int "; сам указатель можно изменить; при этом он будет указывать на другое место, но значение, на которое он будет указывать, с помощью pci изменить нельзя.
А8.6.2. Объявители массивов
В объявления T D, где D имеет вид
D1 [ константное-выражение необ ]
и где тип идентификатора объявления T D1 есть " модификатор-типа Т ", тип идентификатора D есть " модификатор-типа массив из T". Если константное выражение присутствует, то оно должно быть целочисленным и больше 0. Если константное выражение, специфицирующее количество элементов в массиве, отсутствует, то массив имеет незавершенный тип.
Массив можно конструировать из объектов арифметического типа, указателей, структур и объединений, а также других массивов (генерируя при этом многомерные массивы). Любой тип, из которого конструируется массив, должен быть завершенным, он не может быть, например, структурой или массивом незавершенного типа. Это значит, что для многомерного массива пустой может быть только первая размерность. Незавершенный тип массива получает свое завершение либо в другом объявлении этого массива (A10.2), либо при его инициализации (A8.7). Например, запись
float fa[17], *afp[17];
объявляет массив из чисел типа float и массив из указателей на числа типа float . Аналогично
static int x3d[3][5][7];
объявляет статический трехмерный массив целых размера 3 x 5 x 7. На самом деле, если быть точными, x3d является массивом из трех элементов, каждый из которых есть массив из пяти элементов, содержащих по 7 значений типа int .
Читать дальше