Supposons s
et t
sont char *
s qui pointent vers des chaînes de caractères (et d'assumer s
est au moins aussi grand que t
). En C, les chaînes de tous les fin en 0
(ASCII "NUL"), correct? Qu'est ce que cela à faire:
*s++ = *t++;
Tout d'abord, il n' *s = *t
,, copie de la valeur en *t
de *s
. Ensuite, il n' s++
, alors s
pointe maintenant vers le caractère suivant. Et puis il ne t++
, alors t
points au caractère suivant. Cela a à voir avec la priorité de l'opérateur et du préfixe vs postfix incrémenter/décrémenter.
La priorité de l'opérateur est l'ordre dans lequel les opérateurs sont résolus. Pour un exemple simple, regardez:
4 + 2 * 3
Est-ce 4 + (2 * 3)
ou (4 + 2) * 3
? Eh bien, nous savons qu'il est le premier à cause de la priorité - binaires - *
(opérateur de multiplication) a une priorité plus élevée que le binaire +
(opérateur d'addition), et est résolu en premier.
En *s++
, nous avons unaire *
(déréférencement de pointeur de l'opérateur) et unaires ++
(postfix opérateur d'incrémentation). Dans ce cas, ++
a une priorité plus élevée (dit aussi "lier serré") que *
. Si on avait dit, ++*s
, nous incrémenter la valeur en *s
plutôt que de l' adresse pointée par s
parce que le préfixe de l'incrément a priorité inférieure* comme déréférencement, mais nous avons utilisé postfix incrément, qui a une priorité plus élevée. Si l'on avait voulu utiliser le préfixe de l'incrément, nous pourrions avoir fait *(++s)
, depuis la parenthèse aurait remplacé tous en bas de priorités et forcé ++s
venir en premier, mais cela aurait l'effet indésirable en laissant un vide de caractères au début de la chaîne.
Notez que juste parce qu'elle a une priorité plus élevée ne signifie pas qu'il arrive en premier. Postfix incrément spécifiquement arrive après la valeur a été utilisé, ce qui à son pourquoi *s = *t
qui se produit avant l' s++
.
Alors maintenant, vous comprenez *s++ = *t++
. Mais ils l'ont mis dans une boucle:
while(*s++ = *t++);
Cette boucle n'est rien - l'action est tout dans la condition. Mais de vérifier que la condition qu'il renvoie "false" si *s
jamais 0, ce qui signifie *t
a 0, ce qui signifie qu'ils étaient à la fin de la chaîne (yay pour ASCII "NUL"). Si cette boucle tourne tant qu'il y a des caractères en t
, et les copies consciencieusement en s
, l'incrémentation s
et t
tout le chemin. Lorsque cette boucle s'arrête, s
a été NUL de terminaison, et est une chaîne correcte. Le seul problème est, s
de points à la fin. Garder un autre pointeur de la pratique qui pointe vers le début de l' s
(c - s
avant l' while()
boucle) - qui sera votre copié chaîne:
char *s, *string = s;
while(*s++ = *t++);
printf("%s", string); // prints the string that was in *t
Alternativement, regardez ça:
size_t i = strlen(t);
while(*s++ = *t++);
s -= i + 1;
printf("%s\n", s); // prints the string that was in *t
Nous avons commencé par l'obtention de la longueur, de sorte que lorsque nous avons terminé, nous n'avons plus l'arithmétique des pointeurs de mettre s
de retour au début, où il a commencé.
Bien sûr, ce fragment de code (et toutes mes fragments de code) ignorer tampon questions pour des raisons de simplicité. La meilleure version est ceci:
size_t i = strlen(t);
char *c = malloc(i + 1);
while(*s++ = *t++);
s -= i + 1;
printf("%s\n", s); // prints the string that was in *t
free(c);
Mais tu le savais déjà, ou vous allez bientôt poser une question sur préférée de tout le monde site web à ce sujet. ;)
* En fait, ils ont la même priorité, mais c'est résolu par des règles différentes. Effectivement ils ont de priorité plus basse dans cette situation.