Effet de “+1” après le paramètre de chaîne de format sur printf ()

J’ai quelques problèmes liés à ce code. Le paramètre de printf est de type const char* and ... (liste d’arguments variables).

1) Pourquoi la sortie du programme est-elle d et non 127 ?
2) Est-ce que le +1 serait converti en chaîne et passé à une variable de paramètre de type const char* ?

 #include int main() { printf("%d"+1 , 127); //how this will get executed? return 0; } 

Sortie:

 d 

Le premier paramètre est un pointeur sur char .
Le littéral "%d" serait un pointeur sur le '%' , qui est implicitement suivi de 'd' et '\0' . C’est un pointeur sur char , car c’est la représentation en C des littéraux de chaîne: séquences de caractères avec un '\0' à la fin; représenté pour une utilisation en tant que parameters, etc., comme pointeur sur char .
Mais "%d"+1 , selon l’arithmétique du pointeur, est un pointeur sur 'd' , suivi de '\0' .
Les deux sont terminés à zéro, ce qui convient pour un paramètre à printf.

Donc, le résultat est le même que

 printf("d", ignored); 

127 devient “ignoré”, c’est-à-dire qu’il est ignoré, car le "d" indique à printf de ne rien attendre, car il ne contient aucune des séquences de caractères spéciaux, par exemple “% someletter”. Donc, il ne s’attendra pas, ne cherchera rien et ne fera aucune impression au-delà de la ficelle parfaitement normale qu’il pense avoir été donnée.
Notez cependant que les parameters supplémentaires, ceux qui ne sont couverts par aucun élément de la chaîne de format, sont évalués puis ignorés. Ceci est pertinent, car tous les effets secondaires (appels de fonction, par exemple) de cette évaluation se produisent réellement.
Voir par exemple ici pour plus de détails:
http://en.cppreference.com/w/c/io/fprintf

Permettez-moi d’essayer d’aider et d’append à la réponse de @Yunnosch:

  char *str = "%d"; printf (str, 127); 

et la sortie devrait être:

 127 

Dans l’exemple ci-dessus, str est stocké dans la mémoire comme ceci (il ne s’agit que d’un exemple et, dans la vie réelle, les adresses sont comme 0xabcdef12345678):

 address | memory --------+-------------- 0 | % 1 | d 3 | \0 

so str pointe sur l’adresse 0 (ou son équivalent sur votre système) qui contient % , printf() obtient cette adresse et commence à lire à partir de là, lit jusqu’à atteindre le caractère NULL ‘\ 0’. Maintenant, chaque fois qu’il voit le % il recherche le caractère suivant d , c , x etc., il lit l’argument suivant de la liste d’arguments. Si vous avez fourni d , le résultat est décimal, si vous fournissez c , le caractère sera imprimé, x est pour hex et il y en a beaucoup plus. Donc printf() lira tous les caractères et remplacera % par le paramètre approprié jusqu’à atteindre le caractère NULL \0 , mais il commencera à l’adresse fournie.

Ton cas:

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

est identique à:

 char *str = "%d"; printf (str + 1, 127); // printf receives address of character `d` as starting point 

ou il est similaire à

 char *str = "%d"; char *str1 = str+1; // increment the address of ssortingng by one printf (str1, 127) 

dans les deux cas, il reçoit l’adresse de d et lit à partir de là jusqu’à atteindre \0 .

Si vous faites ce qui suit:

 printf ("%d" + 2, 127); 

Ce serait la même chose que:

 char *str = "%d"; printf (str + 2, 127); 

cela ne produirait rien car printf() obtiendra l’adresse de \0 . et comme @Yunnosh l’a dit, 127 seraient ignorés.

Ainsi, +1 et +2 ne sont pas convertis en une chaîne, ils sont ajoutés à l’adresse de la chaîne.

J’espère que cela aide, je pense avoir répondu à vos deux questions.