Подтвердить что ты не робот

Почему не arr [-2] эквивалентно -2 [arr]?

#include <iostream>
using namespace std;

int main() 
{
    int arr[3] = { 10, 20, 30 };
    cout << arr[-2] << endl;
    cout << -2[arr] << endl;        
    return 0;
}

Вывод:

4196160
-30

Здесь arr[-2] находится вне допустимого диапазона и недействителен, вызывая поведение undefined. Но -2[arr] оценивается как -30. Почему?

Не arr[-2] эквивалентно -2[arr]?

4b9b3361

Ответ 1

-2[arr] анализируется как -(2[arr]). В C (и в С++, игнорируя перегрузку), определение X[Y] равно *(X+Y) (подробнее об этом см. В этот вопрос), что означает, что 2[arr] равно arr[2].

Ответ 2

Компилятор анализирует это выражение

-2

как

unary_minus decimal_integer_literal

То есть определения целых литералов не содержат признаков.

В свою очередь выражение

2[arr]

анализируется компилятором как постфиксное выражение.

Постфиксные выражения имеют более высокий приоритет, чем унарные выражения. Таким образом, это выражение

-2[arr]

эквивалентно

- ( 2[arr] )

Таким образом, унарный минус применяется к lvalue, возвращаемому выражением postfix 2[arr].

С другой стороны, если вы написали

int n = -2;

а затем

n[arr]

то это выражение будет эквивалентно

arr[-2]

Ответ 3

-2[arr] эквивалентен -(2[arr]), что эквивалентно -arr[2]. Однако (-2)[arr] эквивалентно arr[-2].

Это связано с тем, что E1 [E2] идентичен (* ((E1) + (E2)))

Ответ 4

Основная проблема заключается в приоритете оператора. В С++ [], т.е. Оператор Subscript имеет больше приоритетов (несколько схожий с предпочтением), чем оператор - unary_minus.

Поэтому, когда вы пишете,

arr[-2]

Сначала выполняется компилятор arr[], затем -, но unary_minus заключен в пределах [-2], поэтому выражение разлагается вместе.

В <

-2[arr]

То же самое происходит, но компилятор выполняет 2[] сначала оператор -, поэтому он заканчивается тем, что -(2[arr]) не (-2)[arr]

Ваше понимание концепции, что, arr[i] i[arr] и *(i+arr) все одинаковы. Это все эквивалентные выражения.

Если вы хотите написать таким образом, напишите его как (-2)[arr]. Вы получите то же самое значение точно.

Отметьте это для будущего обращения: http://en.cppreference.com/w/cpp/language/operator_precedence