Condividi tramite


Inizializzazione dei tipi di aggregazione

Un tipo di aggregazione è una struttura, un'unione o un tipo di matrice. Se un tipo di aggregazione contiene membri di tipi di aggregazione, le regole di inizializzazione vengono applicate in modo ricorsivo.

Sintassi

initializer:
{ initializer-list } /* Per l'inizializzazione aggregata */
{ initializer-list , }

initializer-list:
initializer
initializer-list , initializer

initializer-list è un elenco di inizializzatori separati da virgole. Ogni inizializzatore nell'elenco è un'espressione costante o un elenco di inizializzatori. Pertanto, gli elenchi di inizializzatori possono essere annidati. Questo modulo è utile per inizializzare i membri aggregati di un tipo di aggregazione, come illustrato negli esempi di questa sezione. Tuttavia, se l'inizializzatore per un identificatore automatico è una singola espressione, non deve essere un'espressione costante; deve semplicemente avere un tipo appropriato per l'assegnazione all'identificatore.

Per ogni elenco di inizializzatori, i valori delle espressioni costanti vengono assegnati, in ordine, ai membri corrispondenti della variabile di aggregazione.

Se initializer-list ha meno valori di un tipo di aggregazione, i membri o gli elementi rimanenti del tipo di aggregazione vengono inizializzati su 0. Il valore iniziale di un identificatore automatico non inizializzato in modo esplicito non è definito. Se initializer-list ha più valori di un tipo di aggregazione, viene restituito un errore. Queste regole si applicano a ogni elenco di inizializzatori incorporati e all'aggregazione nel suo complesso.

L'inizializzatore di una struttura è un'espressione dello stesso tipo o un elenco di inizializzatori per i relativi membri racchiusi tra parentesi graffe ({ }). I membri del campo di bit senza nome non vengono inizializzati.

Quando viene inizializzata un'unione, initializer-list deve essere una singola espressione costante. Il valore dell'espressione costante viene assegnato al primo membro dell'unione.

Se una matrice ha dimensioni sconosciute, il numero di inizializzatori determina le dimensioni della matrice e il relativo tipo diventa completo. Non è possibile specificare la ripetizione di un inizializzatore in C o di inizializzare un elemento al centro di una matrice senza fornire anche tutti i valori precedenti. Se è necessaria questa operazione nel programma, scrivere la routine nel linguaggio assembly.

Il numero di inizializzatori può impostare le dimensioni della matrice:

int x[ ] = { 0, 1, 2 }

Se si specificano le dimensioni e si assegna il numero errato di inizializzatori, tuttavia, il compilatore genera un errore.

Sezione specifica Microsoft

Le dimensioni massime per una matrice sono definite da size_t.

Fine sezione specifica Microsoft

Esempi

Questo esempio mostra gli inizializzatori per una matrice.

int P[4][3] =
{
    { 1, 1, 1 },
    { 2, 2, 2 },
    { 3, 3, 3,},
    { 4, 4, 4,},
};

Questa istruzione dichiara P come matrice quattro per tre e inizializza gli elementi della prima riga su 1, gli elementi della seconda riga a 2 e così via, fino alla quarta riga. L'elenco di inizializzatori per la terza e la quarta riga contiene virgole dopo l'ultima espressione costante. Anche l'ultimo elenco di inizializzatori ({4, 4, 4,},) è seguito da una virgola. Queste virgole aggiuntive sono consentite ma non sono necessarie. Sono necessarie solo virgole che separano le espressioni costanti l'una dall'altra e le virgole che separano un elenco di inizializzatori da un altro.

Se un membro aggregato non ha un elenco di inizializzatori incorporati, i valori vengono assegnati, in ordine, a ogni membro del subaggregato. Pertanto, l'inizializzazione nell'esempio precedente è equivalente all'esempio seguente:

int P[4][3] =
{
   1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4
};

Le parentesi graffe possono anche essere visualizzate intorno a singoli inizializzatori nell'elenco e contribuirebbero a chiarire l'esempio.

