J’ai le code suivant qui se bloque à la ligne où j’initialise ch
:
char * p = "Test"; char ch = *p++; printf("Here : %s\n%c", p, ch);
Cependant le code suivant n’a pas de problème:
char * p = "Test"; char ch = *p++; ch++; printf("Here : %s\n%c", p, ch);
Dans le premier cas, vous essayez de modifier le T
dans la chaîne “Test” compilée dans le programme, qui est conservée dans une partie de la mémoire que votre code n’est pas censé changer (généralement; il existe des environnements dans lesquels autorisé, mais ce n’est généralement pas le cas. C’est parce que (*p)++
signifie (en gros) *p = *p + 1
(par exemple, indiquez le caractère pointé par p
, augmentez-le et écrivez-le en retour), et bien sûr, *p
pointe sur le compilé dans “Test”.
Votre deuxième version n’a pas ce problème, car vous incrémentez ch
, que vous êtes autorisé à modifier. Votre deuxième version incrémente en réalité deux choses différentes; en premier lieu, char ch = *p++;
qui récupère le caractère en *p
puis incrémente p
(maintenant, il pointe vers le “e” dans “Test”), puis vous faites ch = ch++
. (Vous avez probablement voulu dire juste ch++;
là, car ++
opère directement sur son opérande.)
Le problème se résume à la priorité des opérateurs et à l’utilisation de parenthèses ()
.
char ch = (*p)++;
Cette ligne (tentera) d’incrémenter le caractère à l’adresse enregistrée dans p
char ch = *p++;
Celui-ci définit ch
égal au caractère à l’adresse stockée dans p
, puis incrémente l’adresse stockée dans p
. L’opérateur ++
a priorité sur l’opérateur de déréférencement du pointeur; il sera donc exécuté en premier. Pour être clair, la deuxième ligne est équivalente à:
char ch = *(p++);
Votre premier exemple incrémente la valeur de *p
. Puisque p pointe sur une constante de chaîne, cela n’est pas autorisé avec beaucoup de compilateurs.
Votre deuxième exemple incrémente le pointeur, pas la valeur à laquelle il pointe.
Ce code:
(*p)++
essaie d’incrémenter la valeur que p pointe. p pointe sur la chaîne de caractères “Test”, qui ne peut pas être modifiée.
La première version fait ceci:
char * p = "Test"; //this should really be const char * *p = *p + 1; //CRASH! attempthing to modifiy the contents of a ssortingng literal char ch = *p; ch = ch++; //This is excessive, ch++ on it's own would do the same printf("Here : %s\n%c", p, ch);
Pendant que la deuxième version fait ceci:
char * p = "Test"; //still should be const char * char ch = *p; p++; //p now points to "est" ch = ch++; printf("Here : %s\n%c", p, ch); //prints est\nU