Почему 2 [a] могут пройти компиляцию, если только объявить int a [3] в C

#c #arrays #pointers #gcc

#c #массивы #указатели #ссагпз #gcc

Вопрос:

Почему 2 [a] могут быть скомпилированы, если только объявить int a [3] в C.

  1  #include <stdio.h>
 2
 3  int main(int argc, char **argv)
 4  {
 5      int a[3] = {1, 2, 3};
 6      printf("a[2] is: %dn", a[2]);
 7      printf("2[a] is: %dn", 2[a]);
 8
 9      return 0;
10  }
  

И на выходе оба 3, как это объяснить?

Ответ №1:

Потому что a[2] это просто синтаксический сахар для *(a 2) , который такой же, как *(2 a) или 2[a] .

Комментарии:

1. Некоторые назвали бы это синтаксическим уксусом. 🙂

Ответ №2:

Потому что все a[2] средства в C есть *(a 2) , и поэтому *(2 a) работает так же хорошо, что также может быть написано 2[a] .

Ответ №3:

Выражение состоит из одного или нескольких операндов. Простейшая форма выражения состоит из одной литеральной константы или объекта. Результатом, в общем случае, является rvalue операнда.

Согласно стандарту C:

6.5.2.1 Подписка на массив

2 Постфиксное выражение, за которым следует выражение в квадратных скобках [], является подписанным обозначением элемента объекта массива. Определение оператора подстрочного индекса [] заключается в том, что E1 [E2] идентично (*((E1) (E2))). Из-за правил преобразования, которые применяются к двоичному оператору , если E1 является объектом массива (эквивалентно, указателем на начальный элемент объекта массива), а E2 является целым числом, E1[E2] обозначает E2-й элемент E1 (считая от нуля).

Итак, a[b] эквивалентно *(a b) и b[a] . где a и b может быть любым выражением.