Domanda

Ieri ho trovato un codice di inizializzazione della struttura che mi ha lanciato per un ciclo. Ecco un esempio:

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);
}

Sorprendentemente (per me), ecco l'output:

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

Come puoi vedere, la struttura viene inizializzata correttamente. Non sapevo che le dichiarazioni etichettate potessero essere usate così. Ho visto diversi altri modi per eseguire l'inizializzazione della struttura, ma non ho trovato esempi di questo tipo di inizializzazione della struttura in nessuna delle domande frequenti in linea di C. Qualcuno è a conoscenza di come / perché funziona?

È stato utile?

Soluzione

Ecco la sezione del manuale di gcc che spiega la sintassi degli inizializzatori designati sia per le strutture che per le matrici:

  

In un inizializzatore di struttura, specificare il nome di un campo da inizializzare   con " .fieldname = " prima del valore dell'elemento. Ad esempio, dato il   struttura seguente,

 struct point { int x, y; };
     

la seguente inizializzazione

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

è equivalente a

 struct point p = { xvalue, yvalue }; 
     

Un'altra sintassi che ha lo stesso significato, obsoleta da GCC 2.5, è ' fieldname: ', come mostrato qui:

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

La pagina pertinente è disponibile qui .

Il compilatore dovrebbe avere una documentazione simile.

Altri suggerimenti

Queste non sono né etichette né campi di bit.

Questa è una sintassi per inizializzare i membri struct risalenti ai giorni precedenti C99. Non è standardizzato ma disponibile ad es. gcc.

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

In C99, la sintassi per l'inizializzazione di membri specifici della struttura è stata introdotta per la prima volta in uno standard, ma ha un aspetto leggermente diverso:

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

Sì, come indicato sopra, questi sono inizializzatori designati, che sono standard C, anche se dovresti passare a usare punti invece di due punti. E come notate, la maggior parte dei libri là fuori sono ancora bloccati da qualche parte intorno al 1984 nella loro sintassi e non li menzionano. Altre curiosità:

- Quando si utilizzano inizializzatori designati, tutto ciò che non specificato viene inizializzato su zero. Questo aiuta con strutture eccezionalmente grandi, ad es .:

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));

- Inoltre, è possibile utilizzare il modulo letterale composto per utilizzare questo modulo su una riga di non inizializzazione, ad es .:

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

Queste sono funzioni davvero eccezionali e sono supportate da ogni compilatore C che mi viene in mente, essendo questo lo standard. È un peccato che non siano così conosciuti.

In realtà non è " istruzioni etichettate " ;, ma un modo per dare valori iniziali ai campi nominati nella struttura.

Gcc dà un avvertimento sull'uso obsoleto dell'inizializzatore designato con ':' " ;, e in C99 dovresti invece scrivere:

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

Tale sintassi non è definita dallo standard C. La sezione 6.7.8 Inizializzazione dice

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

Se il compilatore accetta una designazione con due punti senza un messaggio di diagnostica significa che il compilatore non è (o è configurato per non essere) conforme agli standard.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top