3
votes

Si je déclare un tableau de caractères, dois-je également compter le caractère nul?

Par exemple:

char array[][5] = {"game", "house"};

Est-ce que house convient au tableau ou dois-je ajouter le caractère nul donc je dois déclarer comme ceci: p >

char array [] [6] = {"game", "house"};

c

6 commentaires

@xing mais si je le compile et l'imprime, il fonctionne avec 5 colonnes.


@xing il imprime "jeu maison"


@xing pourquoi imprime-t-il "housegame game"?


Si vous souhaitez stocker une chaîne à N caractères dans un tableau, le tableau doit avoir au moins N + 1 éléments de large pour tenir compte du terminateur 0. Oui, vous pouvez insérer {'h', 'o', 'u', 's', 'e'} dans un tableau à 5 éléments, mais ce n'est pas une chaîne , et si vous passez ce tableau comme argument à quelque chose qui attend une chaîne, vous obtiendrez probablement des résultats inattendus.


@xing: Généralement, les compilateurs ne doivent pas avertir sur char array [] [5] = {"game", "house"}; . Il est strictement conforme C d'initialiser un tableau qui correspond juste aux caractères explicites et qui n'a pas de place pour le caractère nul de fin.


user11006304, "il imprime" housegame game "-> Postez le code qui fait cela pour plus de clarté.


4 Réponses :


4
votes

Si vous utilisez le tableau comme chaîne , il doit inclure le caractère nul de fin. Le caractère nul de fin fait partie du tableau et doit être inclus dans sa taille.

De nombreuses routines standard de la bibliothèque C acceptent des arguments qui sont des chaînes , qui sont des tableaux de caractères terminés par un caractère nul.

Il est également possible d'utiliser un tableau de caractères pour vos propres besoins, sans le passer à une fonction de bibliothèque standard qui nécessite une chaîne. Si c'est ainsi que vous utiliserez le tableau, il n'a pas besoin d'inclure un caractère nul de fin.

Lorsque vous initialisez un tel tableau avec des littéraux de chaîne, vous n'avez pas besoin d'inclure d'espace pour le caractère nul de fin dans la taille du tableau. Le caractère nul de fin dans la chaîne littérale sera utilisé pour initialiser un élément de tableau uniquement s'il y a de la place pour cela.


2 commentaires

Détail: "les routines de la bibliothèque prennent des arguments qui sont des pointeurs vers chaînes"


@chux: selon 7.1.1 1, une chaîne est "une séquence contiguë de caractères terminée par et incluant le premier caractère." Cela décrit un tableau (selon 6.2.5 20, un type de tableau décrit un «ensemble d'objets non vides alloués de manière contiguë avec un type d'objet membre particulier»). Donc, passer une chaîne, c'est passer un tableau, qui est converti en un pointeur vers son premier caractère. Passer un pointeur vers une chaîne reviendrait à passer char (*) [] , ce qui est faux. L'article 7 utilise «pointeur vers une chaîne» comme vous le feriez, mais il est néanmoins incohérent. Nous pourrions dire "pointeur vers le premier caractère d'une chaîne".



2
votes

Cela dépend de ce que vous avez l'intention de faire avec les chaînes.

La définition

char array[][6] = {"game", "house"};

initialisera array avec la dimension 2 et 5 . array [0] sera initialisé avec les éléments 'g', 'a', 'm', 'e', ​​'\ 0' et array [ 1] comme 'h', 'o', 'u', 's', 'e' . Notez l'absence du '\ 0' de fin sur array[1 .

Ce qui se passe alors dépend de ce que votre code fait ensuite avec le tableau . Par exemple;

for (i = 0; i < 2; ++i)
{
   printf("%s\n", array[i]);
}

imprimera avec plaisir deux lignes avec game et house dans le stdout code >, puisque les boucles se limitent spécifiquement à ne pas accéder à un élément de tableau en dehors des limites.

Cependant,

for (i = 0; i < 2; ++i)
{
   for (j = 0; j < 5, ++j)
   {
       if (array[i][j] != '\0')
           printf("%c", array[i][j]);
       else
           j = 5;    /*   terminate the inner loop */
   }       
   printf("\n");
}

aura un comportement non défini, puisque le % s imprimera chaque caractère du array [i] jusqu'à ce qu'un '\ 0' de fin soit trouvé. Puisque array [1] est initialisé sans '\ 0' de fin, printf () s'exécutera généralement au-delà de la fin de la boucle du tableau ie quelle que soit la mémoire qui se trouve être située immédiatement après la fin du array , et affichez tous les déchets qu'il trouve jusqu'à ce qu'il trouve un caractère avec la valeur '\ 0' . S'il n'y a pas de tel caractère dans la mémoire disponible pour le programme, alors le programme peut simplement continuer à imprimer des caractères inutiles, puis se bloquer (par exemple, si le système d'exploitation hôte détecte le programme accédant à la mémoire, il ne devrait pas et termine de force le programme) / p>

La règle générale est: si vous utilisez des fonctions qui ASSUMENT la présence d'un '\ 0' de fin ( printf () avec le % s format, strcat () , strcmp () , etc etc) alors il est nécessaire de s'assurer que le terminateur est présent. Cela signifie s'assurer que le tableau contient suffisamment d'éléments ET initialiser l'un de ces éléments à '\0'.

Si vous initialisez à la place array comme p >

char array[][5] = {"game", "house"};

alors les deux array [0] et array [1] ont le terminateur requis.


0 commentaires

0
votes

Juste une remarque: le fait de manger silencieusement le caractère NULL terminal des chaînes littérales est une fonctionnalité de C uniquement. En C ++, il est interdit de fournir des chaînes d'initialisation plus grandes que le tableau à initialiser.


1 commentaires

Bien que cette remarque soit vraie, elle est superflue puisque la question est étiquetée en C et non en C ++.



2
votes
<house>
<game>

0 commentaires