Ist ein Zeiger, der auf 0x0000 zeigt, dasselbe wie ein Zeiger, der auf NULL gesetzt ist? Wenn der NULL-Wert in der C-Sprache definiert ist, an welchen Speicherort wird er dann physisch übersetzt? Ist es das gleiche wie 0x0000. Wo finde ich weitere Details zu diesen Konzepten?
12
Antworten:
Ein Punkt, den die meisten Antworten hier zumindest nicht explizit ansprechen, ist, dass ein Nullzeiger ein Wert ist, der während der Ausführung vorhanden ist, und eine Nullzeiger-Konstante ein syntaktisches Konstrukt ist, das im C-Quellcode vorhanden ist.
Eine Nullzeiger-Konstante ist , wie in der Antwort von Karlson richtig angegeben, entweder ein ganzzahliger konstanter Ausdruck mit dem Wert 0 (ein einfaches Beispiel
0
ist das gebräuchlichste) oder ein solcher Ausdruck, der invoid*
(wie(void*)0
) umgewandelt wird.NULL
ist ein Makro, das in<stddef.h>
und mehreren anderen Standard-Headern definiert ist und zu einer implementierungsdefinierten Nullzeiger-Konstante erweitert wird . Die Erweiterung ist normalerweise entweder0
oder((void*)0)
(die äußeren Klammern werden benötigt, um andere Sprachregeln zu erfüllen).0
Wenn also ein Literal in einem Kontext verwendet wird, der einen Ausdruck vom Zeigertyp erfordert, wird es immer zunull pointer
einem eindeutigen Zeigerwert ausgewertet, der auf kein Objekt verweist. Das macht nicht bedeuten , etwas über die Darstellung eines Null - Zeiger . Nullzeiger werden sehr häufig als All-Bit-Null dargestellt, können aber als alles dargestellt werden. Aber auch wenn ein Nullzeiger als dargestellt0xDEADBEEF
wird0
oder(void*)0
immer noch eine Nullzeiger-Konstante ist .Diese Antwort auf die Frage zum Stackoverflow deckt dies gut ab.
Dies impliziert unter anderem, dass
memset()
odercalloc()
, das einen Speicherbereich auf Null setzen kann, keine Zeiger in diesem Bereich auf Null setzen muss. Bei den meisten Implementierungen ist dies wahrscheinlich der Fall, aber die Sprache garantiert dies nicht.Ich weiß nicht , warum diese Frage nicht ein Duplikat betrachtet diese , oder wie es hier aktuell.
quelle
NULL
oder einer beliebigen Nullzeiger-Konstante zu einem Zeigerobjekt wird der Wert dieses Objekts auf einen Nullzeiger gesetzt . Auf der Maschinenebene kann es durchaus auf einen gültigen Speicherblock hindeuten. Das Dereferenzieren eines Nullzeigers hat ein undefiniertes Verhalten. Der Zugriff auf einen Teil des Speichers unter der Adresse0x0000000
ist ein gültiges Verhalten, genau wie alles andere. Diese Adresse unterscheidet sich von jeder anderen Adresse durch (a) Vergleichen gleichNULL
und (b) Vergleichen ungleich einem Zeiger auf ein C-Objekt. Ein Nullzeiger ist ein beliebiger Zeigerwert, der angibt, dass er auf nichts verweist.Jede Plattform da draußen kann NULL frei definieren.
Wenn Sie einem Zeiger gemäß C-Standard Null zuweisen, wird er in einen NULL-Wert (für diese Plattform) konvertiert. Wenn Sie jedoch einen NULL-Zeiger verwenden und ihn in int umwandeln, gibt es keine Garantie dafür, dass Sie Null erhalten auf jeder Plattform da draußen. Tatsache ist jedoch, dass es auf den meisten Plattformen Null sein wird.
Informationen zu diesem Thema finden Sie in der C-Sprachspezifikation . Eine Quelle, für deren Vertrauenswürdigkeit ich nicht bürgen kann: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
quelle
NULL pointer constant
. Soweit ich weiß, gibt es keine Compiler, die das tun.NULL
Makros, das0
in C ++ und entweder0
oder(void *)0
in C erweitert werden muss. denn das ist die echte "Nullzeiger-Konstante".Es ist in der Sprache C definiert, da es keine unveränderliche Maschinenadresse gibt, der es entspricht. Wenn es so wäre, bräuchten wir keine Abstraktion davon! Auch wenn auf den meisten Plattformen NULL möglicherweise irgendwann als 0 implementiert wird, ist es schlichtweg falsch anzunehmen, dass dies universell ist, wenn Sie sich überhaupt für Portabilität interessieren.
quelle
Gemäß Abschnitt C Standarddokument
6.3.2.3
:Bisher habe ich noch keinen Compiler gesehen, der sich davon gelöst hat.
quelle