Quando si inizializza una variabile di aggregazione, è necessario prestare attenzione a usare correttamente parentesi graffe ed elenchi di inizializzatori. L'esempio seguente illustra in modo più dettagliato l'interpretazione delle parentesi graffe del compilatore:

typedef struct
{
    int n1, n2, n3;
} triplet;

triplet nlist[2][3] =
{
    { {  1, 2, 3 }, {  4, 5, 6 }, {  7, 8, 9 } },  /* Row 1 */
    { { 10,11,12 }, { 13,14,15 }, { 16,17,18 } }   /* Row 2 */
};

In questo esempio, nlist viene dichiarato come matrice di strutture da 2 a 3, ognuna con tre membri. La riga 1 dell'inizializzazione assegna valori alla prima riga di nlist, come indicato di seguito:

  1. La prima parentesi graffa sinistra nella riga 1 segnala al compilatore che l'inizializzazione del primo membro aggregato di nlist (ovvero , nlist[0]) inizia.

  2. La seconda parentesi graffa sinistra indica che l'inizializzazione del primo membro aggregato di nlist[0] (ovvero la struttura in nlist[0][0]) inizia.

  3. La prima parentesi graffa destra termina l'inizializzazione della struttura nlist[0][0]; la parentesi graffa successiva inizia l'inizializzazione di nlist[0][1].

  4. Il processo continua fino alla fine della riga, dove la parentesi graffa di chiusura termina l'inizializzazione di nlist[0].

La riga 2 assegna valori alla seconda riga di nlist in modo simile. Sono necessari i set esterni di parentesi graffe che racchiudono gli inizializzatori nelle righe 1 e 2. La costruzione seguente, che omette le parentesi graffe esterne, provocherebbe un errore:

triplet nlist[2][3] =  /* THIS CAUSES AN ERROR */
{
     {  1, 2, 3 },{  4, 5, 6 },{  7, 8, 9 },   /* Line 1 */
     { 10,11,12 },{ 13,14,15 },{ 16,17,18 }    /* Line 2 */
};

In questa costruzione, la prima parentesi graffa sinistra sulla riga 1 avvia l'inizializzazione di nlist[0], che è una matrice di tre strutture. I valori 1, 2 e 3 vengono assegnati ai tre membri della prima struttura. Quando viene rilevata la parentesi graffa destra successiva (dopo il valore 3), l'inizializzazione di nlist[0] viene completata e le due strutture rimanenti nella matrice a tre strutture vengono inizializzate automaticamente su 0. Analogamente, { 4,5,6 } inizializza la prima struttura nella seconda riga di nlist. Le due strutture rimanenti di nlist[1] sono impostate su 0. Quando il compilatore rileva l'elenco di inizializzatori successivo ( { 7,8,9 } ), tenta di inizializzare nlist[2]. Poiché nlist ha solo due righe, questo tentativo causa un errore.

In questo esempio successivo, i tre int membri di x vengono inizializzati rispettivamente su 1, 2 e 3.

struct list
{
    int i, j, k;
    float m[2][3];
} x = {
        1,
        2,
        3,
       {4.0, 4.0, 4.0}
      };

list Nella struttura, i tre elementi della prima riga di m vengono inizializzati su 4.0. Gli elementi della riga rimanente di m vengono inizializzati su 0,0 per impostazione predefinita.

union
{
    char x[2][3];
    int i, j, k;
} y = { {
            {'1'},
            {'4'}
        }
      };

La variabile yunion , in questo esempio, viene inizializzata. Il primo elemento dell'unione è una matrice, quindi l'inizializzatore è un inizializzatore di aggregazione. L'elenco {'1'} di inizializzatori assegna valori alla prima riga della matrice. Poiché nell'elenco viene visualizzato un solo valore, l'elemento nella prima colonna viene inizializzato nel carattere 1e i due elementi rimanenti nella riga vengono inizializzati sul valore 0 per impostazione predefinita. Analogamente, il primo elemento della seconda riga di x viene inizializzato nel carattere 4e i due elementi rimanenti nella riga vengono inizializzati sul valore 0.

Vedere anche

Inizializzazione