La chaîne AC est un tableau de caractères qui se termine par un terminateur nul .
Tous les caractères ont une valeur de table de symboles. Le terminateur nul est la valeur du symbole 0
(zéro). Il est utilisé pour marquer la fin d'une chaîne. Cela est nécessaire car la taille de la chaîne n'est stockée nulle part.
Par conséquent, chaque fois que vous allouez de la place à une chaîne, vous devez inclure suffisamment d'espace pour le caractère de terminaison nul. Votre exemple ne fait pas cela, il alloue uniquement de la place pour les 5 caractères de "hello"
. Le code correct doit être:
char str[6] = "hello";
Ou de manière équivalente, vous pouvez écrire du code auto-documenté pour 5 caractères plus 1 terminateur nul:
char str[5+1] = "hello";
Lors de l'allocation dynamique de mémoire pour une chaîne au moment de l'exécution, vous devez également allouer de l'espace pour le terminateur nul:
char input[n] = ... ;
...
char* str = malloc(strlen(input) + 1);
Si vous n'ajoutez pas de terminateur nul à la fin d'une chaîne, les fonctions de bibliothèque qui attendent une chaîne ne fonctionneront pas correctement et vous obtiendrez des bogues de "comportement indéfini" tels que la sortie des ordures ou les plantages du programme.
La façon la plus courante d'écrire un caractère de terminaison NULL dans C est à l'aide d' un soi-disant « séquence d'échappement octal », qui ressemble à ceci: '\0'
. Cela équivaut à 100% à l'écriture 0
, mais le \
sert de code auto-documenté pour indiquer que le zéro est explicitement destiné à être un terminateur nul. Un code tel que if(str[i] == '\0')
vérifiera si le caractère spécifique est le terminateur nul.
Veuillez noter que le terme null terminator n'a rien à voir avec les pointeurs null ou la NULL
macro! Cela peut être déroutant - des noms très similaires mais des significations très différentes. C'est pourquoi le terminateur nul est parfois appelé NUL
un L, à ne pas confondre avec NULL
ou des pointeurs nuls. Voir les réponses à cette question SO pour plus de détails.
Le "hello"
dans votre code est appelé un littéral de chaîne . Cela doit être considéré comme une chaîne en lecture seule. La ""
syntaxe signifie que le compilateur ajoutera automatiquement un terminateur nul à la fin du littéral de chaîne. Donc, si vous imprimez, sizeof("hello")
vous obtiendrez 6, pas 5, car vous obtenez la taille du tableau, y compris un terminateur nul.
Il compile proprement avec gcc
En effet, pas même un avertissement. Cela est dû à un détail / défaut subtil dans le langage C qui permet d'initialiser les tableaux de caractères avec un littéral de chaîne qui contient exactement autant de caractères qu'il y a de place dans le tableau, puis de supprimer silencieusement le terminateur nul (C17 6.7.9 / 15). Le langage se comporte volontairement comme ceci pour des raisons historiques, voir Diagnostic gcc incohérent pour l'initialisation de la chaîne pour plus de détails. Notez également que C ++ est différent ici et ne permet pas d'utiliser cette astuce / faille.
char str[] = "hello";
cas.