2009-05-29 10 views
64

Mam problem z tym struct contructor gdy próbuję skompilować ten kod:Dlaczego NULL jest niezadeklarowany?

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

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

kiedy przyjdzie ten błąd:

\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 ===| 

Ostatni problem to struktura, ale to działało dobrze, gdy to było w moim main.cpp, tym razem jest w pliku nagłówkowym i daje mi ten problem. Używam Code :: Blocks do kompilacji tego kodu

Odpowiedz

9

Czy w tym pliku wpisujesz "stdlib.h" lub "cstdlib"? NULL jest zdefiniowane w stdlib.h/cstdlib

#include <stdlib.h> 

lub

#include <cstdlib> // This is preferrable for c++ 
+1

NULL jest częścią stddef.h nie stdlib.h – awiebe

104

NULL nie jest wbudowana stała w C lub C++ językach. W rzeczywistości, w C++ jest mniej lub bardziej przestarzały, wystarczy użyć zwykłego literału 0 zamiast tego, kompilator zrobi to, co trzeba, w zależności od kontekstu.

W nowszym C++ (C++ 11 i wyżej), użyj nullptr (jak wskazano w komentarzu, dziękuję).

przeciwnym razie dodać

#include < stddef.h >

aby uzyskać definicję NULL.

+6

NULL jest częścią stddef.h nie stdlib.h.Technicznie rzecz biorąc, nie masz gwarancji, że dostaniesz go jako część stdlib.h, chociaż przyznaję, że byłoby całkiem zaskakujące, gdybyś tego nie zrobił. –

+6

NULL jest zdefiniowany w następujących nagłówkach C: stddef.h, stdlib.h, stdio.h, locale.h, string.h i time.h (i wchar.h jeśli zliczono C99). –

+0

OK, poprawiam się. Zastanawiam się, dlaczego C++ musi jawnie wymieniać zawartość cstddef, a nie inne nagłówki. Być może jest uważane za kanoniczne miejsce "C++" dla NULL, podczas gdy inne lokalizacje są kompatybilne z C? –

14

NULL nie jest natywną częścią podstawowego języka C++, ale jest częścią standardowej biblioteki. Musisz dołączyć jeden ze standardowych plików nagłówkowych, które zawierają jego definicję. #include <cstddef> lub #include <stddef.h> powinny wystarczyć.

Ta definicja NULL jest dostępna, jeśli podasz cstddef lub. Nie jest to gwarantowane, ale najprawdopodobniej otrzymasz jego definicję, jeśli zamiast tego umieścisz wiele innych standardowych nagłówków.

5

Nie używaj NULL, C++ pozwala korzystać z surową 0 zamiast:

previous = 0; 
next = 0; 

I, jak w C++ 11, generalnie nie powinno być przy użyciu NULLlub0 ponieważ zapewnia on nullptr typu std::nullptr_t, który lepiej pasuje do zadania.

+28

Uważam, że NULL jest użyteczną dokumentacją, że zamierzasz używać stałej wskaźnika pustego zamiast stałej całkowitej, chociaż nie sprzeciwiam się użyciu 0. Przyznaję, że nie zyskujesz żadnych praktycznych korzyści w moment, ale jeśli przyjmiesz następną wersję C++, daje dobry początek miejsc do zmiany, aby użyć nowej stałej nullptr. –

+1

Oczywiście zgadzam się z wami. Nawiasem mówiąc, to dobrze, że jeden dokument używa wskaźnika, ale także jeden dobry dokument, który faktycznie podaje liczbę całkowitą do przodu. rozważ printf ("% p \ n", NULL); // OH, UB. Lub jeśli masz dwa przeciążenia, void f (int); void f (void *); możesz myśleć, że f (NULL); wywołuje wersję void *, gdy ma szybki podgląd połączenia. f (0); udokumentuje fakt, że faktycznie wywoła wersję int, ale nie będzie dokumentować faktu, że zamierzasz podać wskaźnik :(Dobrze, że nullptr to naprawia :) –

29

Należy użyć wartości NULL. Jest to # zdefiniowane jako 0 mimo to i bardzo przydatne jest semantyczne odróżnienie go od liczby całkowitej 0.

Występują problemy z używaniem 0 (a zatem NULL). Na przykład:

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

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

Kolejna wersja C++ (C++ 0x) zawiera nullptr aby rozwiązać ten problem.

f(nullptr); // Calls f(void*). 
+3

Jest zdefiniowany jako '((void *) 0)' przez większość standardowych implementacji biblioteki. – Triang3l

+1

To jest najlepsza ** krótka ** odpowiedź (i technicznie dokładna), jaką kiedykolwiek przeczytałem odnośnie tematu: NULL vs. 0 vs. nullptr. Dziękuję Ci! –

+1

@SiPlus '((void *) 0)' jest niepoprawne w C++, ponieważ 'void *' nie jest przystosowane do innych typów wskaźników, tak jak jest w C. glibc, na przykład, '#define NULL 0' when' __cplusplus' jest zdefiniowany. – rpjohnst

Powiązane problemy