С++ реверсивный индексатор и имя массива
Я столкнулся с этим в Интернете и задавался вопросом, может ли кто-нибудь объяснить это или хотя бы дать мне имя того, что может быть, чтобы я мог хотя бы знать, для чего я ищу.
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 или С++.