Initialization
Eine Deklaration eines Objekts kann seinen Anfangswert durch den als Initialisierung bekannten Prozess bereitstellen.
Für jeden Deklarator kann der Initialisierer, falls nicht weggelassen, einer der folgenden sein:
=
Ausdruck
|
(1) | ||||||||
=
{
Initialisiererliste
}
|
(2) | ||||||||
=
{
}
|
(3) | (seit C23) | |||||||
wobei initializer-list eine nicht-leere, kommagetrennte Liste von initializer s ist (mit optionalem abschließendem Komma), wobei jeder Initialisierer eine von drei möglichen Formen hat:
| Ausdruck | (1) | ||||||||
{
Initialisiererliste
}
|
(2) | ||||||||
{
}
|
(3) | (seit C23) | |||||||
Designatorliste
=
Initialisierer
|
(4) | (seit C99) | |||||||
|
wobei
designator-list
eine Liste entweder von Array-Designatoren der Form
Hinweis: Neben Initialisierern kann eine in geschweifte Klammern eingeschlossene initializer-list in compound literals erscheinen, welche Ausdrücke der folgenden Form sind:
|
(seit C99) | ||||||||||||||||||||||||||||||||||||
Inhaltsverzeichnis |
Erklärung
Der Initialisierer gibt den Anfangswert an, der in einem Objekt gespeichert wird.
Explizite Initialisierung
Wenn ein Initialisierer vorhanden ist, siehe
- Skalare Initialisierung für die Initialisierung von Skalartypen
- Array-Initialisierung für die Initialisierung von Arraytypen
- Struct-Initialisierung für die Initialisierung von Struct- und Union-Typen.
Implizite Initialisierung
Wenn kein Initialisierer angegeben ist:
- Objekte mit automatischer Speicherdauer werden auf unbestimmte Werte initialisiert (die Trap-Darstellungen sein können)
- Objekte mit statischer und thread-lokaler Speicherdauer werden leer-initialisiert
Leere Initialisierung
|
Ein Objekt wird leer-initialisiert, wenn es explizit vom Initialisierer = { } initialisiert wird. |
(since C23) |
In einigen Fällen wird ein Objekt leer-initialisiert, wenn es nicht explizit initialisiert wird, das heißt:
- Zeiger werden auf Nullzeigerwerte ihres Typs initialisiert
- Objekte von Ganzzahltypen werden auf vorzeichenlose Null initialisiert
- Objekte von Gleitkommatypen werden auf positive Null initialisiert
- Alle Elemente von Arrays, alle Mitglieder von Structs und die ersten Mitglieder von Unions werden rekursiv leer-initialisiert, zusätzlich werden alle Padding-Bits auf Null initialisiert
- (auf Plattformen, bei denen Nullzeigerwerte und Gleitkomma-Nullen All-Bit-Null-Darstellungen haben, wird diese Form der Initialisierung für Statics normalerweise implementiert, indem sie im .bss-Abschnitt des Programmabbilds zugewiesen werden)
Hinweise
Bei der Initialisierung eines Objekts mit statischer oder thread-lokaler Speicherdauer muss jeder Ausdruck im Initialisierer ein konstanter Ausdruck oder ein Zeichenkettenliteral sein.
Initializer können nicht in Deklarationen von Objekten unvollständigen Typs, VLAs und Blockbereichs-Objekten mit Linkage verwendet werden.
Die Anfangswerte von Funktionsparametern werden so festgelegt, als ob sie durch Zuweisung von den Argumenten eines Funktionsaufrufs stammen würden, und nicht durch Initialisierung.
Wenn ein unbestimmter Wert als Argument für einen Standardbibliotheksaufruf verwendet wird, ist das Verhalten undefiniert. Andernfalls ist das Ergebnis eines jeden Ausdrucks, der unbestimmte Werte enthält, ein unbestimmter Wert (z.B. int n ; , n könnte sich nicht als gleich mit sich selbst vergleichen und könnte bei nachfolgenden Lesevorgängen seinen Wert zu ändern scheinen)
|
Es gibt keine spezielle Konstruktion in C, die der Wertinitialisierung in C++ entspricht; jedoch kann = { 0 } (oder ( T ) { 0 } bei Compound Literals) (seit C99) stattdessen verwendet werden, da der C-Standard leere Strukturen, leere Unions oder Arrays mit Länge Null nicht erlaubt. |
(bis C23) |
|
Der leere Initialisierer = { } (oder ( T ) { } bei Compound Literals) kann verwendet werden, um dieselbe Semantik wie bei der Wertinitialisierung in C++ zu erreichen. |
(seit C23) |
Beispiel
#include <stdlib.h> int a[2]; // initialisiert a mit {0, 0} int main(void) { int i; // initialisiert i mit einem unbestimmten Wert static int j; // initialisiert j mit 0 int k = 1; // initialisiert k mit 1 // initialisiert int x[3] mit 1,3,5 // initialisiert int* p mit &x[0] int x[] = { 1, 3, 5 }, *p = x; // initialisiert w (ein Array von zwei structs) mit // { { {1,0,0}, 0}, { {2,0,0}, 0} } struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2}; // Funktionsaufrufausdruck kann für eine lokale Variable verwendet werden char* ptr = malloc(10); free(ptr); // Fehler: Objekte mit statischer Speicherdauer erfordern konstante Initialisierer // static char* ptr = malloc(10); // Fehler: VLA kann nicht initialisiert werden // int vla[n] = {0}; }
Referenzen
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.7.9 Initialisierung (S: 100-105)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.7.9 Initialization (S. 139-144)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.7.8 Initialisierung (S: 125-130)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 6.5.7 Initialisierung
Siehe auch
|
C++ Dokumentation
für
Initialization
|