Question

J'ai trouvé un code d'initialisation de struct hier qui m'a lancé pour une boucle. Voici un exemple:

typedef struct { int first; int second; } TEST_STRUCT;
void testFunc() {
    TEST_STRUCT test = {
        second: 2,
        first:  1
    };
    printf("test.first=%d test.second=%d\n", test.first, test.second);
}

Étonnamment (pour moi), voici le résultat:

-> testFunc
test.first=1 test.second=2

Comme vous pouvez le constater, la structure est correctement initialisée. Je ne savais pas que les déclarations étiquetées pouvaient être utilisées comme ça J'ai vu plusieurs autres façons de faire l'initialisation de la structure, mais je n'ai trouvé aucun exemple de ce type d'initialisation de la structure dans les FAQ en ligne sur le C. Quelqu'un sait-il comment / pourquoi cela fonctionne?

Était-ce utile?

La solution

Voici la section du manuel gcc qui explique la syntaxe des initialiseurs désignés pour les structures et les tableaux:

  

Dans un initialiseur de structure, spécifiez le nom du champ à initialiser.   avec ' .fieldname = ' avant la valeur de l'élément. Par exemple, étant donné le   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 du champ: ", comme indiqué ici:

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

La page en question se trouve ici .

Votre compilateur devrait avoir une documentation similaire.

Autres conseils

Ce ne sont ni des étiquettes ni des champs de bits.

Ceci est une syntaxe pour initialiser les membres de la structure remontant à la période antérieure à C99. Il n’est pas normalisé, mais disponible par exemple dans gcc.

typedef struct { int y; int x; } POINT;
POINT p = { x: 1, y: 17 };

En C99, la syntaxe d'initialisation de membres de structure spécifiques a été introduite pour la première fois dans une norme, mais elle a un aspect légèrement différent:

typedef struct { int y; int x; } POINT;
POINT p = { .x = 1, .y = 17 };

Oui, comme indiqué ci-dessus, il s’agit d’initialiseurs, qui sont en C standard, bien que vous deviez utiliser des points au lieu de deux points. Et comme vous le constatez, la plupart des livres sont encore bloqués vers 1984 dans leur syntaxe et ne parviennent pas à les mentionner. Plus de faits amusants:

- Lorsque vous utilisez des initialiseurs désignés, tout ce qui n'est pas spécifié est initialisé à zéro. Cela aide avec des structures exceptionnellement grandes, par exemple:

typedef struct {
   double a, b, c, d, e;
   char label[100];
} too_many_type;

too_many_type tm = {.a = 1, .e = 2, .b=1.5};
assert(tm.a + tm.b + tm.c + tm.d + tm.e == 4.5);
assert(!strlen(label));

- Vous pouvez également utiliser la forme littérale composée pour utiliser cette forme sur une ligne de non-initialisation, par exemple:

too_many_type tm2;
tm2 = (too_many_type) {.a = 3, .e=6};

Ce sont vraiment de très bonnes fonctionnalités, et sont supportées par tous les compilateurs C auxquels je peux penser, étant que c’est la norme. C'est dommage qu'ils ne soient pas aussi connus.

Ce n'est pas vraiment des "instructions étiquetées", mais un moyen de donner des valeurs initiales aux champs nommés dans la structure.

Gcc donne un avertissement sur "l'utilisation obsolète de l'initialiseur désigné avec ':'", et dans C99, vous devriez plutôt écrire:

    TEST_STRUCT test = {
        .second = 2,
        .first =  1
    };

Cette syntaxe n'est pas définie par le standard C. La section 6.7.8 Initialisation dit

         designation:
                designator-list =
         designator-list:
                designator
                designator-list designator
         designator:
                [ constant-expression ]
                . identifier

Si votre compilateur accepte une désignation avec deux points sans message de diagnostic, cela signifie que votre compilateur n'est pas (ou n'est pas configuré pour être) conforme aux normes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top