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

Considérez:

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

Et

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?

46
c
demandé sur Jack 2012-08-31 23:22:53

4 réponses

, La clé est la priorité de la += et le ++ opérateur. Le ++ a une priorité plus élevée que le += (en fait, les opérateurs d'affectation ont la deuxième priorité la plus basse 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 du pointeur, ce n'est pas nécessairement un octet, mais plutôt sizeof(*p) en ce qui concerne l'adresse résultante). D'autre part,

*p += 1

Signifie incrémenter la valeur pointé par le pointeur par un (et ne rien faire avec le pointeur lui-même).

95
répondu P.P. 2016-01-07 20:48:45

Préséance. Le postfix ++ se lie plus étroitement que le préfixe * de sorte qu'il incrémente p. Le += est à l'extrémité inférieure de la liste de priorité, avec l'opérateur d'affectation simple, donc il ajoute 1 à *p.

29
répondu Alan Curry 2012-08-31 19:25:56

Priorité du préfixe ++ et * est identique. L'associativité des deux est de droite à gauche. La priorité de postfix ++ est supérieure à * et prefix ++. L'associativité de postfix ++ est de gauche à droite.

0
répondu Manjunath Gk 2015-07-23 18:13:13

Commençons par *p += 1

Je vais essayer de répondre à cela sous un angle un peu différent... Étape 1 regardons les opérateurs et les opérandes: dans ce cas c'est un 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ément. Étape 2 qui a la priorité la plus élevée * a la priorité la plus élevée sur + =


*P++ Celui-ci est un peu plus compliqué... peut être même méchant Encore une fois nous avons un opérande (p le pointeur) et deux opérateurs, seulement maintenant, le * for dereference et ++ post increment ont la même priorité. (Dans certaines tables, le ++ dans un post est une priorité plus élevée.)

Étape 1 regardons les opérateurs et les opérandes: Dans ce cas, il est l'opérande, et vous avez deux opérateurs, dans ce cas * pour un déréférencement et ++ pour incrémenter. Étape 2 qui a la priorité? ++ a une priorité plus élevée que * Note: même s'ils ont la même priorité qu'ils associent de droite à gauche, encore une fois, le ++ est avant * Étape 3 (le partie délicate...) Où est ++ ? c'est à droite de l'opérande, ce qui signifie Post Increment dans ce cas, le compilateur prend une 'note mentale' pour effectuer l'incrément après c'est fait avec tous les autres opérateurs... Quels moyens? Cela signifie qu'il n'appliquera l'incrément que comme la très très dernière étape avant la prochaine ';' donc cela 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, il est aussi équivalent à prendre deux du registre du processeur, l'un tiendra la valeur du déréférencé *p et l'autre tiendra la valeur du incrémenté P++, la raison dans ce cas il y en a deux, est L'activité POST... C'est là que dans ce cas, c'est délicat, et cela ressemble à une contradiction. On s'attendrait à ce que le ++ prenne la priorité sur le*, CE qu'il fait, seulement que le POST signifie qu'il ne sera appliqué qu'après tout autre opérandes, avant le jeton ';' suivant...

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

0
répondu G. Simsic 2017-05-02 13:18:51