Poniższy kod (pobrany stąd ):
int* ptr = int();
kompiluje w języku Visual C ++ i inicjalizuje wskaźnik.
Jak to możliwe? Mam na myśli, że int()
daje obiekt typu int
i nie mogę przypisać wskaźnika int
do wskaźnika.
Dlaczego powyższy kod nie jest nielegalny?
int()
zwraca skonstruowaną wartośćint
(która jest według mnie określoną rzeczą w C ++ 03), a wartość domyślnaint
to0
. Jest to odpowiednikint *ptr = 0;
NULL
może to być wartość niezerowa. Powiedziałem, że może to być dowolna stała całkowita o wartości zero (co obejmujeint()
).Odpowiedzi:
int()
jest wyrażeniem stałym o wartości 0, więc jest to poprawny sposób tworzenia stałej wskaźnika zerowego. Ostatecznie to tylko trochę inny sposób powiedzeniaint *ptr = NULL;
źródło
nullptr
, którego możesz użyć zamiast0
lubNULL
w nowym kodzie.0
może oznaczać stałą zerowego wskaźnika lub liczbę 0, podczas gdynullptr
jest oczywiste , że jest to stała pustego wskaźnika. Ponadto, jak powiedział Jamin, ma również „dodatkowe kontrole w czasie kompilacji”. Spróbuj pomyśleć, zanim zaczniesz pisać.Ponieważ
int()
plony0
, które są wymienne zNULL
.NULL
jest definiowany jako0
, w przeciwieństwie do C,NULL
które jest(void *) 0
.Zauważ, że byłby to błąd:
int* ptr = int(5);
i to nadal będzie działać:
int* ptr = int(0);
0
jest specjalną wartością stałą i jako taka może być traktowana jako wartość wskaźnika. Wyrażenia stałe, które dają0
, takie jak1 - 1
są również dozwolone jako stałe o wartości null.źródło
(void *)0
też. Jest to po prostu zdefiniowane w ramach implementacji „wyrażenie stałej liczby całkowitej z wartością 0 lub takie wyrażenie rzutowane na typ void *”.NULL
jako(void*)0
; tak było zawsze0
(a może0L
). (Ale potem, zanim C90 stało się(void*)0
legalne w C,#if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)
aktualna wersja gcc w Ubuntu to 4.5, w naszym systemie to 4.0.0
jest specjalnym literałem” - tylko dlatego, że jest wyrażeniem stałym i ma specjalną wartość 0.(1-1)
jest równie wyjątkowe, jest również stałą zerową wskaźnika i tak jestint()
. Fakt0
bycia dosłownym jest warunkiem wystarczającym, ale niekoniecznym, aby być wyrażeniem stałym. Coś takiegostrlen("")
, chociaż ma również specjalną wartość0
, nie jest wyrażeniem stałym, a zatem nie jest stałą zerowego wskaźnika.0
, a nie o0
dosłowność.Wyrażenie jest
int()
obliczane na stałą, zainicjowaną domyślnie liczbę całkowitą, która jest wartością 0. Ta wartość jest specjalna: jest używana do inicjowania wskaźnika do stanu NULL.źródło
int f() { return 0; }
wyrażenief()
zwraca wartość 0, ale nie można go użyć do zainicjowania wskaźnika.Od n3290 (C ++ 03 używa podobnego tekstu), 4.10 Konwersje wskaźnika [conv.ptr] akapit 1 (nacisk jest mój):
int()
jest takim całkowitym wyrażeniem stałym prvalue typu całkowitego, którego wynikiem jest zero (to jest kęs!), a zatem może być użyte do zainicjowania typu wskaźnika. Jak widać,0
nie jest to jedyne wyrażenie całkowite, które ma specjalną wielkość liter.źródło
Cóż, int nie jest przedmiotem.
Wierzę, że to, co się tutaj dzieje, to mówienie int *, aby wskazywał na jakiś adres pamięci określony przez int ()
więc jeśli int () utworzy 0, int * wskaże adres pamięci 0
źródło
int()
z całą pewnością jest przedmiotem.int()
. Zdefiniujint i;
, więc bez wątpienia,i
jest przedmiotem.int
jest typem, a nie obiektem. To, czyint()
daje obiekt, czy tylko wartość r, nie wpływa na nic, co ktoś powiedział gdzie indziej.