Роль идентификатора в переч-спецификаторе
аналогична роли тега структуры в структ-спецификаторе: он является именем некоторого конкретного перечисления. Правила для списков и переч-спецификаторов (с тегами и без) те же, что и для спецификаторов структур или объединений, с той лишь оговоркой, что элементы перечислений не бывают незавершенного типа; тег переч-спецификатора без списка перечислителей должен иметь в пределах области видимости спецификатор со списком. В первой версии языка перечислений не было, но они уже несколько лет применяются.
А8.5. Объявители
Объявители имеют следующий синтаксис:
объявитель
: указательнеоб
собственно-объявительсобственно-объявитель
: идентификатор
(объявитель
) собственно-объявитель
[константное-выражениенеоб] собственно-объявитель
(список-типов-параметров) собственно-объявитель
(список-идентификаторовнеоб)указатель
: * список-квалификаторов-типанеоб
* список-квалификаторов-типанеоб
указательсписок-квалификаторов-типа
: квалификатор-типа
список-квалификаторов-типа квалификатор-типа
У структуры объявителя много сходных черт со структурой подвыражений, поскольку в объявителе, как и в подвыражении, допускаются операции косвенного обращения, обращения к функции и получения элемента массива (с тем же порядком применения).
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. Если константное выражение, специфицирующее количество элементов в массиве, отсутствует, то массив имеет незавершенный тип.