Ich denke, bei den anderen Antworten wird etwas übersehen.
Ja, p[i]
ist per Definition äquivalent zu *(p+i)
, was (weil Addition kommutativ ist) äquivalent zu ist *(i+p)
, was (wiederum nach der Definition des []
Operators) äquivalent zu ist i[p]
.
(Und in array[i]
wird der Arrayname implizit in einen Zeiger auf das erste Element des Arrays konvertiert.)
Aber die Kommutativität der Addition ist in diesem Fall nicht allzu offensichtlich.
Wenn beide Operanden vom gleichen Typ sind oder sogar von unterschiedlichen numerischen Typen, die zu einem gemeinsamen Typ heraufgestuft werden, ist Kommutativität durchaus sinnvoll : x + y == y + x
.
In diesem Fall handelt es sich jedoch speziell um eine Zeigerarithmetik, bei der ein Operand ein Zeiger und der andere eine Ganzzahl ist. (Ganzzahl + Ganzzahl ist eine andere Operation, und Zeiger + Zeiger ist Unsinn.)
In der Beschreibung des +
Bedieners nach C-Standard ( N1570 6.5.6) heißt es:
Außerdem müssen entweder beide Operanden einen arithmetischen Typ haben, oder ein Operand muss ein Zeiger auf einen vollständigen Objekttyp sein, und der andere muss einen ganzzahligen Typ haben.
Es hätte genauso gut sagen können:
Außerdem müssen entweder beide Operanden einen arithmetischen Typ haben, oder der linke
Operand muss ein Zeiger auf einen vollständigen Objekttyp sein, und der rechte Operand
muss einen ganzzahligen Typ haben.
in diesem Fall beides i + p
und i[p]
wäre illegal.
In C ++ - Begriffen haben wir wirklich zwei Sätze überladener +
Operatoren, die lose beschrieben werden können als:
pointer operator+(pointer p, integer i);
und
pointer operator+(integer i, pointer p);
davon ist nur der erste wirklich notwendig.
Warum ist es so?
C ++ hat diese Definition von C geerbt, das sie von B erhalten hat (die Kommutativität der Array-Indizierung wird in der Benutzerreferenz von 1972 zu B ausdrücklich erwähnt ), die sie von BCPL (Handbuch vom 1967) erhalten hat, was sie möglicherweise sogar erhalten hat frühere Sprachen (CPL? Algol?).
Die Idee, dass die Array-Indizierung als Addition definiert wird und dass die Addition selbst eines Zeigers und einer Ganzzahl kommutativ ist, geht viele Jahrzehnte auf die Ahnensprachen von C zurück.
Diese Sprachen waren viel weniger stark typisiert als das moderne C. Insbesondere wurde die Unterscheidung zwischen Zeigern und ganzen Zahlen oft ignoriert. (Frühe C-Programmierer verwendeten manchmal Zeiger als vorzeichenlose Ganzzahlen, bevor das unsigned
Schlüsselwort zur Sprache hinzugefügt wurde.) Die Idee, das Hinzufügen nicht kommutativ zu machen, weil die Operanden unterschiedlichen Typs sind, wäre den Designern dieser Sprachen wahrscheinlich nicht in den Sinn gekommen. Wenn ein Benutzer zwei "Dinge" hinzufügen wollte, unabhängig davon, ob es sich bei diesen "Dingen" um Ganzzahlen, Zeiger oder etwas anderes handelt, lag es nicht an der Sprache, dies zu verhindern.
Und im Laufe der Jahre hätte jede Änderung dieser Regel den bestehenden Code gebrochen (obwohl der ANSI C-Standard von 1989 eine gute Gelegenheit gewesen sein könnte).
Wenn Sie C und / oder C ++ so ändern, dass der Zeiger links und die Ganzzahl rechts gesetzt werden müssen, wird möglicherweise vorhandener Code beschädigt, es kommt jedoch nicht zu einem Verlust der tatsächlichen Ausdruckskraft.
Jetzt haben arr[3]
und 3[arr]
meinen wir genau dasselbe, obwohl die letztere Form niemals außerhalb des IOCCC erscheinen sollte .