Étant donné ce codeExplique la sortie de l'extrait suivant?
char *s = "Abbas";
printf("%s", s + s[1] - s[3]);
Pourquoi est-ce la sortie?
bbas
Étant donné ce codeExplique la sortie de l'extrait suivant?
char *s = "Abbas";
printf("%s", s + s[1] - s[3]);
Pourquoi est-ce la sortie?
bbas
char *s = "Abbas";
s + s[1] - s[3]
s + 'b' - 'a'
s + 1 /* Assuming ascii encoding. Posibly the machine where you tested, (s + 'b') - 'a' = s + 1 */
"bbas"
Pour mieux comprendre imprimer les valeurs suivantes
printf("%c (%d), %c (%d), %c - %c = %d\n",
/* ^^^^ ^^^*/
s[1],s[1],s[3],s[3], s[3], s[1],s[3] - s[1]);
printf("%s - %s - %s", s, s+1, s+2);
Disposition de la mémoire
+-----+-----+-----+-----+-----+-----+
| 'A' | 'b' | 'b' | 'a' | 's' | '\0'|
+-----+-----+-----+-----+-----+-----+
s s+1 s+2 s+3 s+4 s+5
EDIT
Comme indiqué dans les autres réponses et commentaires, s+s[1]-s[3]
conduit à UB. Pour vous assurer que vous obtenez bbas
en sortie, vous devez utiliser parantesis autour expression plus tard: s+(s[1]-s[3])
comme noté sur les autres réponses,' s + 'b' - 'a'' à 's + 1' n'est pas comment C fonctionne; l'association est de gauche à droite –
@MattMcNabb Exactement ce n'est pas comme cela que ça fonctionne. C'est juste pour faciliter l'explication pour que les lecteurs comprennent mieux. (a + b) - c = a + (bc) tant que (b> c ou b et c sont signés positifs) et (a est non signé ou a ne déborde pas), ou en mots simples sur la plupart des systèmes disponible. –
L'arithmétique du pointeur @MohitJain n'est définie que dans l'objet tableau, 's + 'b'' provoque un comportement indéfini. (Votre réponse explique ce qui pourrait arriver sur les systèmes qui utilisent un modèle de mémoire plate et ne piège pas les pointeurs hors limites) –
Votre sortie est erronée. sortie sera: bbas
Parce que, s pointe sur la base du tableau permet de dire 0x10.
et s[1]
donne « b » et s[3]
donne « un »
0x10 + 'b' -'a' = 0x10 + 1 = 0x11
impression démarre à partir s[1]
. alors la sortie sera bbas
s
pointe vers le début de la chaîne. s[1]
est le deuxième élément, c'est-à-dire b
et s[3]
est le 4ème élément a
. Lorsque vous faites s[1]-s[3]
, c'est-à-dire 'b' - 'a'
, il fait en réalité de l'arithmétique sur les valeurs ASCII des caractères et 'b'-'a'
est 1 dans la table ASCII. Ainsi, vous imprimez à partir de s+1
, c'est-à-dire à partir de la 2ème lettre ==>"bbas"
En fait, la sortie doit être "bbas"!
s est un pointeur
s + "un certain nombre" signifie que vous déplacez le pointeur vers l'avant
int votre cas: s [1] = 'b' et s [3] = 'a 'qui sera interprété comme des chiffres, basé sur le code ASCI, où' b 'est un pas plus grand que' a ', donc vous allez ajouter +1 à s et sauter la première lettre
Le code fait cela parce qu'un char
peut convertir en int
et vous pouvez ajouter un int
à un pointer
.
Parce que s[1]
est 'b'
et s[3]
est 'a'
et b
est probablement 98
et a
est 97
que vous faites s+98-97
Ce que je remettrais en question est de savoir si ce comportement est en réalité non définie sans paranthèses. Il me semble que c'est parce que vous ne pouvez pas ajouter 98 à l'adresse s
.
Ce serait bien défini: s + (s[1]-s[3])
bien qu'il soit encore horrible.
FYI sur le sujet de UB: http://stackoverflow.com/questions/10473573/why-is-out -of-bounds-pointer-arithmetic-undefined-behavior (merci jrok et MattMcNabb!) – quetzalcoatl
Je me trompe peut-être ici (n'hésitez pas à me le dire si je le suis), mais n'est-ce pas le cas de 's + 98' seulement un problème si vous essayez ensuite de le dé-référencer? Dans ce cas '* ((s + s [1]) - s [3])' est 'valide' (mais toujours absolument écoeurant). – Baldrickk
@Baldrickk regarde la question référencée. s + 98 n'est pas garanti pour être quelque chose de significatif et soustraire 97 à nouveau n'est pas garanti de vous donner s + 1. – CashCow
La sortie doit être '' bbas'', pas '' bhas'' ' –
Son impression est juste ("% s ", s + 1); déguisé;) –
Personne n'a mentionné que 's + s [1] -s [3]' peut mener à un comportement indéfini selon la sous-expression évaluée en premier. Si c'est l'addition, le pointeur résultant est hors limites et UB s'ensuit. (EDIT: [CashCow] (http://stackoverflow.com/a/25870312/947836) fait, en réalité.) – jrok