Warum ist NULL nicht deklariert?

87

Ich habe ein Problem mit diesem Strukturkonstruktor, wenn ich versuche, diesen Code zu kompilieren:

typedef struct Node
{
    Node( int data ) //
    {
        this->data = data;
        previous = NULL; // Compiler indicates here
        next = NULL;
    }

    int data;
    Node* previous;
    Node* next;
} NODE;

Wenn ich komme, tritt dieser Fehler auf:

\linkedlist\linkedlist.h||In constructor `Node::Node(int)':|
\linkedlist\linkedlist.h|9|error: `NULL' was not declared in this scope|
    ||=== Build finished: 1 errors, 0 warnings ===|

Das letzte Problem war die Struktur, aber es hat gut funktioniert, als es in meiner main.cpp war, diesmal in einer Header-Datei und gibt mir dieses Problem. Ich verwende Code :: Blocks, um diesen Code zu kompilieren

entspannen
quelle

Antworten:

137

NULList keine integrierte Konstante in den Sprachen C oder C ++. Tatsächlich ist es in C ++ mehr oder weniger veraltet. Verwenden Sie 0stattdessen einfach ein einfaches Literal . Der Compiler wird je nach Kontext das Richtige tun.

Verwenden Sie in neuerem C ++ (C ++ 11 und höher) nullptr(wie in einem Kommentar erwähnt, danke).

Andernfalls fügen Sie hinzu

#include <stddef.h>

um die NULLDefinition zu bekommen .

entspannen
quelle
7
NULL ist Teil von stddef.h, nicht von stdlib.h. Technisch gesehen ist es nicht garantiert, dass Sie es als Teil von stdlib.h erhalten, obwohl ich zugebe, dass es ziemlich überraschend wäre, wenn Sie es nicht tun würden.
CB Bailey
8
NULL wird in den folgenden C-Headern definiert: stddef.h, stdlib.h, stdio.h, locale.h, string.h und time.h (und wchar.h, wenn Sie C99 zählen).
Michael Burr
8
<cstddef>ist die sauberere Option.
Fred Foo
29
Verwenden Sie NICHT "0", wenn Sie "NULL" meinen! Es gibt einen Unterschied : Semantik. Unterschätzen Sie niemals die Wichtigkeit, zu wissen, was etwas ist und das richtige Wort zu verwenden, auch wenn der Compiler Sie damit davonkommen lässt!
Imallett
13
@ 6502 Ich rede nicht darüber; 0 und NULL haben (fast) immer den gleichen Wert, daher funktioniert die Verwendung von '\ 0' oder 0 versehentlich. Das Problem ist die Semantik. Die Verwendung von NULL ist aussagekräftiger, da der Wert frage ein Zeiger und nicht nur eine Ganzzahl ist.
Imallett
34

Verwenden Sie NULL. Es ist sowieso nur #defined als 0 und es ist sehr nützlich, es semantisch von der Ganzzahl 0 zu unterscheiden.

Es gibt Probleme bei der Verwendung von 0 (und damit NULL). Beispielsweise:

void f(int);
void f(void*);

f(0); // Ambiguous. Calls f(int).

Die nächste Version von C ++ (C ++ 0x) enthält nullptr, um dies zu beheben.

f(nullptr); // Calls f(void*).
Eric
quelle
5
Es wird wie ((void *)0)bei den meisten C-Standardbibliotheksimplementierungen definiert .
Triang3l
1
Dies ist die beste kurze Antwort (und technisch präzise), die ich je zum Thema gelesen habe: NULL vs. 0 vs. nullptr. Danke dir!
Jose.angel.jimenez
2
@SiPlus ((void *)0)ist in C ++ falsch, da void*es nicht auf andere Zeigertypen erzwungen werden kann, wie dies beispielsweise in C. glibc der Fall ist, #define NULL 0wenn dies __cplusplusdefiniert ist.
rpjohnst
16

NULList kein nativer Teil der C ++ - Kernsprache, aber Teil der Standardbibliothek. Sie müssen eine der Standard-Header-Dateien einschließen, die die Definition enthält. #include <cstddef>oder #include <stddef.h>sollte ausreichen.

Die Definition von NULList garantiert verfügbar, wenn Sie cstddefoder einschließen stddef.h. Es ist nicht garantiert, aber es ist sehr wahrscheinlich, dass die Definition enthalten ist, wenn Sie stattdessen viele der anderen Standardheader einfügen.

CB Bailey
quelle
12

Fügen Sie "stdlib.h" oder "cstdlib" in diese Datei ein? NULL ist in stdlib.h / cstdlib definiert

#include <stdlib.h>

oder

#include <cstdlib>  // This is preferrable for c++
Andy White
quelle
2
NULL ist Teil von stddef.h, nicht stdlib.h
awiebe
@awiebe Das habe ich mir bis vor fünf Minuten gedacht - laut C99 müssen es einige verschiedene Header-Dateien definieren. Abschnitt 7.17 erfordert stddef.h bis, 7.20 erfordert es in stdlib.h, und es gibt wahrscheinlich einige andere.
AJM-Reinstate-Monica
4

Nicht verwenden NULL, C ++ ermöglicht es Ihnen, 0stattdessen das schmucklose zu verwenden:

previous = 0;
next = 0;

Und, wie bei C ++ 11, sollten Sie in der Regel nicht entweder mit NULL oder 0 da es bietet Ihnen nullptrden Typs std::nullptr_t, die besser für die Aufgabe geeignet ist.

paxdiablo
quelle
33
Ich denke, dass NULL eine nützliche Dokumentation ist, dass Sie beabsichtigen, eine Nullzeigerkonstante anstelle einer Ganzzahlkonstante zu verwenden, obwohl ich keine Einwände gegen die Verwendung von 0 habe. Ich gebe zu, dass Sie im Moment keine praktischen Vorteile erzielen Wenn Sie jedoch die nächste C ++ - Version übernehmen, ist dies ein guter Anfang für Orte, an denen Änderungen vorgenommen werden müssen, um die neue Nullptr-Konstante zu verwenden.
CB Bailey
1
Ich stimme Ihnen beiden natürlich zu. Übrigens ist es sowohl gut, dass man einen Zeiger dokumentiert, als auch gut, dass man tatsächlich eine ganze Zahl vorlegt. Betrachten Sie printf ("% p \ n", NULL). // OH, UB. Oder wenn Sie zwei Überladungen haben, void f (int); void f (void *); Sie könnten denken, dass f (NULL); Ruft die void * -Version auf, wenn Sie einen kurzen Blick auf den Anruf werfen. f (0); wird die Tatsache dokumentieren, dass es tatsächlich die int-Version aufruft, aber nicht die Tatsache dokumentieren, dass Sie beabsichtigen, einen Zeiger zu übergeben :( Gut, dass nullptr es behebt :)
Johannes Schaub - litb