Supposons,
int *p;
int a = 100;
p = &a;
Que fera réellement le code suivant et comment?
p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);
Je sais, c'est un peu compliqué en termes de codage, mais je veux savoir ce qui se passera réellement lorsque nous coderons comme ça.
Remarque: 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?
printf
imprimera un pointeur avec% pRéponses:
Premièrement, l'opérateur ++ a priorité sur l'opérateur *, et les opérateurs () ont priorité sur tout le reste.
Deuxièmement, l'opérateur numérique ++ est le même que l'opérateur nombre ++ si vous ne les attribuez à rien. La différence est que nombre ++ renvoie le nombre, puis incrémente le nombre, et ++ le nombre s'incrémente d'abord, puis le renvoie.
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 répétiez dans un tableau.
Donc, pour résumer le tout:
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 of ptr is incremented ++(*ptr); // The value of ptr is incremented ++*(ptr); // The value of 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 of 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, j'ai peut-être fait une erreur, veuillez me corriger si je me trompe.
ÉDITER:
Donc je me suis trompé, la précédence est un peu plus compliquée que ce que j'ai écrit, regardez-la ici: http://en.cppreference.com/w/cpp/language/operator_precedence
la source
vérifié le programme et les résultats sont comme,
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
la source
Ce qui suit est une instanciation des diverses suggestions «il suffit de l'imprimer». J'ai trouvé cela instructif.
#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 retourne
(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 converti les adresses du pointeur en
int
s afin de pouvoir les comparer facilement.Je l'ai compilé avec GCC.
la source
En ce qui concerne "Comment incrémenter une adresse de pointeur et une valeur de pointeur?" Je pense que cela
++(*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 la même chose deux fois 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.
la source
++*p++
incrémenteront avec succès la valeur et le pointeur (le suffixe++
se lie plus fort que le déréférencement*
, et cela se produit avant le préfixe en++
raison de l'ordre). Les parenthèses ne sont nécessaires que lorsque vous avez besoin de la valeur avant de l'incrémenter(*p++)++
. Si vous choisissez tout préfixe,++*++p
cela fonctionnera très bien sans parenthèses (mais incrémentez la valeur pointée après l'incrément du pointeur).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);
la source