( Bitte lesen Sie diesen Absatz, bevor Sie den Beitrag lesen.Ich bitte jeden, der daran interessiert ist, diesen Beitrag zu lesen, zu versuchen, ihn sorgfältig zu lesen, und natürlich nicht abzustimmen, bis Sie ihn vollständig verstanden haben, danke. )
Es ist jetzt ein Community-Wiki. Wenn jemand mit einem der Konzepte nicht einverstanden ist, ändern Sie es bitte mit einer klaren und detaillierten Erklärung, was falsch ist und warum, und wenn möglich, zitieren Sie Quellen oder liefern Sie Beweise, die reproduziert werden können.
Antworten
Hier sind einige andere Gründe, die die zugrunde liegenden Faktoren für NULL == 0 sein könnten
- Die Tatsache, dass Null falsch ist, kann man also direkt
if(!my_ptr)
statt tun if(my_ptr==NULL)
.
- Die Tatsache, dass nicht initiierte globale Ganzzahlen standardmäßig auf alle Nullen initialisiert werden und als solcher ein Zeiger aller Nullen als nicht initialisiert betrachtet wird.
Hier möchte ich ein Wort zu anderen Antworten sagen
Nicht wegen syntaktischen Zuckers
Zu sagen, dass NULL wegen syntaktischen Zuckers Null ist, macht nicht allzu viel Sinn. Wenn ja, warum nicht den Index 0 eines Arrays verwenden, um seine Länge zu halten?
Tatsächlich ist C die Sprache, die der internen Implementierung am ähnlichsten ist. Ist es sinnvoll zu sagen, dass C nur wegen syntaktischen Zuckers Null gewählt hat? Sie würden lieber ein Schlüsselwort null angeben (wie es viele andere Sprachen tun), als null auf NULL abzubilden!
Obwohl es sich heute möglicherweise nur um syntaktischen Zucker handelt, ist klar, dass die ursprüngliche Absicht der Entwickler der C-Sprache nicht syntaktischer Zucker war, wie ich weiter zeigen werde.
1) Die Spezifikation
Zwar spricht die C-Spezifikation von der Konstanten 0 als Nullzeiger (Abschnitt 6.3.2.3) und definiert auch NULL als implementierungsdefiniert (Abschnitt 7.19 in der C11-Spezifikation und 7.17 in der C99-Spezifikation) Tatsache bleibt, dass in dem von den Erfindern von C verfassten Buch "The C Programming Language" in Abschnitt 5.4 Folgendes angegeben ist:
C garantiert, dass Null niemals eine gültige Adresse für Daten ist, sodass ein Rückgabewert von Null verwendet werden kann, um ein abnormales Ereignis zu signalisieren, in diesem Fall kein Leerzeichen.
Zeiger und ganze Zahlen sind nicht austauschbar, Null ist die einzige Ausnahme: Die Konstante Null kann einem Zeiger zugewiesen werden, und ein Zeiger kann mit der Konstanten Null verglichen werden. Die symbolische Konstante NULL wird häufig anstelle von Null als Mnemonik verwendet, um deutlicher anzuzeigen, dass dies ein spezieller Wert für einen Zeiger ist. NULL ist definiert in. Wir werden fortan NULL verwenden.
Wie man sehen kann (aus den Worten "Nulladresse"), war zumindest die ursprüngliche Absicht der Autoren von C die Adresse Null und nicht die Konstante Null, außerdem geht aus diesem Auszug hervor, dass der Grund, warum die Spezifikation von der spricht Die Konstante Null soll wahrscheinlich keinen Ausdruck ausschließen, der als Null ausgewertet wird, sondern stattdessen die Ganzzahlkonstante Null als einzige Ganzzahlkonstante einschließen, die in einem Zeigerkontext ohne Umwandlung verwendet werden darf.
2) Zusammenfassung
Während die Spezifikation nicht explizit besagt, dass eine Nulladresse anders als die Nullkonstante behandelt werden kann, sagt sie dies nicht, und die Tatsache, dass beim Umgang mit der Nullzeigerkonstante nicht behauptet wird, dass sie als solche definiert ist Wenn die von NULL definierte Konstante stattdessen behauptet, sie sei Null, zeigt dies, dass möglicherweise ein Unterschied zwischen der Nullkonstante und der Nulladresse besteht.
(Wenn dies jedoch der Fall ist, frage ich mich nur, warum NULL implementierungsdefiniert ist, da in einem solchen Fall NULL auch die Konstante Null sein kann, da der Compiler ohnehin alle Nullkonstanten in die tatsächlich implementierte Implementierung NULL konvertieren muss.)
Ich sehe dies jedoch nicht in der realen Aktion, und auf den allgemeinen Plattformen werden die Adresse Null und die Konstante Null gleich behandelt und werfen die gleiche Fehlermeldung aus.
Tatsache ist außerdem, dass die heutigen Betriebssysteme tatsächlich die gesamte erste Seite (Bereich 0x0000 bis 0xFFFF) reservieren, um den Zugriff auf die Nulladresse aufgrund des NULL-Zeigers von C zu verhindern (siehe http://en.wikipedia.org/wiki/). Zero_page sowie "Windows Via C / C ++ von Jeffrey Richter und Christophe Nasarre (herausgegeben von Microsoft Press)").
Daher würde ich jeden, der behauptet, es tatsächlich in Aktion gesehen zu haben, bitten, die Plattform und den Compiler sowie den genauen Code anzugeben, den er tatsächlich gemacht hat (obwohl aufgrund der vagen Definition in der Spezifikation [wie ich gezeigt habe] jeder Compiler und die Plattform ist frei zu tun, was er will).
Es scheint jedoch, dass die Autoren von C dies nicht im Sinn hatten und von der "Null-Adresse" sprachen und dass "C garantiert, dass es sich nie um eine gültige Adresse handelt" sowie "NULL ist nur eine" Mnemonik ", was deutlich zeigt, dass die ursprüngliche Absicht nicht" syntaktischer Zucker "war.
Nicht wegen des Betriebssystems
Außerdem wird behauptet, dass das Betriebssystem aus mehreren Gründen den Zugriff auf die Adresse Null verweigert:
1) Als C geschrieben wurde, gab es keine solche Einschränkung, wie man auf dieser Wikipage http://en.wikipedia.org/wiki/Zero_page sehen kann .
2) Tatsache ist, dass C-Compiler auf die Speicheradresse Null zugegriffen haben.
Dies scheint die Tatsache aus dem folgenden Artikel von BellLabs ( http://www.cs.bell-labs.com/who/dmr/primevalC.html ) zu sein.
Die beiden Compiler unterscheiden sich in den Details darin, wie sie damit umgehen. Im vorherigen Fall wird der Start durch Benennen einer Funktion gefunden. Im späteren Fall wird der Start einfach als 0 angenommen. Dies zeigt an, dass der erste Compiler geschrieben wurde, bevor wir eine Maschine mit Speicherzuordnung hatten, sodass der Ursprung des Programms nicht an Position 0 lag, während zum Zeitpunkt des zweiten Wir hatten einen PDP-11, der Mapping lieferte.
(Tatsächlich liegt der Grund für die Einschränkung des Zugriffs auf die Nulladresse ab heute (wie ich oben in Wikipedia und Microsoft Press zitiert habe) in den NULL-Zeigern von C! Am Ende stellt sich heraus, dass es umgekehrt ist!)
3) Denken Sie daran, dass C auch zum Schreiben von Betriebssystemen und sogar von C-Compilern verwendet wird!
Tatsächlich wurde C entwickelt, um das UNIX-Betriebssystem damit zu schreiben, und als solches scheint es kein Grund zu sein, sich von der Adresse Null zu beschränken.
(Hardware) Erläuterung, wie Computer (physisch) auf die Adresse Null zugreifen können
Es gibt noch einen weiteren Punkt, den ich hier erläutern möchte: Wie ist es überhaupt möglich, auf die Adresse Null zu verweisen?
Denken Sie eine Sekunde darüber nach, die Adressen werden vom Prozessor abgerufen und dann als Spannungen auf dem Speicherbus gesendet, der dann vom Speichersystem verwendet wird, um zur tatsächlichen Adresse zu gelangen, und dennoch bedeutet eine Adresse von Null keine Spannung Wie greift die physische Hardware des Speichersystems auf die Adresse Null zu?
Die Antwort scheint zu sein, dass die Adresse Null die Standardeinstellung ist, und mit anderen Worten, die Adresse Null ist für das Speichersystem immer zugänglich, wenn der Speicherbus vollständig ausgeschaltet ist, und als solche jede Anforderung zum Lesen oder Schreiben, ohne eine tatsächliche Adresse anzugeben (welche ist der Fall bei Adresse Null) greift automatisch auf Adresse Null zu.
if (p != 0)
zuif (p)
einer in C und C ++ gebräuchlichen Redewendung wechseln , obwohl Sie sich aus der Gewohnheit befreien müssen, wenn Sie Java verwenden.