Valaki el tudná magyarázni, hogy a while(foo)
vs while(foo != NULL)
egyenértékűek? Is:
while(!foo)
vs while(foo == NULL)
Tudom ! nem, de nagyjából ennyit tudok.
Valaki el tudná magyarázni, hogy a while(foo)
vs while(foo != NULL)
egyenértékűek? Is:
while(!foo)
vs while(foo == NULL)
Tudom ! nem, de nagyjából ennyit tudok.
foo
egy mutató, akkor a while(foo)
definíciója while(foo != NULL)
. Ezért egyenértékűek. 30.03.2015 Feltételezve, hogy foo
mutató típusú, a while (foo)
és while (foo != NULL)
pontosan egyenértékűek. Mindkettő egyenértékű a while (foo != 0)
-vel is. (Véleményem szerint while (foo != NULL)
egyértelműbben fejezi ki a szándékot.)
Bármilyen feltételt igénylő kontextusban (if()
, while()
, néhány másik), a kifejezés igazként lesz kezelve, ha a feltétel nem egyenlő nullával, hamisként, ha egyenlő nulla.
A NULL
egy makró, amely megvalósítás által meghatározott null pointer konstansra bővül. A mutató értékének összehasonlítása a NULL
értékkel valódi értéket ad a null mutatóhoz, hamis értéket minden nem nulla mutatóhoz.
A 0
konstans egy nulla mutatókonstans [*]. (Ez nem jelenti azt, hogy a nullmutatónak a 0x00000000
vagy valami hasonló bitjei megegyeznek, bár gyakran előfordul; ez azt jelenti, hogy a forráskódban egy konstans 0
nullmutatót jelölhet.) elvárható, hogy a mutató értékének egy null mutató állandóval való összehasonlítása megmondja, hogy a mutató nullmutató-e vagy sem. A while (foo)
-ban a nullával való összehasonlítás implicit, de továbbra is teszteli, hogy a foo
nullmutató-e vagy sem.
Általánosabban, a while (foo)
összehasonlítja a foo
-ot 0
-el, ami egyenértékű a megfelelő típusú "nullával" való összehasonlítással. A while (foo)
mindig egyenértékű a while (foo != 0)
értékkel. Lebegőpontos érték esetén ez egyenértékű a while (foo != 0.0)
értékkel is. Karakterérték esetén ez egyenértékű a while (foo != '\0')
értékkel. És, amint láttuk, a mutató értéke while (foo != NULL)
-nek felel meg.
(C-ben az összehasonlító operátor mindig int
0
értéket ad, ha a feltétel hamis, 1
értéket, ha igaz -- de a nullától eltérő értéket igaznak tekinti a nullához való implicit egyenlőtlenség-összehasonlítás révén.)
[*] A null pointer konstans egy 0
értékű egész szám konstans kifejezés, vagy egy ilyen kifejezés void*
értékre öntve. A null mutatókonstans nem feltétlenül mutató típusú, de konvertálása mutató típusúvá nulla mutatóértéket eredményez. A mutató értékének 0
-hoz való összehasonlítása azt eredményezi, hogy a 0
implicit módon mutatótípussá alakul, így az összehasonlítás elvégezhető.
while(foo);
és
while(foo != NULL)
Egyenértékűek egyszerűen azért, mert a NULL egy makró, amely 0
-ra, (void*)0
-re vagy 0L
-re bővül, mivel C-ben a 0 hamisra (és minden nullától eltérő szám igazra) értékelődik.
while(foo); //while foo isn't 0
while(foo != NULL) //expands to while(foo != 0) < while foo isn't 0
foo
típusától függ. Tekintsük double foo
. A while(foo);
rendben van, de a while(foo != NULL)
nem fordítja le: érvénytelen operandusok binárissá !=
attól függően, hogy a NULL
hogyan van definiálva, ami nulla mutatókonstans kell, hogy legyen, és nem 0
, ahogy itt javasoltuk. 30.03.2015 foo
vagy egy mutató, vagy egy int
, de a NULL
garantáltan egyenlő 0-val, a gyakorlatban szerintem a legtöbb implementáció 0-t használ NULL
-ként. 30.03.2015 #define NULL ((void *)0)
értéket használja. MS Visual 2010, amikor a C
a #define NULL ((void *)0)
értéket használja. Talán arra gondol, hogyan van definiálva a NULL
egy másik nyelvben, például a C++
. 30.03.2015 NULL
lehet (void*)0
, de nem 0
és 0L
sem. Válasza szerint 0, or (void*)0 or 0L
lehet. Az Ön megjegyzése a legtöbb implementáció 0-t használ NULL
-ként, nem támasztja alá egyetlen példa sem, szemben a megadott 2 számláló példával. 30.03.2015 NULL
lehet 0
vagy (void *)0
- helyesbítve. 30.03.2015 míg (expression
) megismétli a befoglaló blokkot mindaddig, amíg a expression
bármely nullától eltérő értékre kiértékelődik. Amikor a expression
értéke 0, a while ciklus véget ér.
Ha a mutató értéke nem std::nullptr
vagy NULL
, a expression
, amely mutatótípus, nem 0-nak minősül.
A !
operátor egy logikai not
operátor.
Ebből adódóan
while (foo)
És
while (foo != NULL)
logikailag egyenértékűek egymással. Ezért a kettő logikai inverze is ekvivalens egymással.
std::nullptr
egy c++ dolog. [c] kérdésben vagyunk. 30.03.2015 A NULL
egy szimbolikus állandó, egyfajta helyettesítő szövegként is felfogható. A NULL
csak valami, amit a fordító később nullára cserél, így a while (foo != NULL)
írása ugyanaz, mint a while (foo != 0)
. Ne feledje, hogy az ==
igent mond, ha a tőle balra lévő egyenlő azzal, ami tőle jobbra van, míg a !=
igent mond, ha a tőle balra lévő NEM egyenlő azzal, ami tőle jobbra van.
C-ben a 0 szám mindig hamis, minden más szám pedig igazat jelent. Tehát a while (foo != 0)
ugyanaz, mint azt mondani, hogy "Futtassa a kódot ebben a ciklusban, miközben a foo igaz". A while (1)
például ugyanaz, mint azt mondani, hogy "Futtassa a kódot ebben a ciklusban örökre", mert az 1 egy olyan szám, amely mindig különbözik a nullától, és ezért mindig igaz.
C-ben, ha csak a foo
értéket használja, ahol igaz vagy hamis típusú értéket várunk, ez ugyanaz, mintha foo != 0
-et mondanánk, ez olyan, mint egy használható parancsikon. A !
azt jelenti, hogy "nem", tehát a !foo
megkérdezése megegyezik azzal a kérdéssel, hogy "a foo NEM igaz?", más szóval "hamis a foo?". Ez azt jelenti, hogy a while (!foo)
ugyanaz, mint a "Futtassa a kódot ebben a ciklusban, miközben a foo false", ami ugyanaz, mint a while (foo == 0)
, mivel a nulla hamis, ami ugyanaz, mint a while (foo == NULL)
, mivel a NULL
nullát jelent.
Képzeld el a következőképpen: a ciklusban lévő kód csak akkor fut le, ha a zárójelben szereplő igaz (azaz nem nulla). Tehát a while (foo)
-ben a számítógép megkérdezi, hogy "a foo nem nulla?", ha igen, a ciklus folytatódik. Most, ha while (!foo)
van, a számítógép megkérdezi, hogy "a foo NOT nem nulla?", ha igen, a ciklus folytatódik. A ciklus csak akkor áll le, ha a zárójelben lévő kifejezés false értéket eredményez.
A NULL
számos szabványos fejlécfájlban van definiálva, ez nem olyan kulcsszó, mint a if
és while
, használatához tartalmaznia kell egy fejlécfájlt, amely meghatározza azt. Az ötlet az, hogy amikor egy mutató a nulla címre mutat, azt "null pointernek" hívják, ezért hívják NULL
-nek, és akkor használják, ha azt akarjuk mondani, hogy "nulla a cím", nem pedig pusztán "nulla a szám".
Szerkesztés: Ahogyan Matt McNabb helyesen rámutatott, a NULL
definíciója lehet 0
vagy (void *)0
. A kétségek elkerülése végett a C11 szabványt idézem:
A 0 értékű egész konstans kifejezést, vagy a void * típusba öntött kifejezést null pointer konstansnak nevezzük.
És később
A NULL makró a ‹stddef.h› fájlban (és más fejlécekben) null mutatókonstansként van definiálva; lásd 7.19.
Ezután a 7.19. szakaszban:
3 A makrók
NULL
amely kibővül egy megvalósítás által definiált null mutató állandóvá; és
eltolás (típus, tagjelölő)
ami kibővül...
És a szöveg megy tovább. Tehát a (void *)0
és a 0
érvényes implementáció által meghatározott nullmutató konstansok.
NULL
lehet 0
vagy (void *)0
. 30.03.2015 NULL
0
? Ahogy olvasom a C spec-et, a NULL
egy null mutató állandó. A 0
egy int
. Talán ugyanaz az érték, de eltérő típusok és méretek. 30.03.2015 null pointer constan
t értéket egy egész szám állandóként, amely nullával egyenlő, vagy ugyanazt a void*
-re vetített értéket. 30.03.2015 NULL
képviselje, de szükséges, hogy a 0
egész számot NULL
-ként kezelje mutatókontextusban. 30.03.2015 0
egész számot NULL
-ként kezelje mutatókontextusban, de ez nem jelenti azt, hogy a null pointer constant
(NULL
) egész szám állandó a korábbi megjegyzésében. Az egyértelműség kedvéért a NULL
-nek nem csak értéke van, hanem típusa is. Ahogy olvastam a C specifikációt, ez a típus valami mutató, a 0
pedig nem mutató. 30.03.2015 "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant"
== "defines null pointer constant on being an integer constant that equals zero or the same cast to void*"
, legalábbis nekem. 30.03.2015 NULL
értékkel, az 0
vagy (void *)0
lehet. 30.03.2015 a while ciklus így futhat:
while(1) //This will run forever.
while(true) //This will run forever.
A NULL
olyan, mint a 0, tehát ha van while(foo != NULL)
, akkor ez azt jelenti, hogy a while (foo nem egyenlő 0-val, tehát míg egyenlő 1-gyel vagy valami mással) futtassa.
0
egyint
típusú kifejezés és egy nulla mutatókonstans; látom, hogy ez zavart okozhat.) 30.03.2015#define NULL 0
ugyanúgy érvényes lehet, mint#define NULL ((void*)0)
. Ez utóbbinak vannak előnyei, de mindkettő megfelel az előírásoknak. 30.03.2015#define NULL ((void*)0)
nem érvényes. (Az N1570 6.5.1p5 nem mondja ki, hogy a zárójelben szereplő nullmutató állandó nullamutató állandó.) A gyakorlatban azonban minden bizonnyal érvényesnek kell lennie. 30.03.2015