46 votes

Pourquoi *p++ est-il différent de *p += 1 ?

Pensez-y :

void foo1(char **p) { *p++; }
void foo2(char **p) { *p += 1; }

y

char *s = "abcd";
char *a = s; 
foo1(&a); 
printf("%s", a); //abcd

mais si j'utilise foo2() au lieu de :

char *a = s; 
foo2(&a); 
printf("%s", a); //bcd

Quelqu'un peut-il l'expliquer ?

97voto

La clé est la préséance de la += et le ++ opérateur. Le site ++ a une priorité plus élevée que le += (en fait, les opérateurs d'affectation ont la deuxième plus faible priorité en C), de sorte que l'opération

*p++

signifie déréférencer le pointeur, puis incrémenter le pointeur. lui-même par 1 (comme d'habitude, selon les règles de l'arithmétique des pointeurs, ce n'est pas nécessairement un octet, mais plutôt sizeof(*p) concernant l'adresse résultante). D'autre part,

*p += 1

signifie l'incrémentation de la valeur pointé par le pointeur par un (et ne rien faire avec le pointeur lui-même).

29voto

Alan Curry Points 6612

Prédominance. Le postfixe ++ se lie plus étroitement que le préfixe * donc il incrémente p . Le site += se trouve à l'extrémité inférieure de la liste de précédence, avec l'opérateur d'affectation simple, et ajoute donc 1 à *p .

0voto

Manjunath Gk Points 48

La prépondérance des préfixes ++ et * est la même. L'associativité des deux est de droite à gauche. La prépondérance du postfixe ++ est supérieure à celle de * et du préfixe ++. L'associativité du postfixe ++ est de gauche à droite.

0voto

G. Simsic Points 21

Commençons par *p += 1

Je vais essayer de répondre à cette question sous un angle un peu différent... Étape 1 Regardons les opérateurs et les opérandes : Dans ce cas, il s'agit d'un seul opérande (le pointeur p), et nous avons deux opérateurs, dans ce cas * pour le déréférencement et += 1 pour l'incrémentation. Étape 2 : qui a la priorité la plus élevée ? * a une priorité plus élevée que +=.


*P++ Celui-ci est un peu plus délicat... peut-être même méchant. Encore une fois nous avons un opérande (p le pointeur) et deux opérateurs, seulement maintenant le * pour la déréférence et le ++ pour l'incrémentation sont de la même précédence. (Dans certains tableaux, le ++ de post est d'une plus grande préséance).

Étape 1 Regardons les opérateurs et les opérandes : Dans ce cas, c'est l'opérande, et vous avez deux opérateurs, dans ce cas * pour le déréférencement et ++ pour l'incrémentation. Étape 2 : lequel a la plus haute priorité ? ++ a une plus grande précédence que * Note : même s'ils ont la MÊME précédence, ils s'associent de droite à gauche, encore une fois, le ++ est avant *. Étape 3 (la partie délicate...) Où se trouve ++ ? il est à droite de l'opérande, ce qui signifie que Incrément de POST Dans ce cas, le compilateur prend une "note mentale" pour effectuer l'incrémentation. APRÈS c'est fait avec tous les autres opérateurs... Que signifie "après" ? Cela signifie qu'il n'appliquera l'incrément qu'en tant que toute toute toute dernière étape avant le prochain ';', donc il sera fait avec tous les autres opérateurs qui sont sur la même 'ligne'. note : si c'était *++p alors il le fera AVANT tout autre opérateur sur la même ligne donc dans ce cas, c'est équivalent à prendre deux registres du processeur, un contiendra la valeur de *p déréférencé et l'autre contiendra la valeur de p++ incrémenté, la raison dans ce cas il y a deux, est l'activité POST... C'est là que dans ce cas, c'est délicat, et cela ressemble à une contradiction. On pourrait s'attendre à ce que le ++ soit prioritaire sur le *, ce qui est le cas, mais le POST signifie qu'il ne sera appliqué qu'après TOUS les autres opérandes, AVANT le prochain jeton " ;"...

Comme je l'ai dit, la partie délicate est que tout incrément qui est à droite d'un opérande sera mis de côté, et sera appliqué comme la DERNIERE opération avant de passer à la ligne suivante...

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