ich weiß das arr[x] ist das gleiche wie *(arr + x). So arr[-2] ist *(arr - 2), was in Ordnung zu sein scheint. Was denkst du?
Das ist richtig. Aus C99 §6.5.2.1/2:
Die Definition des Indexoperators [] ist das E1[E2] ist identisch mit (*((E1)+(E2))).
Es gibt keine Magie. Es ist eine 1-1 Äquivalenz. Wie immer beim Dereferenzieren eines Zeigers
müssen Sie sicher sein, dass es auf eine gültige Adresse verweist. somearray-2 Beachten Sie auch, dass Sie den Zeiger nicht dereferenzieren müssen, um UB zu erhalten. Reines Rechnen somearray ist undefiniert, es sei denn, das Ergebnis liegt im Bereich von Beginn an
bis 1 nach seinem Ende.
– RBerteig
13. August 2010 um 9:12 Uhr [] In älteren Büchern die wurden als bezeichnet Syntax Zucker für Zeigerarithmetik. Favorit 1[arr] Ein Weg, Anfänger zu verwirren, ist zu schreiben arr[1] – Anstatt von
– und beobachten Sie, wie sie raten, was das bedeuten soll.
– Dummy00001
13. August 2010 um 14:24 Uhr
Was passiert auf 64-Bit-Systemen (LP64), wenn Sie einen negativen 32-Bit-Int-Index haben? Soll der Index vor der Adressberechnung zu einem 64-Bit-Signed-Int hochgestuft werden?
– PaulR
11. Oktober 2010 um 16:02 Uhr ((E1)+(E2)) @Paul aus §6.5.6/8 (Additive Operatoren): „Wenn ein Ausdruck vom Typ Integer zu einem Zeiger addiert oder von ihm subtrahiert wird, hat das Ergebnis den Typ des Zeigeroperanden. Wenn der Zeigeroperand auf ein Element zeigt eines Array-Objekts und das Array groß genug ist, zeigt das Ergebnis auf ein Element, das so vom ursprünglichen Element versetzt ist, dass die Differenz der Indizes der resultierenden und ursprünglichen Array-Elemente gleich dem ganzzahligen Ausdruck ist.” Also denke ich, dass es gefördert wird, und
wird ein (64-Bit) Zeiger mit dem erwarteten Wert sein.
– Matthäus Flaschen
11. Oktober 2010 um 22:23 Uhr [] Eine kuriose Randbemerkung: Da der Index-Operator[E2] ist so definiert, dass E1 2[arr] identisch ist mit (*((E1)+(E2))) (siehe die Antwort von Matthew Flaschen), es ist tatsächlich gültiger C-Code zum Schreiben arr[2]Anstatt von
. Ich gebe jedoch zu, dass dies den Code absichtlich verschleiert.
– Christian Borgelt
19. Februar 2013 um 17:36 Uhr arr Dies gilt nur, wenn
int arr[10];
int x = arr[-2]; // invalid; out of range
ist ein Zeiger, der auf das zweite Element in einem Array oder ein späteres Element zeigt. Andernfalls ist es nicht gültig, da Sie auf Speicher außerhalb der Grenzen des Arrays zugreifen würden. Also falsch wäre zum Beispiel:
int arr[10];
int* p = &arr[2];
int x = p[-2]; // valid: accesses arr[0]
Aber das wäre okay:
Es ist jedoch ungewöhnlich, einen negativen Index zu verwenden.
@Matt: Der Code im ersten Beispiel ergibt undefiniertes Verhalten.
– James McNellis
13. August 2010 um 3:40 Uhr int arr[10]; Es ist ungültig. Nach dem C-Standard hat es explizit undefiniertes Verhalten. Andererseits, wenn arr[-2] waren Teil einer Struktur mit anderen Elementen davor, offsetofkönnte möglicherweise gut definiert sein, und Sie könnten feststellen, ob es darauf basiert
etc.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
13. August 2010 um 6:35 Uhr If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1], p[-2], and so on are syntactically legal, and refer to the elements that immediately precede p[0]. Of course, it is illegal to refer to objects that are not within the array bounds. Gefunden in K&R Abschnitt 5.3, gegen Ende:
Trotzdem hilft mir Ihr Beispiel besser, es zu verstehen. Vielen Dank!
– Qiang Xu
9. Mai 2012 um 20:47 Uhr
Entschuldigung für die Nekromantie, aber ich finde es einfach toll, dass K&R nicht eindeutig ist, was “illegal” bedeutet. Der letzte Satz lässt es so klingen, als ob Zugriffe außerhalb der Grenzen einen Kompilierungsfehler auslösen. Das Buch ist Gift für Anfänger.
– Martin
14. Februar 2017 um 21:02 Uhr
@Martin Um fair zu sein, wurde das Buch zu einem früheren Zeitpunkt in der Geschichte unserer Branche geschrieben, als es noch sehr vernünftig war, zu erwarten, dass “illegal” als “tu dies nicht, du darfst nicht” und nicht als “du wirst es sein” interpretiert wird daran gehindert“.
– mtraceur
30. Dezember 2019 um 8:30 Uhr
Klingt gut für mich. Es wäre jedoch ein seltener Fall, dass Sie es rechtmäßig benötigen würden. Es ist nicht das
selten – sehr nützlich zB bei der Bildverarbeitung mit Nachbarschaftsoperatoren.
– PaulR
11. Oktober 2010 um 15:56 Uhr [ structure / design ] Ich musste dies nur verwenden, weil ich einen Speicherpool mit einem Stapel und einem Haufen erstelle
. Der Stack wächst zu höheren Speicheradressen, der Heap wächst zu niedrigeren Speicheradressen. Treffen in der Mitte.
– KANJICODER
24. Januar 2020 um 16:12 Uhr arr Was war das wohl arr[-2] zeigte auf die Mitte des Arrays und machte daher
Der Autor scheint zu sagen, dass 32-Bit-Int-Array-Indizes mit 64-Bit-Adressierung zu schlechten Adressberechnungen führen können, es sei denn, der Array-Index wird explizit auf 64 Bit hochgestuft (z. B. über einen ptrdiff_t-Cast). Ich habe tatsächlich einen Fehler dieser Art mit der PowerPC-Version von gcc 4.1.0 gesehen, aber ich weiß nicht, ob es sich um einen Compiler-Fehler handelt (dh sollte gemäß C99-Standard funktionieren) oder um ein korrektes Verhalten (dh Index muss auf 64 umgewandelt werden Bits für korrektes Verhalten) ?
Das hört sich nach einem Compiler-Bug an.
– Tischler
Benutzeravatar von Adrian Mole
Adrian Mol
Ich weiß, dass die Frage beantwortet ist, aber ich konnte nicht widerstehen, diese Erklärung zu teilen. a Ich erinnere mich an Prinzipien des Compiler-Designs: Nehmen wir an int ist ein int Array und Größe von 2ist a und die Basisadresse für 1000ist
. a[5] Wie wird
Base Address of your Array a + (index of array *size of(data type for array a))
Base Address of your Array a + (5*size of(data type for array a))
i.e. 1000 + (5*2) = 1010
Arbeit -> a[-5] Diese Erklärung ist auch der Grund, warum negative Indizes in Arrays in C funktionieren; dh wenn ich zugreife
Base Address of your Array a + (index of array *size of(data type for array a))
Base Address of your Array a + (-5 * size of(data type for array a))
i.e. 1000 + (-5*2) = 990
es wird mir geben:
Es wird das Objekt an Position 990 zurückgeben. Durch diese Logik können wir also auf negative Indizes in Arrays in C zugreifen.
Das hört sich nach einem Compiler-Bug an.
– Tischler
Benutzeravatar von Maximilian Ast
Maximilian Ast
Warum sollte jemand negative Indizes verwenden, ich habe sie in zwei Kontexten verwendet:[1][-1] Eine Tabelle mit kombinatorischen Zahlen haben, die Ihnen sagt, dass Sie kämmen
= 0; Sie können Indizes immer überprüfen, bevor Sie auf die Tabelle zugreifen, aber auf diese Weise sieht der Code sauberer aus und wird schneller ausgeführt.
while (x < a[i]) i--;
Zentinel am Anfang einer Tabelle setzen. Zum Beispiel möchten Sie etwas wie verwenden i aber das solltest du dann auch prüfen
ist positiv. a[-1] Lösung: Mach es so -DBLE_MAXist x<a[-1] so dass
14242700cookie-checkSind negative Array-Indizes in C erlaubt?yes