124 votes

Comment incrémenter l'adresse et la valeur d'un pointeur ?

Supposons que,

int *p;
int a = 100;
p = &a;

Que fera le code suivant et comment ?

p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);

Je sais que c'est un peu désordonné en termes de codage, mais je veux savoir ce qui se passera réellement lorsque nous coderons comme cela.

Note : Supposons que l'adresse de a=5120300 il est stocké dans le pointeur p dont l'adresse est 3560200 . Maintenant, quelle sera la valeur de p & a après l'exécution de chaque instruction ?

246voto

felipemaia Points 2881

Tout d'abord, l'opérateur ++ est prioritaire sur l'opérateur *, et les opérateurs () sont prioritaires sur tout le reste.

Deuxièmement, l'opérateur ++nombre est le même que l'opérateur ++nombre si vous ne les affectez à rien. La différence est que number++ renvoie le nombre et l'incrémente ensuite, tandis que ++number incrémente d'abord le nombre et le renvoie ensuite.

Troisièmement, en augmentant la valeur d'un pointeur, vous l'incrémentez de la taille de son contenu, c'est-à-dire que vous l'incrémentez comme si vous itériez dans un tableau.

Donc, pour résumer :

ptr++;    // Pointer moves to the next int position (as if it was an array)
++ptr;    // Pointer moves to the next int position (as if it was an array)
++*ptr;   // The value pointed at by ptr is incremented
++(*ptr); // The value pointed at by ptr is incremented
++*(ptr); // The value pointed at by ptr is incremented
*ptr++;   // Pointer moves to the next int position (as if it was an array). But returns the old content
(*ptr)++; // The value pointed at by ptr is incremented
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content
*++ptr;   // Pointer moves to the next int position, and then get's accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault

Comme il y a beaucoup de cas ici, il se peut que j'aie fait des erreurs, merci de me corriger si je me trompe.

EDIT :

J'avais donc tort, la jurisprudence est un peu plus compliquée que ce que j'ai écrit, voir ici : http://en.cppreference.com/w/cpp/language/operator_precedence

17voto

Sujith R Kumar Points 159

A vérifié le programme et les résultats sont les suivants,

p++;    // use it then move to next int position
++p;    // move to next int and then use it
++*p;   // increments the value by 1 then use it 
++(*p); // increments the value by 1 then use it
++*(p); // increments the value by 1 then use it
*p++;   // use the value of p then moves to next position
(*p)++; // use the value of p then increment the value
*(p)++; // use the value of p then moves to next position
*++p;   // moves to the next int location then use that value
*(++p); // moves to next location then use that value

7voto

Rico Picone Points 118

Ce qui suit est une instanciation des diverses suggestions "imprimez simplement". Je l'ai trouvée instructive.

#include "stdio.h"

int main() {
    static int x = 5;
    static int *p = &x;
    printf("(int) p   => %d\n",(int) p);
    printf("(int) p++ => %d\n",(int) p++);
    x = 5; p = &x;
    printf("(int) ++p => %d\n",(int) ++p);
    x = 5; p = &x;
    printf("++*p      => %d\n",++*p);
    x = 5; p = &x;
    printf("++(*p)    => %d\n",++(*p));
    x = 5; p = &x;
    printf("++*(p)    => %d\n",++*(p));
    x = 5; p = &x;
    printf("*p++      => %d\n",*p++);
    x = 5; p = &x;
    printf("(*p)++    => %d\n",(*p)++);
    x = 5; p = &x;
    printf("*(p)++    => %d\n",*(p)++);
    x = 5; p = &x;
    printf("*++p      => %d\n",*++p);
    x = 5; p = &x;
    printf("*(++p)    => %d\n",*(++p));
    return 0;
}

Il renvoie

(int) p   => 256688152
(int) p++ => 256688152
(int) ++p => 256688156
++*p      => 6
++(*p)    => 6
++*(p)    => 6
*p++      => 5
(*p)++    => 5
*(p)++    => 5
*++p      => 0
*(++p)    => 0

J'ai transformé les adresses des pointeurs en int afin de pouvoir les comparer facilement.

Je l'ai compilé avec GCC.

4voto

Flexo Points 39273

En ce qui concerne "Comment incrémenter l'adresse et la valeur d'un pointeur ? Je pense que ++(*p++); est en fait bien défini et fait ce que vous demandez, par exemple :

#include <stdio.h>

int main() {
  int a = 100;
  int *p = &a;
  printf("%p\n",(void*)p);
  ++(*p++);
  printf("%p\n",(void*)p);
  printf("%d\n",a);
  return 0;
}

Il ne s'agit pas de modifier deux fois la même chose avant un point de séquence. Je ne pense pas que ce soit un bon style pour la plupart des utilisations - c'est un peu trop cryptique à mon goût.

3voto

Abhishek D K Points 323
        Note:
        1) Both ++ and * have same precedence(priority), so the associativity comes into picture.
        2) in this case Associativity is from **Right-Left**

        important table to remember in case of pointers and arrays: 

        operators           precedence        associativity

    1)  () , []                1               left-right
    2)  *  , identifier        2               right-left
    3)  <data type>            3               ----------

        let me give an example, this might help;

        char **str;
        str = (char **)malloc(sizeof(char*)*2); // allocate mem for 2 char*
        str[0]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char
        str[1]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char

        strcpy(str[0],"abcd");  // assigning value
        strcpy(str[1],"efgh");  // assigning value

        while(*str)
        {
            cout<<*str<<endl;   // printing the string
            *str++;             // incrementing the address(pointer)
                                // check above about the prcedence and associativity
        }
        free(str[0]);
        free(str[1]);
        free(str);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X