Qu'est-ce que '-1




arrays pointers (4)

Ce qui se passe ici est vraiment intéressant.

p [n] signifie *(p+n) . C’est pour cela que vous voyez 3, car "p" pointe sur le tableau [1] qui correspond à 2 et que -p [1] est interprété comme -(*(p+1)) qui correspond à -3.

Cette question a déjà une réponse ici:

Aujourd'hui, je suis tombé sur une énigme de C qui a eu une nouvelle surprise pour moi.

Je ne pensais pas que -1 [p] dans l'exemple ci-dessous compilerait, mais c'est ce qui s'est passé. En fait, x finit par être -3.

    int x;
    int array[] = {1, 2, 3};
    int *p = &array[1];
    x = -1[p]

J'ai cherché sur Internet quelque chose comme -1 [pointeur] mais je n'ai rien trouvé. D'accord, il est difficile d'entrer la bonne requête de recherche, je l'avoue. Qui sait pourquoi -1 [p] compile et X devient -3?


Cette

int array[] = {1, 2, 3};

ressemble à

array[0]   array[1]  array[2]
 --------------------------
|     1   |    2    |   3  | 
 --------------------------
 0x100     0x104     0x108   <-- lets assume 0x100 is base address of array
array

Ensuite quand tu aimes

int *p = &array[1];

le pointeur entier p pointe sur l'adresse du array[1] savoir 0x104 . On dirait

array[0]   array[1]  array[2]
 --------------------------
|     1   |    2    |   3  | 
 --------------------------
 0x100     0x104     0x108   <-- lets assume 0x100 is base address of array
             |
            p holds 0x104

Et quand tu aimes

x = -1[p]

-1[p] est équivalent à -(1[p]) c'est -(p[1]) dire -(p[1]) . On dirait

-(p[1]) ==> -(*(p + 1*4)) /* p holds points to array[1] i.e 0x104 */
        ==> -(*(0x104 + 4))
        ==> -(*(0x108)) ==> value at 0x108 is 3
        ==> prints -3

La première chose à comprendre est la priorité. À savoir que [] a une priorité plus élevée que les opérateurs unaires, donc -1[p] est égal à -(1[p]) , pas (-1)[p] . Nous prenons donc le résultat de 1[p] et le nions.

x[y] est égal à *(x+y) , donc 1[p] est égal à *(1+p) , ce qui est égal à *(p+1) , ce qui est égal à p[1] .

Nous prenons donc l’élément un après où p indique le troisième élément du array , c’est-à-dire 3, puis nous le nions, ce qui nous donne -3 .


Selon la norme C (6.5.2 opérateurs Postfix), l’opérateur indice est défini comme suit:

postfix-expression [ expression ]

Donc, avant les crochets, il doit y avoir une expression postfixée.

Dans cette déclaration d'expression

x = -1[p];

il est utilisé l'expression postfixe 1 (qui est en même temps une expression primaire), l'expression postfixe 1[p] (c'est-à-dire l'opérateur en indice) et l'opérateur unaire - Tenez compte du fait que lorsque le compilateur divise un programme en jetons alors les constantes entières sont considérées comme des jetons eux-mêmes sans le moins. moins est un jeton séparé.

Donc, la déclaration peut être réécrite comme

x = -( 1[p] );

car une expression postfixe a une priorité supérieure à une expression unaire.

Considérons d’abord la sous-expression postfixe 1[p]

Selon la norme C (6.5.2.1 Indice de matrice)

2 Une expression postfixée suivie d'une expression entre crochets [] est une désignation en indice d'un élément d'un objet tableau. La définition de l'opérateur en indice [] est que E1 [E2] est identique à (* ((E1) + (E2))). En raison des règles de conversion qui s'appliquent à l'opérateur binaire +, si E1 est un objet de tableau (de manière équivalente, un pointeur sur l'élément initial d'un objet de tableau) et E2 est un entier, E1 [E2] désigne l'élément E2 de E1 (à partir de zéro).

Donc, cette sous-expression s’évalue comme *( ( 1 ) + ( p ) ) et est identique à *( ( p ) + ( 1 ) ).

Ainsi, la déclaration ci-dessus

x = -1[p];

est équivalent à

x = -p[1];

et donnera -3 , car le pointeur p pointe sur le deuxième élément du tableau en raison de la déclaration

int *p = &array[1];

et ensuite l'expression p[1] donne la valeur de l'élément après le deuxième élément du tableau. Ensuite, l'opérateur unaire - est appliqué.





postfix-operator