Je lisais juste du code et j'ai trouvé que la personne utilisait arr[-2]
pour accéder au 2ème élément avant le arr
, comme ceci:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Est-ce permis?
Je sais que arr[x]
c'est la même chose *(arr + x)
. Ainsi arr[-2]
est *(arr - 2)
, ce qui semble OK. Qu'est-ce que tu penses?
somearray-2
est indéfini sauf si le résultat est compris entre le débutsomearray
et 1 après sa fin.[]
étaient référencés comme un sucre de syntaxe pour l'arithmétique des pointeurs. La façon préférée de confondre les débutants est d'écrire1[arr]
- au lieu dearr[1]
- et de les regarder deviner ce que cela signifie.((E1)+(E2))
s'agira d'un pointeur (64 bits) avec la valeur attendue.Ceci n'est valide que s'il
arr
s'agit d'un pointeur qui pointe vers le deuxième élément d'un tableau ou un élément ultérieur. Sinon, ce n'est pas valide, car vous accéderiez à la mémoire en dehors des limites du tableau. Donc, par exemple, ce serait faux:Mais ce serait bien:
Il est cependant inhabituel d'utiliser un indice négatif.
la source
int arr[10];
faisait partie d'une structure avec d'autres éléments avant elle,arr[-2]
pourrait potentiellement être bien définie, et vous pourriez déterminer si elle est basée suroffsetof
, etc.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.
Pourtant, votre exemple est meilleur pour m'aider à le comprendre. Merci!Cela me convient. Ce serait un cas rare où vous en auriez légitimement besoin.
la source
Ce qui était probablement qui
arr
pointait vers le milieu du tableau, faisant ainsiarr[-2]
pointer vers quelque chose dans le tableau d'origine sans sortir des limites.la source
Je ne sais pas à quel point cela est fiable, mais je viens de lire la mise en garde suivante concernant les indices de tableau négatifs sur les systèmes 64 bits (probablement LP64): http://www.devx.com/tips/Tip/41349
L'auteur semble dire que les indices de tableau int 32 bits avec un adressage 64 bits peuvent entraîner de mauvais calculs d'adresse à moins que l'index de tableau ne soit explicitement promu à 64 bits (par exemple via un cast ptrdiff_t). J'ai en fait vu un bogue de sa nature avec la version PowerPC de gcc 4.1.0, mais je ne sais pas si c'est un bogue du compilateur (c.-à-d. Devrait fonctionner selon la norme C99) ou un comportement correct (c.-à-d. Que l'index a besoin d'un cast en 64 bits pour un comportement correct)?
la source
Je sais que la question est répondue, mais je n'ai pas pu résister à partager cette explication.
Je me souviens des principes de conception du compilateur, supposons que a est un tableau int et que la taille de int est 2, & l'adresse de base pour a est 1000.
Comment
a[5]
fonctionnera ->Cette explication est également la raison pour laquelle les index négatifs dans les tableaux fonctionnent en C.
ie si j'y accède,
a[-5]
ça me donneraIl me renverra l'objet à l'emplacement 990. Par cette logique, nous pouvons accéder aux index négatifs dans Array en C.
la source
À propos des raisons pour lesquelles quelqu'un voudrait utiliser des index négatifs, je les ai utilisés dans deux contextes:
Avoir une table de nombres combinatoires qui vous indique comb [1] [- 1] = 0; vous pouvez toujours vérifier les index avant d'accéder à la table, mais de cette façon le code semble plus propre et s'exécute plus rapidement.
Mettre un centinel au début d'une table. Par exemple, vous souhaitez utiliser quelque chose comme
mais alors vous devriez également vérifier que
i
c'est positif.Solution: faites en sorte que ce
a[-1]
soit-DBLE_MAX
ainsi, cex<a[-1]
sera toujours faux.la source
la source