Udostępnij za pośrednictwem


Inicjowanie typów agregacji

Typ agregacji jest strukturą, unią lub typem tablicy. Jeśli typ agregacji zawiera elementy członkowskie typów agregacji, reguły inicjowania są stosowane rekursywnie.

Składnia

initializer:
{ initializer-list } /* W przypadku inicjowania agregacji */
{ initializer-list , }

initializer-list:
initializer
initializer-list , initializer

Jest initializer-list to lista inicjatorów rozdzielonych przecinkami. Każdy inicjator na liście jest wyrażeniem stałym lub listą inicjatora. W związku z tym listy inicjatorów można zagnieżdżać. Ten formularz jest przydatny do inicjowania agregujących elementów członkowskich typu agregującego, jak pokazano w przykładach w tej sekcji. Jeśli jednak inicjatorem automatycznego identyfikatora jest pojedyncze wyrażenie, nie musi być wyrażeniem stałym; musi mieć tylko odpowiedni typ przypisania do identyfikatora.

Dla każdej listy inicjatorów wartości wyrażeń stałych są przypisywane w kolejności do odpowiednich elementów członkowskich zmiennej agregującej.

Jeśli initializer-list ma mniej wartości niż typ agregujący, pozostałe elementy członkowskie lub elementy typu agregacji są inicjowane do 0. Początkowa wartość identyfikatora automatycznego, która nie została jawnie zainicjowana, jest niezdefiniowana. Jeśli initializer-list ma więcej wartości niż typ agregacji, wynik błędu. Te reguły mają zastosowanie do każdej osadzonej listy inicjatorów oraz do agregacji jako całości.

Inicjator struktury jest wyrażeniem tego samego typu lub listą inicjatorów elementów członkowskich ujętymi w nawiasy klamrowe ({ }). Nienazwane elementy członkowskie pól bitowych nie są inicjowane.

Gdy unia jest inicjowana, initializer-list musi być pojedynczym wyrażeniem stałym. Wartość wyrażenia stałego jest przypisywana do pierwszego elementu członkowskiego unii.

Jeśli tablica ma nieznany rozmiar, liczba inicjatorów określa rozmiar tablicy, a jego typ staje się kompletny. Nie ma możliwości określenia powtórzenia inicjatora w języku C lub zainicjowania elementu w środku tablicy bez podawania wszystkich powyższych wartości. Jeśli potrzebujesz tej operacji w programie, napisz procedurę w języku zestawu.

Liczba inicjatorów może ustawić rozmiar tablicy:

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

Jeśli jednak określisz rozmiar i nadasz niewłaściwą liczbę inicjatorów, kompilator generuje błąd.

Specyficzne dla firmy Microsoft

Maksymalny rozmiar tablicy jest definiowany przez size_telement .

END Microsoft Specific

Przykłady

W tym przykładzie przedstawiono inicjatory dla tablicy.

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

Ta instrukcja deklaruje P jako tablicę cztery po trzech i inicjuje elementy pierwszego wiersza do 1, elementy drugiego wiersza do 2 itd. w czwartym wierszu. Lista inicjatora dla trzeciego i czwartego wiersza zawiera przecinki po ostatnim wyrażeniu stałej. Po ostatniej liście inicjatora ({4, 4, 4,},) następuje również przecinek. Te dodatkowe przecinki są dozwolone, ale nie są wymagane. Wymagane są tylko przecinki oddzielające wyrażenia stałe od siebie i przecinki oddzielające jedną listę inicjatorów od innej.

Jeśli element członkowski agregacji nie ma osadzonej listy inicjatorów, wartości są przypisywane do każdego elementu członkowskiego podagregu. Dlatego inicjowanie w poprzednim przykładzie jest równoważne następującemu przykładowi:

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

Nawiasy klamrowe mogą również pojawiać się wokół poszczególnych inicjatorów na liście i mogłyby pomóc w wyjaśnieniu przykładu.

Podczas inicjowania zmiennej agregującej należy zachować ostrożność, aby prawidłowo używać list nawiasów klamrowych i inicjatorów. Poniższy przykład ilustruje bardziej szczegółowo interpretację nawiasów klamrowych kompilatora:

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 */
};

W tym przykładzie nlist jest deklarowana jako tablica 2-by-3 struktur, z których każda ma trzy elementy członkowskie. Wiersz 1 inicjowania przypisuje wartości do pierwszego wiersza elementu nlistw następujący sposób:

  1. Pierwszy lewy nawias klamrowy w wierszu 1 sygnalizuje kompilator, który inicjuje pierwszy zagregowany element nlist członkowski (czyli nlist[0]) rozpoczyna się.

  2. Drugi lewy nawias klamrowy wskazuje, że inicjowanie pierwszego zagregowanego elementu nlist[0] członkowskiego (czyli struktura na ) nlist[0][0]zaczyna się.

  3. Pierwszy prawy nawias klamrowy kończy inicjowanie struktury nlist[0][0]; następny lewy nawias klamrowy nlist[0][1]rozpoczyna inicjowanie elementu .

  4. Proces jest kontynuowany do końca wiersza, gdzie zamykający prawy nawias klamrowy kończy inicjowanie nlist[0]elementu .

Wiersz 2 przypisuje wartości do drugiego nlist wiersza w podobny sposób. Zewnętrzne zestawy nawiasów klamrowych otaczające inicjatory w wierszach 1 i 2 są wymagane. Następująca konstrukcja, która pomija zewnętrzne nawiasy klamrowe, spowoduje błąd:

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 */
};

W tej konstrukcji pierwszy lewy nawias klamrowy w wierszu 1 rozpoczyna inicjację nlist[0], która jest tablicą trzech struktur. Wartości 1, 2 i 3 są przypisywane do trzech elementów członkowskich pierwszej struktury. Po napotkaniu następnego prawego nawiasu klamrowego (po wartości 3) inicjowanie nlist[0] elementu jest ukończone, a dwie pozostałe struktury w tablicy trójwymiarowej są automatycznie inicjowane do wartości 0. { 4,5,6 } Podobnie inicjuje pierwszą strukturę w drugim wierszu .nlist Pozostałe dwie struktury nlist[1] mają wartość 0. Gdy kompilator napotka kolejną listę inicjatorów ( { 7,8,9 } ), próbuje zainicjować nlist[2]element . Ponieważ nlist ma tylko dwa wiersze, ta próba powoduje błąd.

W następnym przykładzie trzy int elementy członkowskie x są inicjowane odpowiednio do 1, 2 i 3.

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

list W strukturze trzy elementy w pierwszym wierszu m są inicjowane do 4,0; elementy pozostałego m wiersza są domyślnie inicjowane do 0,0.

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

Zmienna yunii , w tym przykładzie, jest inicjowana. Pierwszym elementem unii jest tablica, więc inicjator jest inicjatorem agregacji. Lista {'1'} inicjatorów przypisuje wartości do pierwszego wiersza tablicy. Ponieważ na liście pojawia się tylko jedna wartość, element w pierwszej kolumnie jest inicjowany do znaku 1, a pozostałe dwa elementy w wierszu są domyślnie inicjowane do wartości 0. Podobnie pierwszy element drugiego wiersza x elementu jest inicjowany do znaku 4, a pozostałe dwa elementy w wierszu są inicjowane do wartości 0.

Zobacz też

Inicjowanie