Array Indizierung ist identisch mit Zeigerarithmetik (eigentlich zuerst das Array Namen („Zerfälle“) auf einen Zeiger auf das erste Element vor dem []
-Operator angewendet wird, umgewandelt wird):
arr[r][c] <=> *(arr + r * INNER_LENGTH + c)
Ihr Array hat zwei Einträge pro Dimension. In C beginnen Indizes von 0
, so dass für jede Dimension gültige Indizes 0
und 1
sind (d. H. total_entries - 1
). Das macht drei Ihrer Ausdrücke in erster Linie suspective:
arr[0][2] // [outer dimension/index][inner dimension/index]
arr[1][2]
arr[2][0]
wir diese Fälle haben:
- Beide Indizes gelten: kein Problem.
- nur die Adresse entnommen wird, wird das Element nicht zugegriffen und
- der äußeree Index gültig ist und die innere (siehe unten) Index, der die Länge der Innenabmessung entspricht: Vergleich und bestimmte Adressenarithmetik (andere erlaubt Einschränkungen gelten!).
- der äußere Index ist gleich der Länge der äußeren Dimension, und der innere Index ist
0
: Das gleiche.
- Alles andere: Die Adresse ist ungültig und jede Nutzung (nehmen Sie Adresse, dereferenzieren, etc.) ruft undefinierten Verhalten.
Was genau in Erinnerung geht vielleicht ein bisschen mehr klar werden, wenn wir unterschiedliche Längen für die Abmessungen verwenden und einen Blick, wie die Daten gespeichert werden:
int arr[3][2];
Dies ist ein " Array von 3 Arrays von 2 int
Elementen ".Die am weitesten links liegende Dimension ist die „äußere“, die am weitesten rechts der „innere“ Dimension, wegen der Speicherlayout genannt:
arr[0][0] // row 0, column 0
arr[0][1] // row 0, column 1
arr[1][0] // ...
arr[1][1]
arr[2][0]
arr[2][1]
der obigen Formel Verwendung, &arr[0][2]
(arr + 0 * 2 + 2
) die gleiche wie &arr[1][0]
(arr + 1 * 2 + 0
) ergeben, usw. Beachten Sie jedoch, während die Adressen identisch sind, die erste Version nicht dereferenziert werden und der Compiler möglicherweise falschen Code usw.
Wie überprüfen Sie, wie ihre Adresse ist? – mszymborski
Sind Sie sicher, dass Sie nicht jedes Mal die Adresse des Basiszeigers erhalten? Das wäre meine starke Vermutung. Poste deinen Code, um die Adressen zu überprüfen. –
Die Auswertung von 'arr [0] [2]' erzeugt einen Out-of-Bounds-Zugriff mit undefiniertem Verhalten. (Aber nur die Adresse zu nehmen ist in Ordnung ('& arr [0] [2]'), weil das nicht ausgewertet wird.) –