Initialisation du tableau C char

Je ne suis pas sûr de ce qui sera dans le tableau de caractères 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 que buf[0] devrait être ' ' , buf[1] devrait être '\0' et de buf[2] à buf[9] serait un contenu aléatoire. Pour le cas 3, je pense que buf[0] devrait être 'a' , buf[1] devrait être ‘\ 0’ et de buf[2] à buf[9] serait un contenu aléatoire.

Est-ce exact?

Et pour le cas 1, que sera le buf ? buf[0] == '\0' et de buf[1] à buf[9] sera un contenu aléatoire?

Ce n’est pas comme cela que vous initialisez 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’initialiseurs, le rest du tableau est initialisé avec 0 . C’est le cas même si le tableau est déclaré dans une fonction.

Edit: OP (ou un éditeur) a changé en silence certaines des guillemets simples de la question initiale en guillemets à un moment donné après avoir fourni cette réponse.

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

 char buf[10] ; buf = '' 

est doublement illégal. Tout d’abord, en C, il n’y a pas de caractère vide. Vous pouvez utiliser des guillemets pour désigner une chaîne vide, comme avec:

 char* buf = ""; 

Cela vous donnera un pointeur sur une chaîne NUL , c’est-à-dire une chaîne de caractères unique avec uniquement le caractère NUL . Mais vous ne pouvez pas utiliser des guillemets simples sans rien à l’intérieur – c’est indéfini. Si vous devez désigner le caractère NUL , vous devez le spécifier:

 char buf = '\0'; 

La barre oblique inverse est nécessaire pour désambiguïser du caractère '0' .

 char buf = 0; 

accomplit la même chose, mais le premier est un peu moins ambigu à lire, je pense.

Deuxièmement, vous ne pouvez pas initialiser les tableaux après leur définition.

 char buf[10]; 

déclare et définit le tableau. L’identificateur de tableau buf est maintenant une adresse en mémoire, et vous ne pouvez pas modifier l’endroit où buf affecté par l’affectation. Alors

 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 rest étant NUL , c’est-à-dire '\0' . Lorsqu’un tableau est déclaré et défini avec un initialiseur, les éléments du tableau (le cas échéant) dépassant ceux avec les valeurs initiales spécifiées sont automatiquement remplis avec 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 ci-dessous:

 char buf [10]; 

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

  1. Ce sont des équivalents

     char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  2. Ce sont des équivalents

     char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  3. Ce sont des équivalents

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

La partie pertinente de l’initialisation de la version standard n11 de la version 1.1.7 de C11 indique:

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

et

21 S’il y a moins d’initialiseurs dans une liste entourée d’accolades qu’il y a d’éléments ou de membres d’un agrégat, ou moins de caractères dans un littéral de chaîne utilisé pour initialiser un tableau de taille connue qu’il y a d’éléments dans le tableau, doivent être initialisés implicitement de la même manière que les objects qui ont une 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 d’un caractère static char c; serait initialisé dans une fonction.

Finalement,

10 Si un object avec une durée de stockage automatique n’est pas initialisé explicitement, sa valeur est indéterminée. Si un object qui a une durée de stockage statique ou de thread n’est pas initialisé explicitement, alors:

[-]

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

[]

Ainsi, le caractère char étant un type arithmétique, le rest du tableau est également garanti initialisé par des zéros.

Il est intéressant de noter qu’il est possible d’initialiser des tableaux à tout moment dans le programme, à condition qu’ils soient membres d’une struct ou d’une union .

Exemple de programme:

 #include  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 comstackr 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; } 

Je ne suis pas sûr mais j’initialise généralement un tableau à “” dans ce cas, je n’ai pas besoin de m’inquiéter de la fin nulle de la chaîne.

 main() { void something(char[]); char s[100] = ""; something(s); printf("%s", s); } void something(char s[]) { // ... do something, pass the output to s // no need to add s[i] = '\0'; because all unused slot is already set to '\0' }