a[2]
- постфиксное выражение, которое построено из идентификатора первичного выражения a
и оператора индекса [].
Если рассматривать в одиночку декларацию
int a[2][4];
, то эта декларация объявляет идентификатор a
как имеющий тип int[2][4]
.
Вы можете отделить идентификатор от других элементов объявления с помощью typedef. Например,
typedef int T[2][4];
T a;
Теперь более ясно, что является идентификатором. Таким образом, a
является идентификатором, который имеет тип T
, который, в свою очередь, эквивалентен int[2][4]
.
В грамматике C есть такое понятие, как декларатор. Например, идентификатор является декларатором. В объявлении ниже я вложил все объявления в круглые скобки.
int (((a)[2])[4]);
Это действует декларация, хотя выглядит запутанным. :) То есть в данном объявлении a
, a[2]
и a[2][4]
являются declarators, которые строятся начиная с идентификатором a
.
Примечание: языковой стандарт не ограничивает термин * идентификатор * только функциями и переменными. В § 6.2.1 «Идентификатор может обозначать объект: функцию, тег или член структуры, объединения или перечисления, имя typedef, имя метки, имя макроса или параметр макроса». – WhozCraig
@WhozCraig Исправил ответ. –
Это не r-значения, а lvalues (объекты с выделенным пространством памяти) и * могут быть преобразованы в rvalues *. – MikeCAT