Raison de la sortie

#include int main(void) { int a=5; printf("%d"+1,a); } 

Sortie: d. Je n’ai pas compris comment la sortie s’en vient: d?

Vous avez passé le premier argument de printf "%d"+1 ; "%d" est en fait vu comme un caractère const char * qui pointe vers un emplacement mémoire où %d est stocké. Comme avec n’importe quel pointeur, si vous l’incrémentez d’un point, le résultat pointera sur l’élément suivant, qui, dans ce cas, sera d .

a n’est pas utilisé, mais cela ne devrait pas poser de problème, car en général ( je ne sais pas si c’est obligatoire, Edit: oui, voir ci-dessous), la responsabilité du nettoyage de la stack pour les fonctions variadiques revient à l’appelant (du moins , cdecl fait de cette façon , cela peut cependant ne pas être UB, je ne sais pas *).

Vous pouvez le voir plus facilement de cette façon:

 #include int main(void) { int a=5; const char * str="%d"; printf(str + 1, a); } 

 str ---------+ | V +----+----+----+ | % | d | \0 | +----+----+----+ str + 1 ----------+ | V +----+----+----+ | % | d | \0 | +----+----+----+ 

Ainsi, ( "%d"+1 ) (qui est "d" ) est interprété comme la chaîne de formatage, et printf , ne trouvant pas de % , l’imprimera simplement tel quel. Si vous vouliez plutôt imprimer la valeur d’ a plus 1, vous auriez dû faire

 printf("%d", a+1); 

Edit: * ok, ce n’est pas UB, du moins pour la norme C99 (§7.19.6.1.2), il est correct d’avoir des parameters inutilisés dans fprintf :

Si le format est épuisé tant qu’il rest des arguments, les arguments en excès sont évalués (comme toujours) mais sont sinon ignorés.

et printf est défini pour avoir le même comportement au §7.19.6.3.2

La fonction printf est équivalente à fprintf avec l’argument stdout interposé avant les arguments de printf.

Les littéraux de chaîne sont des pointeurs. Faire avancer le pointeur sur "%d" de 1 entraîne "d" . L’argument est jeté.

Vous devriez faire printf("%d", a+1) . "%d" + 1 est un pointeur sur "d" dans un tableau de caractères ( {'%','d','\0'} ).

À cause de +1 . Si vous souhaitez incrémenter a printf("%d", a + 1); : printf("%d", a + 1); au lieu.

Supposons que vous ayez:

 char x[] = "%d"; 

Qu’attendez-vous

 printf(x + 1, a); 

imprimer?

Astuce: tc: 5: warning: trop d’arguments pour le format

“% d” est une constante de chaîne, elle sera stockée dans le caractère char [] de la mémoire. Pendant l’exécution, “% d” renvoie l’emplacement de départ du caractère []. L’augmentation du pointeur d’un tableau de caractères vers un autre pointera vers le caractère suivant. Par conséquent, “d” seul est transmis à la fonction printf. donc la sortie est “d”