comment printf imprime-t-il une chaîne terminée par un caractère null?

Le livre de programmation c dit que ma chaîne doit être terminée par un caractère nul pour l’imprimer à l’aide de printf, mais le programme suivant l’imprime malgré son caractère non nul !!

#include  #include  int main(){ int i ; char str[10] ; for(i = 0 ; i < 10 ; i++ ) { str[i] = (char)(i+97) ; } printf("%s",str) ; } 

J’utilise codeblocks IDE.

C’est un comportement indéfini de lire au-delà des limites d’un tableau, vous étiez malchanceux de ne pas le planter. Si vous l’exécutez suffisamment de fois ou appelez-le dans une fonction, il peut (ou non) se bloquer, vous devez toujours terminer la chaîne ou utilisez un spécificateur de largeur:

 printf("%.10s", str); 

Quoi que ce soit après le 10ème élément de str se trouve être nul. Ce null est en dehors des limites définies du tableau, mais C n’a pas de vérification des limites du tableau. Dans votre cas, c’est un coup de chance que c’est ainsi que les choses se sont passées.

Selon le standard C, la fonction printf imprime le caractère dans la chaîne jusqu’à ce qu’elle trouve un caractère nul. Sinon, après l’index de tableau défini, ce qu’il va faire n’est pas défini. J’ai testé votre code. et après avoir imprimé “abcdefghij”, il affiche une valeur résiduelle.

Si vous faites autre chose avant cet appel, votre zone de stack contiendra des données autres que celles non utilisées. Imagine ça:

 #include  #include  #include  int use_stack(void) { char str[500]; memset(str, 'X', sizeof(str)); printf("Filled memory from %p to %p.\n", &str, &str+sizeof str); } void print_stuff() { int i; char str[16]; // changed that so that 10..15 contain X for(i = 0; i < 10; i++) { str[i] = (char)(i+97); } printf("%s",str); // have a line break before ? Then it comes from i. printf("&str: %p\n", &str); printf("&i: %p\n", &i); // Here you see that i follows str as &i is &str + 16 (0x10 in hex) } int main() { use_stack(); print_stuff(); } 

votre zone de stack sera pleine de X es et printf() les verra.

Dans votre situation et dans votre environnement, la stack est «propre» par coïncidence au démarrage du programme.

EDIT: Cela peut ou peut ne pas arriver. Si le compilateur place la variable i immédiatement après le tableau, vos données seront néanmoins terminées par NUL , car le premier octet est la valeur de i (que vous devez également afficher – il peut s’agir d’une rupture libne dans votre cas – et le deuxième octet est un octet NUL même si c’est le cas, votre code appelle UB (comportement indéfini).

Pouvez-vous regarder (en hexdump sortie du programme dans hexdump ou similaire) si votre sortie contient un caractère 0A ? Si c’est le cas, je suppose que c’est correct. Je viens de le tester, et sur mon compilateur ( gcc ), cela semble être le chemin.

Comme dit, rien ne devrait compter sur vous.

EDIT2: Si vous voyez une rupture de ligne avant le , j’imaginais que c’était vrai. Et si vous regardez les pointeurs en cours d’impression, vous pouvez comparer leurs adresses en mémoire.

Parce qu’en mode débogage, *(str+10) et tout l’espace inutilisé ont une valeur initialisée ‘0’, il semble donc que 0 soit terminé.

 bash-3.2$ clang -O0 tc -ot #comstack in debug mode bash-3.2$ ./t abcdefghij bash-3.2$ clang -O2 tc -ot #comstack with optimization bash-3.2$ ./t abcdefghij2÷d=