Ist es möglich, einen C-Zeiger auf NULL zu initialisieren?
TL; DR Ja, sehr.
Die tatsächliche Behauptung auf dem Leitfaden lautet wie folgt
Wenn Sie jedoch nur die einzelne Anfangszuweisung verwenden, int *my_int_ptr = 2;
versucht das Programm, den Inhalt des Speicherorts, auf den durch gezeigt wird, my_int_ptr
mit dem Wert 2 zu füllen . Da er my_int_ptr
mit Müll gefüllt ist, kann es sich um eine beliebige Adresse handeln. [...]
Nun, sie sind falsch, du hast recht.
Für die Aussage ( ignoriert vorerst die Tatsache, dass der Zeiger auf die Ganzzahlkonvertierung ein implementierungsdefiniertes Verhalten ist )
int * my_int_ptr = 2;
my_int_ptr
ist eine Variable (vom Typ Zeiger auf int
), sie hat eine eigene Adresse (Typ: Adresse des Zeigers auf Ganzzahl), Sie speichern einen Wert von 2
in dieser Adresse.
Da my_int_ptr
es sich nun um einen Zeigertyp handelt, können wir sagen, dass er auf den Wert von "Typ" an der Speicherstelle zeigt, auf die gezeigt wird die der Wert zeigt, inmy_int_ptr
. Also, Sie sind im Wesentlichen den Wert Zuordnung von der Zeigervariable, nicht der Wert des Speicherplatzes , auf den durch den Zeiger.
Also zum Abschluss
char *x=NULL;
initialisiert die Zeigervariable x
aufNULL
, nicht auf den Wert an der Speicheradresse, auf die der Zeiger zeigt .
Dies ist das gleiche wie
char *x;
x = NULL;
Erweiterung:
Nun, streng konform, eine Aussage wie
int * my_int_ptr = 2;
ist illegal, da es sich um eine Verletzung von Einschränkungen handelt. Deutlich sein,
my_int_ptr
ist eine Zeigervariable vom Typ int *
- Eine Ganzzahlkonstante
2
hat int
per Definition einen Typ .
und da es sich nicht um "kompatible" Typen handelt, ist diese Initialisierung ungültig, da sie gegen die Regeln der einfachen Zuweisung verstößt, die in Kapitel 6.5.16.1 / P1, beschrieben in Lundins Antwort, erwähnt werden .
Falls jemand interessiert ist, wie die Initialisierung mit einfachen Zuweisungsbeschränkungen verbunden ist, zitieren Sie C11
, Kapitel §6.7.9, P11
Der Initialisierer für einen Skalar muss ein einzelner Ausdruck sein, der optional in geschweiften Klammern eingeschlossen ist. Der Anfangswert des Objekts ist der des Ausdrucks (nach der Konvertierung). Es gelten die gleichen Typbeschränkungen und Konvertierungen wie für die einfache Zuweisung, wobei der Typ des Skalars als nicht qualifizierte Version seines deklarierten Typs angesehen wird.
int *x = whatever;
tut und dem, wasint *x; *x = whatever;
tut.int *x = whatever;
verhält sich eigentlich soint *x; x = whatever;
, nicht*x = whatever;
.