Ik was net wat code aan het lezen en ontdekte dat de persoon arr[-2]
gebruikte om toegang te krijgen tot het 2e element vóór de arr
, zoals zo:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Mag dat?
Ik weet dat arr[x]
hetzelfde is als *(arr + x)
. Dus arr[-2]
is *(arr - 2)
, wat goed lijkt. Wat denk je?
Antwoord 1, autoriteit 100%
Dat klopt. Vanaf C99 §6.5.2.1/2:
De definitie van het subscript
operator [] is dat E1[E2] is
identiek aan (*((E1)+(E2))).
Er is geen magie. Het is een 1-1 equivalentie. Zoals altijd wanneer u een verwijzing naar een aanwijzer (*) verwijdert, moet u er zeker van zijn dat deze naar een geldig adres verwijst.
Antwoord 2, autoriteit 39%
Dit is alleen geldig als arr
een pointer is die verwijst naar het tweede element in een array of een later element. Anders is het niet geldig, omdat u toegang zou krijgen tot geheugen buiten de grenzen van de array. Dit zou bijvoorbeeld verkeerd zijn:
int arr[10];
int x = arr[-2]; // invalid; out of range
Maar dit zou goed zijn:
int arr[10];
int* p = &arr[2];
int x = p[-2]; // valid: accesses arr[0]
Het is echter ongebruikelijk om een negatief subscript te gebruiken.
Antwoord 3, autoriteit 8%
Klinkt goed voor mij. Het zou echter zelden voorkomen dat u het legitiem nodig zou hebben.
Antwoord 4, autoriteit 5%
Waarschijnlijk was dat arr
naar het midden van de array wees, waardoor arr[-2]
naar iets in de originele array wees zonder buiten de grenzen te gaan .
Antwoord 5, autoriteit 4%
Ik weet niet zeker hoe betrouwbaar dit is, maar ik las zojuist het volgende voorbehoud over negatieve array-indexen op 64-bits systemen (vermoedelijk LP64): http://www.devx.com/tips/Tip/41349
De auteur lijkt te zeggen dat 32-bits int-array-indexen met 64-bits adressering kunnen resulteren in slechte adresberekeningen, tenzij de array-index expliciet wordt gepromoveerd tot 64 bits (bijvoorbeeld via een ptrdiff_t-cast). Ik heb eigenlijk een bug van zijn aard gezien met de PowerPC-versie van gcc 4.1.0, maar ik weet niet of het een compilerbug is (dwz zou moeten werken volgens de C99-standaard) of correct gedrag (dwz index heeft een cast nodig naar 64 bits voor correct gedrag) ?
Antwoord 6, autoriteit 2%
Ik weet dat de vraag is beantwoord, maar ik kon het niet laten om deze uitleg te delen.
Ik herinner me de principes van compilerontwerp: laten we aannemen dat a
een int
-array is en dat de grootte van int
2
, en het basisadres voor a
is 1000
.
Hoe werkt a[5]
->
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
Deze verklaring is ook de reden waarom negatieve indexen in arrays werken in C; d.w.z. als ik a[-5]
benader, krijg ik:
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
Het zal het object op locatie 990 retourneren. Dus door deze logica hebben we toegang tot negatieve indexen in arrays in C.