2010-10-07 13 views

Antwort

9

Alle nicht angegebenen Felder werden auf Null initialisiert. Also hier haben Sie eine Reihe von Strukturen. Sie initialisieren das erste Element des Arrays mit einem Strukturinitialisierer, der das erste Element der Struktur auf Null initialisiert. Der Rest der ersten Struktur und der Rest der Array-Elemente sind alle ebenfalls Null. Es ist ein schönes Idiom.

+0

Nur um sicherzustellen, dass ich das richtig verstehe. Da alle nicht angegebenen Felder auf Null initialisiert werden, hat das '= {{0}}' im Wesentlichen keine Auswirkung? –

+2

Es hat einen Effekt. Es initialisiert das erste Element spezifisch auf Null und initialisiert den Rest der Elemente implizit auf Null. Wenn Sie {{0}} auslassen, erhalten Sie einen zufälligen Müll, wenn Sie ihn innerhalb einer Funktion (auf dem Stapel) deklariert haben. (Wenn Sie dies als global deklarieren und das {{0}} weglassen, wird es auch aus anderen Gründen auf Null initialisiert.) – xscott

3

Es sind nicht die geschachtelten geschweiften Klammern, die initialisiert werden. Die äußeren Verstrebungen sind die anzeigt, dass ein Array initialisiert wird:

struct mystruct s[10] = {   }; 

Da es sich um eine Anordnung von Strukturen, die jeweils Strukturen können mit weiteren Klammern initialisiert werden:

struct mystruct { int x, y, z}; 

struct mystruct s[10] = { {0, 1, 2}, // <-- initializes s[0].x, s[0].y, s[0].z 
          {1, 2, 3}, // <-- initializes s[1].x, s[1].y, s[1].z 
          {2, 3, 4} // <-- initializes s[2].x, s[2].y, s[2].z 
}; 

Beachten Sie, dass nur die ersten drei Elemente sind initialisiert. Laut C-Standard müssen die restlichen 7 Elemente auf 0 initialisiert werden. Das passiert auch mit Ihrem Code. Wie xscott in seiner Antwort erwähnte, wird alles, was in der Initialisierungsliste weggelassen wird, auf 0 initialisiert.

3

Wie gezeigt?

Grundsätzlich sollten Sie jeden zusammengesetzten Typ - Array, Struktur usw. - in seine eigene Ebene von Klammern einschließen.

Bedenken Sie:

struct mystruct 
{ 
    int i; 
    double d; 
    char s[10]; 
    int a[5]; 
} s[10] = 
{ 
     { 0, 0.0, "abc", { 1, 2, 3, 4, 5 } }, 
     { 1, 1.0, "def", { 2, 3   } }, // Partially initialized array 
     { 2, 2.0, { 'x', 'y', 'z' }, { 0 } }, // Strings are a shorthand 
[9] = { 9, 99, 0,  { 9, 8, 7, 6, 5 } }, // C99 - initialize row 9 
}; 

Sie können aber auch Klammern weglassen, wenn Sie (schlecht, archaische Praxis) bestehen:

struct mystruct t[3] = 
{ // You cannot avoid using these outside braces 
    0, 0.00, "abc", 1, 2, 3, 4, 5, // Omitted braces 
    1, 1.11, "bcd", 2, 3, 4, 5, 4, 
    2, 2.34,      // Omitted values 
}; 

Alle weggelassen initializers werden als Nullen behandelt.

+0

Der Vorteil der Verwendung der geschweiften Klammern ist, dass Sie die Initialisierung von Teilen weglassen können von einigen Mitgliedern (die dann implizit auf Null initialisiert werden), während die späteren Mitglieder weiter initialisiert werden. Die Verwendung von '{'x', 'y', 'z'},' ist ein Beispiel dafür. –

0

Es ist nützlich zu beachten, dass, während die inneren Klammern optional sind, der Compiler überprüft, um sicherzustellen, dass öffnende geschweifte Klammern nur dort angezeigt werden, wo sie sollten, und dass kein verschachteltes Element zu viele Initialisierer hat. Außerdem kann man einige Felder einer Struktur weglassen und der Compiler automatisch auf Null setzen, selbst wenn die Struktur nicht am Ende des Arrays ist. Beachten Sie, dass sich Implementierungen in ihrer Effizienz bei der Handhabung unterscheiden. Einige teilen den Initialisierungsdatensatz in kleine Teile auf, während andere einfach viele Nullen in den Code einfügen. wenn jede Struktur Zum Beispiel sah aus wie:

 
typedef struct { 
    char name[8]; 
    char more_stuff[1016]; 
} THINGIE; 
THINGIE my_array = {{"Fred"},{"George"},{"Mark"}}; 

einige Compiler 3K im Wert von const Daten erzeugen würden, während andere drei relativ kleine ‚const-init‘ Aufzeichnungen erzeugen würde.

+0

Der Compiler kann nicht überprüfen, dass öffnende geschweifte Klammern nur dort erscheinen, wo sie "sollen", weil sie überall gültig sind. Auch das ist gültig C: 'int x = {0};'. –

+0

Sie haben das Schlüsselwort "typedef" vor Ihrer Strukturdefinition weggelassen. In Ihrem obigen Code ist THINGIE eine Variable, kein Typ. – xscott

+0

@R: True; Wo Sie Validierung erhalten, ist, wenn Sie versuchen, zwei oder mehr Dinge in eine geschweifte Klammer zu legen. Ich bin mir ziemlich sicher "int x = {0,1};" ist nicht legal. – supercat

Verwandte Themen