Доступ к массивам по индексу [array] в C и С++
Итак, есть этот маленький трюк, который некоторые интервьюеры любят спрашивать по любой причине:
int arr[] = {1, 2, 3};
2[arr] = 5; // does this line compile?
assert(arr[2] == 5); // does this assertion fail?
Из того, что я могу понять, a[b]
преобразуется в *(a + b)
, и поскольку сложение является коммутативным, на самом деле не имеет значения их порядок, поэтому 2[a]
действительно *(2 + a)
и это отлично работает.
Гарантируется ли это с помощью спецификаций C и/или С++?
Ответы
Ответ 1
Да. 6.5.2.1, пункт 1 (стандарт C99) описывает аргументы оператору []
:
Одно из выражений должно иметь тип "указатель на объект type
", другое выражение должно иметь целочисленный тип, а результат имеет тип "type
".
6.5.2.1 пункт 2 (выделено мной):
Постфиксное выражение, за которым следует выражение в квадратных скобках []
, является индексированным обозначение элемента объекта массива. Определение индексного оператора []
что E1[E2]
идентичен (*((E1)+(E2)))
. Из-за правил преобразования, которые примените к двоичному оператору +
, если E1
- объект массива (эквивалентно, указатель на начальный элемент объекта массива), а E2
- целое число, E1[E2]
обозначает E2
-th элемент E1
(отсчет с нуля).
В нем ничего не сказано, чтобы порядок аргументов []
был нормальным.
Ответ 2
В общем случае 2[a]
идентичен a[2]
, и это гарантировано эквивалентно как в C, так и в С++ (при отсутствии перегрузки оператора), потому что, как вы это понимаете, он переводится в *(2+a)
или *(a+2)
, соответственно. Поскольку оператор плюс является коммутативным, две формы эквивалентны.
Хотя формы эквивалентны, пожалуйста, ради всех этих святых (и будущих программистов на обслуживание), предпочитайте "a [2]" форму над другим.
PS. Если вас спросят об этом на собеседовании, сделайте точную месть от имени сообщества C/С++ и убедитесь, что, что вы попросите интервьюера перечислить все последовательности триграфов в качестве предварительного условия вам давая ответ. Возможно, это разочарует его/ее от того, чтобы задавать такие (бесполезные, по сути, какие-либо вопросы) вопросы в будущем. В нечетном случае, когда интервьюер действительно знает все девять последовательностей триграфа, вы всегда можете сделать еще одну попытку подтолкнуть их вопросом о порядке уничтожения виртуальных базовых классов - вопрос, который так же бескомпромиссен для повседневного программирования.