152 votes

Initialisation du tableau de chars en C

Je ne suis pas sûr de ce qui se trouvera dans le tableau de chars après l'initialisation de la manière suivante.

1. char buf[10] = "";
2. char buf[10] = " ";
3. char buf[10] = "a";

Pour le cas 2, je pense buf[0] devrait être ' ' , buf[1] devrait être '\0' et de buf[2] à buf[9] sera un contenu aléatoire. Pour le cas 3, je pense buf[0] devrait être 'a' , buf[1] devrait être \0 ', et de buf[2] à buf[9] sera un contenu aléatoire.

Est-ce exact ?

Et pour le cas 1, qu'est-ce qu'il y aura dans les buf ? buf[0] == '\0' et de buf[1] à buf[9] sera un contenu aléatoire ?

270voto

ouah Points 75311

Ce n'est pas comme ça qu'on initialise un tableau, mais pour :

  1. La première déclaration :

    char buf[10] = "";

    est équivalent à

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  2. La deuxième déclaration :

    char buf[10] = " ";

    est équivalent à

    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
  3. La troisième déclaration :

    char buf[10] = "a";

    est équivalent à

    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};

Comme vous pouvez le voir, pas de contenu aléatoire : s'il y a moins d'initialisateurs, le reste du tableau est initialisé avec 0 . C'est le cas même si le tableau est déclaré à l'intérieur d'une fonction.

42voto

Steven Penny Points 18523
  1. Ceux-ci sont équivalents

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  2. Ceux-ci sont équivalents

    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
  3. Ceux-ci sont équivalents

    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};

31voto

verbose Points 3615

Edit : OP (ou un éditeur) a silencieusement changé certains des guillemets simples dans la question originale en guillemets doubles à un moment donné après que j'ai fourni cette réponse.

Votre code entraînera des erreurs de compilation. Votre premier fragment de code :

char buf[10] ; buf = ''

est doublement illégale. Tout d'abord, en C, il n'existe pas d'objet vide. char . Vous pouvez utiliser des guillemets doubles pour désigner une chaîne vide, comme avec :

char* buf = ""; 

Cela vous donnera un pointeur vers un NUL c'est-à-dire une chaîne à un seul caractère avec seulement l'élément NUL personnage. Mais vous ne pouvez pas utiliser de guillemets simples sans rien à l'intérieur - c'est indéfini. Si vous devez désigner le NUL vous devez le spécifier :

char buf = '\0';

La barre oblique inverse est nécessaire pour éviter toute ambiguïté par rapport au caractère '0' .

char buf = 0;

accomplit la même chose, mais la première est un peu moins ambiguë à lire, je pense.

Deuxièmement, vous ne pouvez pas initialiser les tableaux après qu'ils ont été définis.

char buf[10];

déclare et définit le tableau. L'identifiant du tableau buf est maintenant une adresse dans la mémoire, et vous ne pouvez pas changer l'endroit où buf points grâce à l'affectation. Donc

buf =     // anything on RHS

est illégal. Vos deuxième et troisième fragments de code sont illégaux pour cette raison.

Pour initialiser un tableau, vous devez le faire au moment de la définition :

char buf [10] = ' ';

vous donnera un tableau de 10 caractères, le premier étant l'espace. '\040' et le reste étant NUL c'est-à-dire, '\0' . Lorsqu'un tableau est déclaré et défini avec un initialisateur, les éléments du tableau (s'il y en a) après ceux qui ont des valeurs initiales spécifiées sont automatiquement remplis de 0 . Il n'y aura pas de "contenu aléatoire".

Si vous déclarez et définissez le tableau mais ne l'initialisez pas, comme dans l'exemple suivant :

char buf [10];

vous aurez un contenu aléatoire dans tous les éléments.

14voto

Antti Haapala Points 11542

La partie pertinente du projet de norme C11 n1570 6.7.9 initialisation dit :

14 Un tableau de type caractère peut être initialisé par un littéral de chaîne de caractères ou une chaîne UTF-8. éventuellement entouré d'accolades. Les octets successifs du littéral de chaîne de caractères (y compris le de fin de chaîne s'il y a de la place ou si le tableau est de taille inconnue) initialisent la fonction éléments du tableau.

et

21 S'il y a moins d'initialisateurs dans une liste encadrée par des accolades qu'il n'y a d'éléments ou de membres d'un agrégat, ou moins de caractères dans une chaîne littérale utilisée pour initialiser un tableau de données connues. connue qu'il n'y a d'éléments dans le tableau, le reste de l'agrégat est initialisé implicitement de la même manière que les objets qui ont durée de stockage statique.

Ainsi, le ' \0 est ajouté, s'il y a assez d'espace et les caractères restants sont initialisés avec la valeur que a static char c; serait initialisé dans une fonction.

Enfin,

10 Si un objet qui a une durée de stockage automatique n'est pas initialisé explicitement, sa valeur est indéterminée. Si un objet qui a statique ou la durée de stockage du fil n'est pas initialisée explicitement, alors :

[--]

  • s'il est de type arithmétique, il est initialisé à zéro (positif ou non signé) ;

[--]

Así, char étant un type arithmétique, le reste du tableau est également garanti d'être initialisé avec des zéros.

3voto

user3381726 Points 153

Il est intéressant de noter qu'il est possible d'initialiser les tableaux de n'importe quelle manière et à n'importe quel moment du programme, à condition qu'ils soient membres d'un groupe struct o union .

Exemple de programme :

#include <stdio.h>

struct ccont
{
  char array[32];
};

struct icont
{
  int array[32];
};

int main()
{
  int  cnt;
  char carray[32] = { 'A', 66, 6*11+1 };    // 'A', 'B', 'C', '\0', '\0', ...
  int  iarray[32] = { 67, 42, 25 };

  struct ccont cc = { 0 };
  struct icont ic = { 0 };

  /*  these don't work
  carray = { [0]=1 };           // expected expression before '{' token
  carray = { [0 ... 31]=1 };    // (likewise)
  carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *'
  iarray = (int[32]){ 1 };      // (likewise, but s/char/int/g)
  */

  // but these perfectly work...
  cc = (struct ccont){ .array='a' };        // 'a', '\0', '\0', '\0', ...
  // the following is a gcc extension, 
  cc = (struct ccont){ .array={ [0 ... 2]='a' } };  // 'a', 'a', 'a', '\0', '\0', ...
  ic = (struct icont){ .array={ 42,67 } };      // 42, 67, 0, 0, 0, ...
  // index ranges can overlap, the latter override the former
  // (no compiler warning with -Wall -Wextra)
  ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ...

  for (cnt=0; cnt<5; cnt++)
    printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);

  return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X