Udostępnij za pośrednictwem


Inicjowanie typów agregacji

Typ "agregacji" to typ struktury, związku lub tablicy.Jeśli typ agregacji zawiera elementy członkowskie typów agregacji, zasady inicjowania są stosowane rekursywnie.

Składnia

  • Inicjator:
    { lista-inicjatora } /* dla inicjowania agregacji */

    { lista-inicjatora , }

  • lista-inicjatora:
    Inicjator

    lista-inicjatora , inicjator

Lista-inicjatora jest listą 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 mogą być zagnieżdżane.Forma ta jest przydatna do inicjowania członków agregacji typu agregacji, jak przedstawiono w przykładach w niniejszej sekcji.Jednak, jeśli inicjator automatycznego identyfikatora jest pojedynczym wyrażeniem, to nie musi być wyrażenie stałe; musi mieć tylko odpowiedni typ przypisania do identyfikatora.

Dla każdej listy inicjatora, wartości stałych wyrażeń są przypisane, w kolejności, do odpowiadających elementów członkowskich zmiennej agregacji.

Jeśli lista-inicjatora ma mniej wartości niż typ agregacji, pozostałe elementy członkowskie lub elementy typu agregacji są inicjowane na wartość 0.Początkowa wartość automatycznego identyfikatora, który nie został jawnie zainicjowany jest niezdefiniowana.Jeśli lista-inicjatora ma więcej wartości niż typ agregacji, występuje błąd.Reguły te stosuje się do każdej osadzonej listy inicjatora, jak również do agregacji jako całości.

Inicjator struktury jest wyrażeniem tego samego typu albo listą inicjatorów dla elementów członkowskich ujętych w nawiasy klamrowe ({ }).Nienazwane członkowskie pola bitowe nie są inicjowane.

Podczas inicjowania związku, lista-inicjatora musi być pojedynczym wyrażeniem stałym.Wartość stałego wyrażenia jest przypisana do pierwszego elementu członkowskiego związku.

Jeśli tablica ma nieznany rozmiar, liczba inicjatorów określa rozmiar tablicy i jej typ staje się kompletny.Nie ma sposobu na określenie powtarzania inicjatora w C lub inicjowanie elementu w środku tablicy bez dostarczania także wszystkich poprzednich wartości.Jeśli potrzebujesz tej operacji w programie, należy napisać procedurę w języku asemblera.

Należy zauważyć, że liczba inicjatorów może ustawić rozmiar tablicy:

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

Jeśli jednak użytkownik określi rozmiar i poda niewłaściwą liczbę inicjatorów, kompilator wygeneruje błąd.

Specyficzne dla firmy Microsoft

Maksymalny rozmiar tablicy jest zdefiniowany przez size_t.size_t zdefiniowany w pliku nagłówkowym STDDEF.H jest wartością typu unsigned int i ma zakres od 0x00000000 do 0x7CFFFFFF.

KONIEC informacji specyficznych dla firmy Microsoft

Przykłady

W przykładzie tym pokazano inicjatory dla tablicy.

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

Instrukcja ta deklaruje P jako tablicę cztery na trzy i inicjuje elementy jego pierwszego wiersza na 1, elementy jego drugiego wiersza na 2 i tak dalej aż do czwartego wiersza.Należy zauważyć, że lista inicjatora dla trzeciego i czwartego wiersza zawiera przecinki po ostatnim wyrażeniu stałym.Po ostatniej liście inicjatora ({4, 4, 4,},) również występuje przecinek.Te dodatkowe przecinki są dozwolone, ale nie są wymagane; wymagane są tylko przecinki, które oddzielają od siebie wyrażenia stałe i te, które oddzielają jedną listę inicjatora od drugiej.

Jeśli element członkowski agregacji nie zawiera osadzonej listy inicjatora, wartości są po prostu przypisywane, w kolejności, do każdego członka podagregacji.W związku z tym, inicjowanie w poprzednim przykładzie jest równoważne z następującymi czynnościami:

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

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

Podczas inicjowania zmiennej agregacji, należy zachować ostrożność, aby poprawnie użyć nawiasów klamrowych i list inicjatorów.W poniższym przykładzie zilustrowano interpretację nawiasów klamrowych przez kompilator bardziej szczegółowo:

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 zadeklarowana jako tablica struktur 2 na 3, każda struktura ma trzy elementy członkowskie.Wiersz 1 inicjowania przypisuje wartości do pierwszego wiersza nlist, w następujący sposób:

  1. Pierwszy otwierający nawias klamrowy w wierszu 1 sygnalizuje kompilatorowi, że rozpoczęła się inicjacja pierwszego elementu członkowskiego agregacji nlist (to znaczy, nlist[0]).

  2. Drugi otwierający nawias klamrowy wskazuje, że rozpoczęła się inicjacja pierwszego elementu członkowskiego agregacji nlist[0] (to znaczy struktury w nlist[0][0]).

  3. Inicjację struktury nlist[0][0] kończy pierwszy zamykający nawias klamrowy; kolejny otwierający nawias klamrowy rozpoczyna inicjowanie nlist[0][1].

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

Wiersz 2 przypisuje wartości do drugiego wiersza nlist w podobny sposób.Należy zauważyć, że 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, powoduje 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 otwierający nawias klamrowy w wierszu 1 rozpoczyna inicjowanie nlist[0], który jest tablicą trzech struktur.Wartości 1, 2 i 3 są przypisane do trzech elementów członkowskich pierwszej struktury.Kiedy zostanie napotkany następny zamykający nawias klamrowy (po wartości 3), inicjacja nlist[0] została ukończona, a dwie pozostałe struktury w tablicy trzech struktur są automatycznie inicjowane na wartość 0.Podobnie, { 4,5,6 } inicjuje pierwszą strukturę w drugim wierszu nlist.Pozostałe dwie struktury nlist[1] są ustawiane na 0.Kiedy kompilator napotyka następną listę inicjatora ( { 7,8,9 } ), próbuje inicjować nlist[2].Ponieważ nlist ma tylko dwa wiersze, próba ta powoduje błąd.

W następnym przykładzie, trzy elementy członkowskie x typu int są inicjowane, odpowiednio, na wartość 1, 2 i 3.

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

W strukturze list powyżej, trzy elementy w pierwszym wierszu m są inicjowane na 4.0; elementy pozostałego wiersza m są inicjowane domyślnie na 0.0.

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

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

Zobacz też

Koncepcje

Inicjalizacja