În C, par să existe diferențe între diferite valori de zero -- NUL
, NUL
și 0
.
Știu că de caractere ASCII'0'
se evaluează la 48 " sau " 0x30
.
La NULL
pointer este de obicei definit ca:
#define NULL 0
Sau
#define NULL (void *)0
În plus, există NUL
caracter'\0'
care pare să se evalueze la 0
la fel de bine.
Există momente când aceste trei valori nu pot fi egale?
Este adevărat, de asemenea, pe sistemele pe 64 biti?
Notă: Acest răspuns este valabil pentru limbajul C, nu C++.
Întreg constante literale 0
are sensuri diferite în funcție de contextul în care se's a folosit. În toate cazurile, este încă un număr întreg constantă cu valoarea "0", este descris în moduri diferite.
Dacă un pointer este comparat cu constante literale 0
, atunci aceasta este o verificare pentru a vedea dacă indicatorul este un pointer nul. Acest " 0 " atunci menționată ca un pointer nul constantă. C standard definește ca 0
exprimate de tip void *` este atât un pointer nul și un pointer nul constantă.
În plus, pentru a ajuta lizibilitate, macro NULL
este furnizat în fișierul antet stddef.h
. În funcție de compilator, ar putea fi posibil să #undef NUL
și redefinească la ceva nebunesc.
Prin urmare, aici sunt unele valabil moduri de a verifica pentru un pointer nul:
if (pointer == NULL)
NULL
este definit pentru a compara egal cu un pointer null. Aceasta este punerea în aplicare a definit ceea ce definiția actuală a NULL
este, atâta timp cât acesta este valabil null pointer constant.
if (pointer == 0)
0
este o altă reprezentare a null pointer constant.
if (!pointer)
Acest "dacă" declarație implicit verifică "nu este 0", asa ca am inversă care să spui "0".
Următoarele sunt valabile moduri de a verifica pentru un pointer nul:
int mynull = 0;
<some code>
if (pointer == mynull)
Pentru compilatorul acest lucru nu este un cec pentru un pointer nul, dar o egalitate verifica pe două variabile. Acest lucru ar putea ** funcționa dacă mynull nu se schimbă niciodată în cod și compilatorul optimizări constantă ori 0 în cazul în care declarația, dar acest lucru nu este garantat și compilatorul trebuie să producă cel puțin un diagnostic mesaj (de avertizare sau de eroare) potrivit C Standard.
Rețineți că ceea ce este un pointer nul în limbajul C. Nu contează pe baza arhitecturii. Dacă arhitectura de bază a unui pointer nul valoarea definită ca adresa 0xDEADBEEF, atunci este de până la compilator pentru a rezolva problema.
Ca atare, chiar pe acest amuzant arhitectura, următoarele moduri sunt încă valabile moduri de a verifica pentru un pointer nul:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Următoarele sunt valabile moduri de a verifica pentru un pointer nul:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
ca acestea sunt văzute de către un compilator ca normal comparații.
'\0'
este definit a fi un caracter nul - care este un personaj cu toți biții setați la zero. Acest lucru nu are nimic de-a face cu indicii. Cu toate acestea, este posibil să vedeți ceva similar cu acest cod:
if (!*string_pointer)
verifică dacă șirul pointer este îndreptat la un caracter null
if (*string_pointer)
verifică dacă șirul pointer este îndreptat la un non-null caracter
Don't obține aceste confundat cu null pointer. Doar pentru că pic de reprezentare este la fel, și acest lucru vă permite pentru unele convenabil treacă cazuri, acestea nu sunt chiar același lucru.
În plus, '\0'
este (la fel ca toate de caractere literale) un număr întreg constantă, în acest caz, cu valoarea zero. Deci'\0'
este complet echivalentă cu o neinfrumusetata 0
întreg constanta - singura diferență este în intenție, care se transmite de la un om reader ("I'm, folosind acest lucru ca un caracter nul.").
A se vedea Întrebare 5.3 din comp.lang.c FAQ pentru mai multe. A se vedea pdf pentru C standard. Check out secțiuni 6.3.2.3 Indicii, punctul 3.
Se pare că un număr de oameni înțeleg greșit ce diferențele între NULL, '\0' și 0 sunt. Deci, pentru a explica, și în încercarea de a evita repetarea lucruri spuse mai devreme:
O expresie constantă de tip int cu valoarea 0, sau o expresie de acest tip, exprimate de tip void * este un null pointer constant, care, dacă convertit la un pointer devine o pointer nul. Acesta este garantat de standardul de a compara inegale la orice pointer la orice obiect sau funcția.
NULL este un macro, definite în <stddef.h> ca un null pointer constant.
'\0' este o construcție utilizate pentru a reprezenta caracter null, folosit pentru a termina un șir de caractere.
O caracter null este un octet care are toți biții setați la 0.
Toate trei pentru a defini sensul de la zero în alt context.
Aceste trei sunt diferite atunci când te uiți la memorie:
NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20
Sper că acest lucru clarifică.
Dacă NUL și 0 sunt echivalente ca pointer nul constante, care ar trebui să folosesc? în C FAQ lista abordează această problemă, precum:
C programatorii trebuie să înțeleagă că
NULL
si0
sunt interschimbabile în pointer contexte, și care o uncast0
este perfect acceptabil. Orice utilizare a NUL (ca opus la "0") ar trebui să fie considerat un memento blând ca un indicatorul este implicat; programatori nu ar trebui să depindă de ea (fie pentru propria lor înțelegere sau compiler's) pentru a distinge pointer0
's de la întreg0
's.Acesta este doar în indicatorul contexte care
NULL
si0
sunt echivalente.NULL
ar trebui să nu trebuie utilizat atunci când un alt fel de " 0 " este necesară, chiar dacă aceasta ar putea să funcționeze, pentru că, procedând astfel, trimite greșit stilistică mesaj. (În plus, ANSI permite definirea deNULL
să fie((void *)0)
, care nu va funcționa la toate în non-pointer contexte.) În special, nu utilizațiNULL
când ASCII caracterul null (NUL
) este de dorit. Ofere o definiție proprie
#define NUL '\0'
dacă trebuie.
care este diferența dintre NULL, '\0' si 0
"caracter nul (NUL)" este mai ușor pentru a exclude. '\0'
este un personaj literar.
În C, acesta este implementat ca int
, deci,'s la fel ca 0, care este de INT_TYPE_SIZE
. În C++, caracter literal este implementat ca char
, care este de 1 octet. Acest lucru este în mod normal, diferit de NULL
sau 0
.
Apoi, NULL
este un pointer valoare care specifică faptul că o variabilă nu orice spațiu de adrese. Las deoparte faptul că este de obicei implementat ca zero, acesta trebuie să fie capabil să-și exprime întregul spațiu de adrese de arhitectura. Astfel, pe o arhitectură pe 32 de biți NULL (probabil) este de 4 octet și pe arhitectura 64-bit 8-byte. Acest lucru este de până la punerea în aplicare a C.
În cele din urmă, literal 0
este de tip int
, care este de dimensiunea INT_TYPE_SIZE. Valoarea implicită a
INT_TYPE_SIZE` ar putea fi diferite în funcție de arhitectură.
Apple a scris:
64-bit model de date utilizate de sistemul de operare Mac OS X este cunoscut sub numele de "LP64". Acest lucru este comun model de date folosit de alte 64 de biți sisteme UNIX de la Soare și SGI precum și 64-bit Linux. La LP64 model de date definește tipuri primitive, după cum urmează:
- int sunt 32-bit
- cumpărătorii sunt pe 64-bit
- pe termen lung-cumpărătorii sunt, de asemenea, 64-bit
- indicii sunt pe 64-bit
Wikipedia 64-bit:
Microsoft's VC++ compiler folosește LLP64 model.
64-bit data models
Data model short int long long long pointers Sample operating systems
LLP64 16 32 32 64 64 Microsoft Win64 (X64/IA64)
LP64 16 32 64 64 64 Most Unix and Unix-like systems (Solaris, Linux, etc.)
ILP64 16 64 64 64 64 HAL
SILP64 64 64 64 64 64 ?
Edit: Adăugat mai mult pe caracterul literal.
#include <stdio.h>
int main(void) {
printf("%d", sizeof('\0'));
return 0;
}
Codul de mai sus returnează 4 pe gcc și 1 pe g++.
Unu-L NUL, se încheie un șir de caractere.
Un-doi-EU NUL puncte la nici un lucru.
Și pun pariu pe un taur de aur
Că nu există nici trei-L NULLL.
https://stackoverflow.com/questions/220423/how-do-you-deal-with-nul
O piesă bună, care mă ajută atunci când începe cu C(Luate de la Expertul de Programare C de Tei)
Cel 'l' nul și cei Doi 'l' nul
Memoreze această rimă să reamintim terminologia corectă pentru indicii și ASCII zero:
The one "l" NUL ends an ASCII string,
The two "l" NULL points to no thing.
Apologies to Ogden Nash, but the three "l" nulll means check your spelling.
Caracterul ASCII cu model de biți de zero este numit un "NUL". Speciale indicatorul valoare care înseamnă indicatorul de puncte nicăieri nu este "NUL". Cei doi termeni nu sunt interschimbabile în sensul.
"NUL" nu este 0, dar se referă la ASCII caracter NUL. Cel puțin, asta's cum am'am văzut-o folosită. Null pointer este adesea definit ca 0, dar acest lucru depinde de mediul de funcționare, și caietul de sarcini de orice sistem de operare sau limbaj pe care îl utilizați.
În ANSI C, null pointer este specificat ca valoarea întreagă 0. Deci orice lume în care ca's nu-i adevărat, nu este ANSI C conforme.
NULL
nu este garantat de a fi 0 -- valoarea sa exactă este arhitectura-dependente. Cele mai importante arhitecturi definiți la (void*)0
.
'\0'
va fi întotdeauna egală cu 0, pentru că este modul byte 0 este codificat într-un personaj literar.
Eu nu't amintesc dacă compilatoare C sunt necesare pentru a utiliza ASCII-dacă nu, '0'
s-ar putea să nu fie întotdeauna egale 48. Indiferent, l's puțin probabil'll întâlni vreodată un sistem care folosește o alternativă set de caractere ca EBCDIC dacă nu're de lucru pe foarte obscure sisteme.
Dimensiunile diverselor tipuri diferă pe sistemele pe 64 de biți, dar valorile întregi va fi la fel.
Unii comentatori și-au exprimat îndoiala că NULL fi egal cu 0, dar nu fi zero. Aici este un exemplu de program, împreună cu temperatura de ieșire pe un astfel de sistem:
#include <stdio.h>
int main () {
size_t ii;
int *ptr = NULL;
unsigned long *null_value = (unsigned long *)&ptr;
if (NULL == 0) {
printf ("NULL == 0\n"); }
printf ("NULL = 0x");
for (ii = 0; ii < sizeof (ptr); ii++) {
printf ("%02X", null_value[ii]); }
printf ("\n");
return 0;
}
Care program ar putea print:
NULL == 0
NULL = 0x00000001
Un octet cu valoarea 0x00 este, pe tabelul ASCII, caracterul special numit "NUL" sau "NUL". În C, deoarece nu ar trebui't încorpora caractere de control în codul sursă, aceasta este reprezentată în C siruri de caractere cu un evadat 0, de exemplu, "\0".
Dar un adevărat NUL este nu o valoare. Este lipsa de valoare. Pentru un pointer, înseamnă că indicatorul nu are nimic de a indica. Într-o bază de date, aceasta înseamnă că nu există nici o valoare într-un domeniu (care nu este același lucru cu a spune: câmpul este gol, 0, sau umplute cu spații).
La real valoarea unui anumit sistem sau o bază de date format de fișier folosește pentru a reprezenta un NUL e't neapărat 0x00.