In C scheint es Unterschiede zwischen verschiedenen Werten von Null zu geben - NULL
, NUL
und 0
.
Ich weiß, dass das ASCII-Zeichen zu '0'
ausgewertet wird48
oder0x30
.
Der NULL
Zeiger ist normalerweise definiert als:
#define NULL 0
Oder
#define NULL (void *)0
Hinzu kommt der NUL
Charakter'\0'
der ebenfalls zu bewerten scheint 0
.
Gibt es Zeiten, in denen diese drei Werte nicht gleich sein können?
Gilt das auch für 64-Bit-Systeme?
NUL
existiert nicht in der C-Standardsprache oder -Bibliothek (oder, soweit ich weiß, in C ++). Das Nullzeichen wird manchmal als NUL bezeichnet, aber es wird normalerweise nur als C oder C ++ bezeichnet'\0'
.Antworten:
Hinweis: Diese Antwort gilt für die C-Sprache, nicht für C ++.
Nullzeiger
Das ganzzahlige Konstantenliteral
0
hat je nach Kontext, in dem es verwendet wird, unterschiedliche Bedeutungen. In allen Fällen ist es immer noch eine ganzzahlige Konstante mit dem Wert0
, es wird nur auf verschiedene Arten beschrieben.Wenn ein Zeiger mit dem konstanten Literal verglichen wird,
0
wird überprüft, ob der Zeiger ein Nullzeiger ist. Dies0
wird dann als Nullzeigerkonstante bezeichnet. Der C-Standard definiert, dass die0
Umwandlung in den Typvoid *
sowohl ein Nullzeiger als auch eine Nullzeigerkonstante ist.Um die Lesbarkeit zu verbessern, wird das Makro hinzugefügt
NULL
in der Header-Datei bereitgestelltstddef.h
. Abhängig von Ihrem Compiler ist es möglicherweise möglich,#undef NULL
ihn zu etwas Verrücktem neu zu definieren.Daher gibt es hier einige gültige Möglichkeiten, um nach einem Nullzeiger zu suchen:
NULL
ist so definiert, dass es einem Nullzeiger entspricht. Es ist eine Implementierung, die definiertNULL
ist, wie die tatsächliche Definition lautet, solange es sich um eine gültige Nullzeigerkonstante handelt.0
ist eine weitere Darstellung der Nullzeigerkonstante.Diese
if
Anweisung prüft implizit "ist nicht 0", daher kehren wir das um und bedeuten "ist 0".Die folgenden Methoden sind UNGÜLTIG, um nach einem Nullzeiger zu suchen:
Für den Compiler ist dies keine Prüfung auf einen Nullzeiger, sondern eine Gleichheitsprüfung für zwei Variablen. Dies kann funktionieren, wenn mynull den Code nie ändert und die Compiler-Optimierungskonstante die 0 in die if-Anweisung faltet. Dies ist jedoch nicht garantiert und der Compiler muss mindestens eine Diagnosemeldung (Warnung oder Fehler) gemäß C-Standard erstellen.
Beachten Sie, dass dies ein Nullzeiger in der Sprache C ist. Es spielt keine Rolle für die zugrunde liegende Architektur. Wenn die zugrunde liegende Architektur einen Nullzeigerwert hat, der als Adresse 0xDEADBEEF definiert ist, ist es Sache des Compilers, dieses Durcheinander zu beseitigen.
Selbst in dieser lustigen Architektur sind die folgenden Methoden immer noch gültige Methoden, um nach einem Nullzeiger zu suchen:
Die folgenden Methoden sind UNGÜLTIG, um nach einem Nullzeiger zu suchen:
da diese von einem Compiler als normale Vergleiche angesehen werden.
Nullzeichen
'\0'
wird als Nullzeichen definiert - das ist ein Zeichen, bei dem alle Bits auf Null gesetzt sind. Dies hat nichts mit Zeigern zu tun. Möglicherweise sehen Sie jedoch etwas Ähnliches wie diesen Code:Überprüft, ob der Zeichenfolgenzeiger auf ein Nullzeichen zeigt
Überprüft, ob der Zeichenfolgenzeiger auf ein Nicht-Null-Zeichen zeigt
Verwechseln Sie diese nicht mit Nullzeigern. Nur weil die Bitdarstellung dieselbe ist und dies einige bequeme Überkreuzungsfälle ermöglicht, sind sie nicht wirklich dasselbe.
Außerdem
'\0'
ist (wie alle Zeichenliterale) eine Ganzzahlkonstante, in diesem Fall mit dem Wert Null. Ist'\0'
also völlig gleichbedeutend mit einer schmucklosen0
Ganzzahlkonstante - der einzige Unterschied besteht in der Absicht , die sie einem menschlichen Leser vermittelt ("Ich verwende dies als Nullzeichen.").Verweise
Weitere Informationen finden Sie in Frage 5.3 der FAQ zu comp.lang.c. In diesem PDF finden Sie den C-Standard. Lesen Sie die Abschnitte 6.3.2.3 Zeiger, Absatz 3.
quelle
ptr
mit All-Bits-Null vergleichen . Dies ist keinmemcmp
, aber dies ist ein Vergleich mit einem eingebauten Operator. Die eine Seite ist eine Nullzeigerkonstante'\0'
und die andere Seite ist ein Zeiger. Aswell wie bei den beiden anderen Versionen mitNULL
und0
. Diese drei machen das Gleiche.0xDEADBEEF
noch ein Nullzeiger ist, egal was seine Bitstring aussieht, und es wird zu vergleichen , noch gleichNULL
,0
,\0
und alle anderen Null - Zeiger - Konstante bildet.ptr == '\0'
.Es scheint, dass einige Leute die Unterschiede zwischen NULL, '\ 0' und 0 falsch verstehen. Um dies zu erklären und um zu vermeiden, dass die zuvor genannten Dinge wiederholt werden:
Ein konstanter Ausdruck des Typs
int
mit dem Wert 0 oder einem Ausdruck dieser Art, gegossen , um Typenvoid *
ist ein Nullzeiger Konstante , die in einen Zeiger umgewandelt wird zu einem , wenn Null - Zeiger . Der Standard garantiert, dass der Vergleich mit einem Zeiger auf ein Objekt oder eine Funktion ungleich ist .NULL
ist ein Makro, das als Nullzeigerkonstante definiert ist .\0
ist eine Konstruktion, die zur Darstellung des Nullzeichens verwendet wird und zum Beenden einer Zeichenfolge verwendet wird.Ein Nullzeichen ist ein Byte, dessen Bits auf 0 gesetzt sind.
quelle
Alle drei definieren die Bedeutung von Null in unterschiedlichen Zusammenhängen.
Diese drei sind immer unterschiedlich, wenn Sie sich die Erinnerung ansehen:
Ich hoffe das klärt es.
quelle
sizeof('\0')
und überrascht sein.Wenn NULL und 0 als Nullzeigerkonstanten äquivalent sind, welche soll ich verwenden? In der C-FAQ-Liste wird auch dieses Problem behoben:
quelle
"Nullzeichen (NUL)" ist am einfachsten auszuschließen.
'\0'
ist ein Zeichenliteral. In C ist es so implementiertint
, dass es dasselbe ist wie 0, was von istINT_TYPE_SIZE
. In C ++ wird das Zeichenliteral alschar
1 Byte implementiert . Dies unterscheidet sich normalerweise vonNULL
oder0
.Nächster,
NULL
wird ein Zeigerwert angegeben, der angibt, dass eine Variable nicht auf einen Adressraum verweist. Abgesehen von der Tatsache, dass es normalerweise als Nullen implementiert wird, muss es in der Lage sein, den gesamten Adressraum der Architektur auszudrücken. In einer 32-Bit-Architektur beträgt NULL (wahrscheinlich) 4 Byte und in einer 64-Bit-Architektur 8 Byte. Dies liegt an der Implementierung von C.Schließlich ist das Literal
0
vom Typint
, der von Größe istINT_TYPE_SIZE
. Der Standardwert vonINT_TYPE_SIZE
kann je nach Architektur unterschiedlich sein.Apple schrieb:
Wikipedia 64-Bit :
Bearbeiten : Mehr zum Zeichenliteral hinzugefügt.
Der obige Code gibt 4 auf gcc und 1 auf g ++ zurück.
quelle
'\0'
ist kein 1-Byte-Wert. Es ist ein Zeichenliteral, das ein ganzzahliger konstanter Ausdruck ist. Wenn also gesagt werden kann, dass es eine Größe hat, dann ist es die Größe von aint
(die mindestens 2 Bytes betragen muss). Wenn Sie mir nicht glauben, bewerten Siesizeof('\0')
und überzeugen Sie sich selbst.'\0'
,0
Und0x0
sind völlig gleichwertig.sizeof('\0')
einen C ++ - Compiler aus.Ein One-L NUL, es beendet eine Zeichenfolge.
Ein Zwei-L-NULL zeigt auf nichts.
Und ich werde einen goldenen Stier wetten
Dass es keine Drei-L-NULL gibt.
Wie gehst du mit NUL um?
quelle
Ein gutes Stück, das mir hilft, wenn ich mit C beginne (entnommen aus der Expert C-Programmierung von Linden)
Das Eine 'l' nul und das Zwei 'l' null
Merken Sie sich diesen kleinen Reim, um die korrekte Terminologie für Zeiger und ASCII-Null abzurufen:
Das ASCII-Zeichen mit dem Bitmuster Null wird als "NUL" bezeichnet. Der spezielle Zeigerwert, der bedeutet, dass der Zeiger nirgendwo hin zeigt, ist "NULL". Die beiden Begriffe sind in ihrer Bedeutung nicht austauschbar.
quelle
NUL
ist ein Steuercode wieBEL
,VT
,HT
,SOT
usw. und hat somit max. 3 Zeichen."NUL" ist nicht 0, sondern bezieht sich auf das ASCII-NUL-Zeichen. Zumindest habe ich das so gesehen. Der Nullzeiger wird häufig als 0 definiert. Dies hängt jedoch von der Umgebung ab, in der Sie ausgeführt werden, und von der Spezifikation des von Ihnen verwendeten Betriebssystems oder der verwendeten Sprache.
In ANSI C wird der Nullzeiger als ganzzahliger Wert 0 angegeben. Jede Welt, in der dies nicht zutrifft, ist also nicht ANSI C-konform.
quelle
Ein Byte mit dem Wert von
0x00
ist in der ASCII-Tabelle das SonderzeichenNUL
oderNULL
. Da Sie in C keine Steuerzeichen in Ihren Quellcode einbetten sollten, wird dies in C-Zeichenfolgen mit einer maskierten 0 dargestellt, d. H.\0
. H.Aber ein wahrer NULL ist kein Wert. Es ist das Fehlen eines Wertes. Für einen Zeiger bedeutet dies, dass der Zeiger nichts hat, auf das er zeigen kann. In einer Datenbank bedeutet dies, dass ein Feld keinen Wert enthält (was nicht bedeutet, dass das Feld leer, 0 oder mit Leerzeichen gefüllt ist).
Der tatsächliche Wert, den ein bestimmtes System- oder Datenbankdateiformat zur Darstellung von a verwendet,
NULL
ist nicht unbedingt erforderlich0x00
.quelle
NULL
ist nicht garantiert 0 - sein genauer Wert ist architekturabhängig. Die meisten großen Architekturen definieren es so(void*)0
.'\0'
wird immer gleich 0 sein, da Byte 0 auf diese Weise in einem Zeichenliteral codiert wird.Ich erinnere mich nicht, ob C-Compiler ASCII verwenden müssen - wenn nicht, sind sie
'0'
möglicherweise nicht immer gleich 48. Unabhängig davon ist es unwahrscheinlich, dass Sie jemals auf ein System stoßen, das einen alternativen Zeichensatz wie EBCDIC verwendet, es sei denn, Sie arbeiten sehr daran obskure Systeme.Die Größen der verschiedenen Typen unterscheiden sich auf 64-Bit-Systemen, aber die ganzzahligen Werte sind gleich.
Einige Kommentatoren haben Zweifel geäußert , dass NULL gleich 0 sein, aber nicht sein Null. Hier ist ein Beispielprogramm zusammen mit der erwarteten Ausgabe auf einem solchen System:
Dieses Programm könnte drucken:
quelle
(void *) 0 ist NULL und '\ 0' steht für das Ende einer Zeichenfolge.
quelle