2016-06-30 7 views
0

Warum erlaubt C++ die folgende Anweisung?Warum Array-Subskriptionsoperator funktioniert in beide Richtungen?

int a[10] = { 0 }; 
    std::cout << 1[a] << std::endl; 
    std::cout << a[1] << std::endl; 

Beide Zeilen drucken Null und es wird keine Compiler-Warnung generiert. Sollte nicht ungültig sein, da 1 kein Array ist und a kein Integer-Typ ist.

Code-Beispiel: http://cpp.sh/4tan

+1

Wegen Zeigerarithmetik. –

+0

Fragen Sie den C-Standard, das ist, wo C++ seine arithmetische – KABoissonneault

Antwort

4

Es ist wegen der Zeigerarithmetik:

a[1] == *(a+1) == *(1+a) == 1[a]; 

Zitiert den Standard (§8.3.4; Punkt 6):

sei denn, es wurde Für eine Klasse deklariert, wird der tiefgestellte Operator [] so interpretiert, dass E1[E2] mit identisch ist. Aufgrund der Konvertierungsregeln, die für + gelten, wenn E1 ein Array und E2 eine ganze Zahl ist, bezieht sich E1[E2] auf das E2 -te Mitglied von E1. Daher ist Subskribieren trotz seiner asymmetrischen Erscheinung eine kommutative Operation.

Beachten Sie, dass, wenn Sie a[1] schreiben, der Compiler als *(a+1) interpretiert. Sie beziehen sich immer noch auf das gleiche Array a, wenn Sie 1[a] schreiben, so ist der Compiler tatsächlich immer noch Typ Überprüfung.

+0

bekam ich, aber warum führt es keine Typüberprüfung durch? –

+0

vielleicht besser mit '==' illustriert? 'assert (a [1] == * (a + 1) == * (1 + a) == 1 [a]);' –

+0

@BatCoder Ich denke, OP geht davon aus, dass 'operator []' nur für Zeiger gültig ist Typen, Array-Typen und benutzerdefinierte Typen, die den Operator überlasten. Aber wie in der Frage gezeigt, ist es nicht. – KABoissonneault

1

Beide sind in Ordnung, da unter der Decke alles nur Zeigerarithmetik ist. Die Adresse von etwas zu nehmen und etwas anderes hinzuzufügen (a[1) ist genau das gleiche wie etwas anderes zu nehmen und eine Adresse hinzuzufügen() - die endgültige Adresse des Objekts, auf das Sie verweisen, ist dasselbe. Eine Notation ist für den Menschen intuitiver als die andere.

Verwandte Themen