#include <iostream>
using namespace std;
int main()
{
int arr[3] = { 10, 20, 30 };
cout << arr[-2] << endl;
cout << -2[arr] << endl;
return 0;
}
Sortie:
4196160
-30
Ici arr[-2]
est hors de portée et non valide, provoquant comportement indéfini. Mais -2[arr]
correspond à -30
. Pourquoi?
N'est-ce pas arr[-2]
équivalent à -2[arr]
?
-2[arr]
Est analysé en tant que -(2[arr])
. En C (et en C++, en ignorant la surcharge), la définition de X[Y]
Est *(X+Y)
(voir plus de discussion à ce sujet dans cette question ), ce qui signifie que 2[arr]
Est égal à arr[2]
.
Le compilateur analyse cette expression
-2
comme
unary_minus decimal_integer_literal
Autrement dit, les définitions des littéraux entiers n'incluent pas de signes.
À son tour, l'expression
2[arr]
est analysé par le compilateur comme une expression de suffixe.
Les expressions postfixes ont une priorité plus élevée que les expressions unaires. Ainsi cette expression
-2[arr]
est équivalent à
- ( 2[arr] )
Ainsi, le moins unaire est appliqué à la valeur l renvoyée par l'expression de suffixe 2[arr]
.
D'un autre côté, si vous avez écrit
int n = -2;
et alors
n[arr]
alors cette expression serait équivalente à
arr[-2]
-2[arr]
Est équivalent à -(2[arr])
, qui est équivalent à -arr[2]
. Cependant, (-2)[arr]
Équivaut à arr[-2]
.
Le problème sous-jacent est avec la priorité de l'opérateur . En C++, l'opérateur []
, C'est-à-dire l'opérateur Subscript, a plus de priorité (un peu comme une préférence) que l'opérateur -
Unary_minus.
Alors quand on écrit,
arr[-2]
Le compilateur exécute d'abord arr[]
Puis -
, Mais le unary_minus est enfermé dans les limites de [-2]
De sorte que l'expression est décomposée ensemble.
Dans le,
-2[arr]
La même chose se produit mais, le compilateur exécute 2[]
D'abord l'opérateur n -
Donc il finit par être -(2[arr])
pas (-2)[arr]
Votre compréhension du concept selon lequel arr[i]
i[arr]
Et *(i+arr)
sont tous identiques est correcte. Ce sont toutes des expressions équivalentes.
Si vous voulez écrire de cette façon, écrivez-le comme (-2)[arr]
. Vous obtiendrez à coup sûr la même valeur.
Vérifiez ceci pour référence future: http://en.cppreference.com/w/cpp/language/operator_precedence