Der folgende Code ( von hier übernommen ):
int* ptr = int();
Kompiliert in Visual C ++ und initialisiert den Zeiger mit einem Wert.
Wie ist das möglich? Ich meine, int()
ergibt ein Objekt vom Typ int
und ich kann int
einem Zeiger kein Objekt zuweisen .
Wie ist der obige Code nicht illegal?
c++
visual-c++
pointers
initialization
built-in-types
scharfer Zahn
quelle
quelle
int()
ergibt sich der Wert konstruierter Wert vonint
(was meiner Meinung nach eine von C ++ 03 spezifizierte Sache ist) und der Standardwert vonint
ist0
. Dies entsprichtint *ptr = 0;
NULL
dass ein Wert ungleich Null sein könnte. Ich sagte, es könnte eine beliebige ganzzahlige Konstante mit Nullwert sein (einschließlichint()
).Antworten:
int()
ist ein konstanter Ausdruck mit dem Wert 0, daher ist dies eine gültige Methode zum Erzeugen einer Nullzeigerkonstante. Letztendlich ist es nur eine etwas andere Art zu sagenint *ptr = NULL;
quelle
nullptr
, die Sie anstelle von0
oderNULL
in neuem Code verwenden können.0
eine Nullzeigerkonstante oder die Zahl 0 bedeuten könnte, währendnullptr
offensichtlich eine Nullzeigerkonstante ist. Darüber hinaus gibt es, wie Jamin sagte, auch "zusätzliche Überprüfungen zur Kompilierungszeit". Versuchen Sie zu überlegen, bevor Sie tippen.weil
int()
Ausbeuten0
, die austauschbar sind mitNULL
.NULL
selbst ist definiert als0
, im Gegensatz zu Cs,NULL
die ist(void *) 0
.Beachten Sie, dass dies ein Fehler wäre:
und das wird noch funktionieren:
0
ist ein spezieller konstanter Wert und kann daher als Zeigerwert behandelt werden. Konstante Ausdrücke, die ergeben0
, wie z. B.1 - 1
Nullzeigerkonstanten.quelle
(void *)0
. Es ist einfach eine Implementierung, die als "ganzzahliger konstanter Ausdruck mit dem Wert 0 oder ein solcher Ausdruck vom Typ void *" definiert ist.NULL
als(void*)0
; es war immer0
(oder vielleicht0L
). (Aber als C90(void*)0
in C legalisiert wurde, verwendete ich bereits C ++.)#if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)
Die aktuelle Version von gcc in Ubuntu ist 4.5, in unserem System ist 4.0.0
ist ein spezielles Literal" - nur weil es ein konstanter Ausdruck ist und den speziellen Wert 0 hat.(1-1)
ist ebenso speziell, es ist auch eine Nullzeigerkonstante und so ist es auchint()
. Die Tatsache0
, ein Literal zu sein, ist ausreichend, aber keine notwendige Bedingung, um ein konstanter Ausdruck zu sein. Etwas wiestrlen("")
, obwohl es auch den speziellen Wert hat0
, ist kein konstanter Ausdruck und daher keine Nullzeigerkonstante.0
, nicht um das0
Literal.Der Ausdruck
int()
ergibt eine konstante standardmäßig initialisierte Ganzzahl, die der Wert 0 ist. Dieser Wert ist etwas Besonderes: Er wird verwendet, um einen Zeiger auf den NULL-Status zu initialisieren.quelle
int f() { return 0; }
gibt der Ausdruckf()
den Wert 0 aus, kann jedoch nicht zum Initialisieren eines Zeigers verwendet werden.Ab n3290 (C ++ 03 verwendet ähnlichen Text), 4.10 Zeigerkonvertierungen [conv.ptr] Absatz 1 (der Schwerpunkt liegt bei mir):
int()
ist ein solcher integraler konstanter Ausdruck prvalue vom Integer-Typ, der Null ergibt (das ist ein Schluck!) und somit zum Initialisieren eines Zeigertyps verwendet werden kann. Wie Sie sehen können,0
ist dies nicht der einzige integrale Ausdruck, der in einem speziellen Gehäuse steht.quelle
Nun, int ist kein Objekt.
Ich glaube, was hier passiert, ist, dass Sie dem int * sagen, dass er auf eine durch int () bestimmte Speicheradresse verweisen soll.
Wenn also int () 0 erstellt, zeigt int * auf die Speicheradresse 0
quelle
int()
ganz sicher ist ein Objekt.int()
. Definierenint i;
, dann keine Frage,i
ist ein Objekt.int
es sich um einen Typ handelt, nicht um ein Objekt. Ob sichint()
ein Objekt oder nur ein Wert ergibt, hat keinen Einfluss auf irgendetwas, was jemand anders gesagt hat.