С++ реверсивный индексатор и имя массива

Я столкнулся с этим в Интернете и задавался вопросом, может ли кто-нибудь объяснить это или хотя бы дать мне имя того, что может быть, чтобы я мог хотя бы знать, для чего я ищу.

int main()
{
   int myarray[4] = {0, 100, 200, 300};
   2[myarray] = -999;  //why does this work? what is this called?

   for ( int i = 0; i < 4; i++) 
      cout << myarray[i] << endl;
}

Выход равен 0, 100, -999, 300

Я запустил его. Я знаю, что это работает, но почему? Как это называется?

Ответ 1

Причина этого в том, что arr[n] == *(arr + n).

Однако, поскольку сложение является коммутативным, *(arr + n) == *(n + arr). Таким образом, *(n + arr) == n[arr] == *(arr + n) == arr[n].

Возможно, стоит отметить, что *(arr + n) все еще немного вводит в заблуждение. В сборке это означает *(arr + (n * s)), где s есть sizeof arr[0], но это находится под обложками, поэтому вам не нужно беспокоиться об этом.

Ответ 2

Я не думаю, что это [ab-] использование правил для арифметики указателя имеет какое-то конкретное имя. Это просто исключается из того, что арифметика указателя определена в C и С++. Ни один из двух языковых стандартов не делает каких-либо особых попыток предотвратить разворот индекса и указателя. Например, соответствующее правило С++ находится в 5.2.1 [expr.sub], пункт 1:

Постфиксное выражение, за которым следует выражение в квадратных скобках, является постфиксным выражением. Одно из выражений должно иметь тип "массив Т" или "указатель на Т", а другой должен иметь неперечисленное перечисление или интегральный тип. Результат имеет тип "T". Тип "T" должен быть полностью определенным типом объекта. Выражение E1 [E2] идентично (по определению) к * ((E1) + (E2)) [Примечание: см. 5.3 и 5.7 для деталей * и + и 8.3.4 для подробностей массивов. -end note], за исключением того, что в случае операнда массива результат равен lvalue, если этот операнд является lvalue и xvalue в противном случае.

Может возникнуть проблема поиска "С++ 5.2.1" или "С++ [expr.sub]", но использование разворота не настолько велико, чтобы запутать людей, которые недостаточно долго смотрели на C или С++.