Ich habe gerade einen Code gelesen und festgestellt, dass die Person verwendet hat, arr[-2]
um auf das zweite Element vor dem zuzugreifen arr
, wie folgt:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Ist das erlaubt
Ich weiß, das arr[x]
ist das gleiche wie *(arr + x)
. So arr[-2]
ist es *(arr - 2)
, was in Ordnung zu sein scheint. Was denken Sie?
somearray-2
ist undefiniert, es sei denn, das Ergebnis liegt im Bereich von Anfangsomearray
bis 1 nach seinem Ende.[]
wurden sie als Syntaxzucker für die Zeigerarithmetik bezeichnet. Die beliebteste Art, Anfänger zu verwirren, besteht darin, zu schreiben1[arr]
- anstattarr[1]
- und ihnen zuzusehen, wie sie raten, was das bedeuten soll.((E1)+(E2))
ein (64-Bit-) Zeiger mit dem erwarteten Wert sein wird.Dies ist nur gültig, wenn
arr
es sich um einen Zeiger handelt, der auf das zweite Element in einem Array oder einem späteren Element zeigt. Andernfalls ist es nicht gültig, da Sie außerhalb der Grenzen des Arrays auf Speicher zugreifen würden. Das wäre zum Beispiel falsch:Aber das wäre okay:
Es ist jedoch ungewöhnlich, einen negativen Index zu verwenden.
quelle
int arr[10];
ein Teil einer Struktur mit anderen Elementen davorarr[-2]
möglicherweise genau definiert sein, und Sie könnten feststellen, ob er aufoffsetof
usw. basiert .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.
Ich habe es gegen Ende in K & R Abschnitt 5.3 gefunden: Ihr Beispiel hilft mir jedoch besser, es zu verstehen. Vielen Dank!Klingt gut für mich. Es wäre jedoch ein seltener Fall, dass Sie es jedoch zu Recht benötigen würden.
quelle
Was wahrscheinlich war,
arr
zeigte auf die Mitte des Arrays, wodurcharr[-2]
auf etwas im ursprünglichen Array gezeigt wurde, ohne die Grenzen zu überschreiten.quelle
Ich bin mir nicht sicher, wie zuverlässig dies ist, aber ich habe gerade die folgende Einschränkung zu negativen Array-Indizes auf 64-Bit-Systemen (vermutlich LP64) gelesen: http://www.devx.com/tips/Tip/41349
Der Autor scheint zu sagen, dass 32-Bit-Int-Array-Indizes mit 64-Bit-Adressierung zu fehlerhaften Adressberechnungen führen können, es sei denn, der Array-Index wird explizit auf 64 Bit hochgestuft (z. B. über eine ptrdiff_t-Umwandlung). Ich habe tatsächlich einen Fehler seiner 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 der Index benötigt eine Umwandlung in 64) Bits für korrektes Verhalten)?
quelle
Ich weiß, dass die Frage beantwortet ist, aber ich konnte nicht widerstehen, diese Erklärung zu teilen.
Ich erinnere mich an die Prinzipien des Compiler-Designs. Nehmen wir an, a ist ein int-Array und die Größe von int ist 2, und die Basisadresse für a ist 1000.
Wie
a[5]
wird es funktionieren ->Diese Erklärung ist auch der Grund, warum negative Indizes in Arrays in C funktionieren.
dh wenn ich darauf zugreife
a[-5]
, gebe ich esEs wird mir ein Objekt an Position 990 zurückgeben. Durch diese Logik können wir auf negative Indizes in Array in C zugreifen.
quelle
Warum jemand negative Indizes verwenden möchte, habe ich in zwei Zusammenhängen verwendet:
Eine Tabelle mit kombinatorischen Zahlen, aus der hervorgeht, dass Sie [1] [- 1] = 0 kämmen; Sie können Indizes immer überprüfen, bevor Sie auf die Tabelle zugreifen. Auf diese Weise sieht der Code jedoch sauberer aus und wird schneller ausgeführt.
Einen Centinel an den Anfang eines Tisches setzen. Zum Beispiel möchten Sie so etwas wie verwenden
aber dann solltest du auch überprüfen, ob das
i
positiv ist.Lösung: macht es so , dass
a[-1]
ist-DBLE_MAX
, so dassx<a[-1]
immer falsch sein wird.quelle
quelle