Initialisation du tableau de structures

Voici l’initialisation que je viens de trouver dans la question de quelqu’un d’autre.

my_data data[]={ { .name = "Peter" }, { .name = "James" }, { .name = "John" }, { .name = "Mike" } }; 

Je n’avais jamais vu quelque chose comme ça auparavant et je ne trouve pas d’explication sur la manière dont .name est possible d’être correct.
Ce que je cherche, c’est comment ce processus se déroule étape par étape.

On dirait que ça devient:

 1) data; 2) *data; 3) (*data).name; 4) (*data).name="Peter"; 

Ou est-ce que je me trompe totalement?

Il n’y a que deux syntaxes en jeu ici.

  1. Initialisation simple et ancienne du tableau:

     int x[] = {0, 0}; // x[0] = 0, x[1] = 0 
  2. Un initialisateur désigné . Voir la réponse acceptée à cette question: Comment initialiser une structure conformément aux normes du langage de programmation C

    La syntaxe est cependant assez explicite. Vous pouvez initialiser comme ceci:

     struct X { int a; int b; } struct X foo = { 0, 1 }; // a = 0, b = 1 

    ou d’utiliser n’importe quel ordre,

     struct X foo = { .b = 0, .a = 1 }; // a = 1, b = 0 

my_data est une structure dont le name est un champ et data[] contient plusieurs structures, vous initialisez chaque index. lisez ce qui suit:

5.20 initialiseurs désignés :

Dans un initialiseur de structure, spécifiez le nom d’un champ à initialiser avec .fieldname =' avant la valeur de l’élément. Par exemple, étant donné la structure suivante,

  struct point { int x, y; }; 

l’initialisation suivante

  struct point p = { .y = yvalue, .x = xvalue }; 

est équivalent à

  struct point p = { xvalue, yvalue }; 

Une autre syntaxe ayant la même signification, obsolète depuis GCC 2.5, est nom de fieldname:' , comme indiqué ici:

  struct point p = { y: yvalue, x: xvalue }; 

Vous pouvez aussi écrire:

 my_data data[]={ { .name = "Peter" }, { .name = "James" }, { .name = "John" }, { .name = "Mike" } }; 

comme:

 my_data data[]={ { [0].name = "Peter" }, { [1].name = "James" }, { [2].name = "John" }, { [3].name = "Mike" } }; 

La seconde forme peut être pratique car vous n’avez pas besoin d’écrire, par exemple, l’équivalent ci-dessus est équivalent à:

 my_data data[]={ { [3].name = "Mike" }, { [1].name = "James" }, { [0].name = "Peter" }, { [2].name = "John" } }; 

Pour comprendre l’initialisation du tableau, lisez l’ expression étrange d’initialiseur?
De plus, vous voudrez peut-être aussi lire la réponse de Shafik Yaghmour à propos du cas de commutateur: Qu’est-ce que «…» dans un cas de commutation en code C?

Il n’y a pas de “étape par étape” ici. Lorsque l’initialisation est effectuée avec des expressions constantes, le processus est essentiellement effectué au moment de la compilation. Bien sûr, si le tableau est déclaré en tant qu’object local, il est alloué localement et initialisé au moment de l’exécution, mais cela peut toujours être considéré comme un processus en une seule étape qui ne peut pas être subdivisé de manière significative.

Les initialiseurs désignés vous permettent de fournir un initialiseur pour un membre spécifique de l’object struct (ou un élément spécifique d’un tableau). Tous les autres membres sont initialisés à zéro. Donc, si my_data est déclaré comme

 typedef struct my_data { int a; const char *name; double x; } my_data; 

alors votre

 my_data data[]={ { .name = "Peter" }, { .name = "James" }, { .name = "John" }, { .name = "Mike" } }; 

est simplement une forme plus compacte de

 my_data data[4]={ { 0, "Peter", 0 }, { 0, "James", 0 }, { 0, "John", 0 }, { 0, "Mike", 0 } }; 

J’espère que vous savez ce que fait ce dernier.

C’est ce qu’on appelle l’ initialiseur désigné qui est introduit dans C99. Il est utilisé pour initialiser struct ou des tableaux, dans cet exemple, struct .

Donné

 struct point { int x, y; }; 

l’initialisation suivante

 struct point p = { .y = 2, .x = 1 }; 

est équivalent au style C89

 struct point p = { 1, 2 }; 

C’est assez simple: my_data est un type de structure défini auparavant. Donc, vous voulez déclarer un my_data my_data de quelques éléments, comme vous le feriez avec

 char a[] = { 'a', 'b', 'c', 'd' }; 

Donc, le tableau aurait 4 éléments et vous les initialisez comme

 a[0] = 'a', a[1] = 'b', a[1] = 'c', a[1] ='d'; 

Ceci est appelé un initialiseur désigné (si je me souviens bien).

et cela indique simplement que les données doivent être de type my_dat et être un tableau qui doit stocker tellement de structures my_data qu’il existe une structure avec chaque nom de membre de type Peter, James, John et Mike.

C’est un initialiseur désigné , introduit avec la norme C99; il vous permet d’initialiser des membres spécifiques d’un object struct ou union par leur nom. my_data est évidemment une typedef pour un type struct qui a un name de membre de type char * ou char [N] .