web-dev-qa-db-fra.com

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 peut être correct.
Ce que je cherche, c'est comment se déroule pas à pas ce processus.

On dirait que ça devient:

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

Ou est-ce que je me trompe totalement?

19
zubergu

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
    
21
Dave

my_data est une structure avec name comme champ et data[] est une liste de structures, vous initialisez chaque index. lisez ce qui suit: 

5.20 Initializer 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 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" }
}; 

Comprendre l'initialisation du tableau read Strange initializer expression?
De plus, vous voudrez peut-être aussi lire @ Shafik Yaghmour la réponse de/en cas de commutation: Qu'est-ce que «…» en cas de commutation en code C

19
Grijesh Chauhan

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'objet 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 é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'objet 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.

13
AnT

Cela s'appelle désigné initializer qui est introduit dans C99. Il est utilisé pour initialiser struct ou les 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 };
2
Yu Hao

C’est très simple: my_data est un type de structure antérieurement défini . Vous voulez donc déclarer un tableau my_data- de certains é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';

Cela s'appelle un initialiseur désigné (comme 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.

1
dhein

C'est un désigné initializer , introduit avec le standard C99; il vous permet d'initialiser des membres spécifiques d'un objet struct ou union par leur nom. my_data est évidemment un typedef pour un type struct ayant un membre name de type char * ou char [N]

0
John Bode