2012-08-02 8 views
12

In C können Sie teilweise eine Struktur oder ein Array initialisieren, mit dem Ergebnis, dass die Member/Elemente, die nicht im Initialisierer erwähnt werden, Null initialisiert werden. (C99 Abschnitt 6.7.8.19). Zum Beispiel: -Zählt ein String-Literal als Teilinitialisierer und Nullinitialisierung?

int a[4] = {1, 2}; 
// a[0] == 1 
// a[1] == 2 
// a[2] == 0 
// a[3] == 0 

Sie können auch als „eine Anordnung von Zeichentyp“ mit einem Stringliteral (C99 Abschnitt 6.7.8.14) initialisieren, und „... aufeinanderfolgende Zeichen, die Elemente des Arrays initialisieren“. Zum Beispiel: -

char b[4] = "abc"; 
// b[0] == 'a' 
// b[1] == 'b' 
// b[2] == 'c' 
// b[3] == '\0' 

Alles ziemlich einfach. Was passiert aber, wenn Sie explizit die Länge des Arrays angeben, aber ein Literal verwenden, das zu kurz ist, um das Array zu füllen? Sind die verbleibenden Zeichen null-initialisiert oder haben sie undefinierte Werte?

char c[4] = "a"; 
// c[0] == 'a' 
// c[1] == '\0' 
// c[2] == ? 
// c[3] == ? 

es als Teil initializer Behandlung würde Sinn machen, sei es char c[4] = "a" genau wie char c[4] = {'a'} macht verhalten, und es würde den nützlichen Nebeneffekt hat so dass Sie einen Zeichen-Array mit char d[N] = "" prägnanten ganzen Null initialisieren, aber es ist mir gar nicht klar, dass das die Spezifikation erfordert.

+2

Woot. Ich habe eine Frage zu SO gefunden, die Sinn macht. Dan, du hast meinen Tag gemacht. –

Antwort

11
char c[4] = "a"; 

Alle übrigen Elemente des Arrays werden 0 eingestellt werden. Das heißt, nicht nur c[1], sondern auch c[2] und c[3].

Beachten Sie, dass dies nicht von der Speicherdauer c, i abhängt. e., selbst wenn c automatische Speicherdauer hat, werden die verbleibenden Elemente auf 0 gesetzt.

Von dem C Standard (Hervorhebung von mir):

(C99, 6.7.8p21) „Wenn es weniger Initialisierer in einer geschweiften Klammer stehende Liste als es Elemente oder Elemente eines Aggregats sind, oder weniger Zeichen in einer Zeichenkette literal verwendet ein Array von bekannter Größe zu initialisieren, als es Elemente in der Anordnung, wobei der Rest des Aggregats wird implizit die gleiche wie Objekte initialisiert werden, die statische Lagerdauer aufweisen. "

+0

Aha, da. Das ist die Klarstellung, die ich vermisste. –

5

Von der C99-Standard (wie bereits von ouah angegeben):

Wenn weniger Initialisierer in einer geschweiften Klammern stehenden Liste sind als es Elemente oder Elemente eines Aggregats sind, oder weniger Zeichen in einem String-Literal verwendet initialisiert ein Array bekannter Größe Größe als es Elemente im Array sind, der Rest des Aggregats soll implizit gleich wie Objekte mit statischer Speicherdauer initialisiert werden.

und:

Wenn ein Objekt, das die automatische Speicherdauer hat nicht explizit initialisiert, sein Wert ist unbestimmt.Wenn ein Objekt, die statische Speicherdauer hat, ist nicht explizit initialisiert, dann gilt:

  • wenn es Zeigertyp hat, um es zu einem Nullzeiger initialisiert wird;
  • Wenn es einen arithmetischen Typ hat, wird es initialisiert auf (positiv oder vorzeichenlos) Null;
  • Wenn es ein Aggregat ist, wird jedes Mitglied (rekursiv) gemäß diesen Regeln initialisiert;
  • Wenn es sich um eine Union handelt, wird das zuerst benannte Element (rekursiv) gemäß diesen -Regeln initialisiert.

Und char ist eine arithmetische Art, so dass die restlichen Elemente des Arrays werden auf Null initialisiert werden.

3

Absolut überall in C Sprache folgt die alles oder nichts Ansatz zur Initialisierung. Wenn Sie ein Aggregat nur teilweise initialisieren, wird der Rest dieses Aggregats auf Null initialisiert.

Man kann sagen, dass dies mit Strings übermäßig und nicht optimal ist, aber so funktioniert es in C.

Verwandte Themen