2009-05-29 13 views
64

Ho un problema con questo struct contructor quando provo a compilare questo codice:Perché NULL non è dichiarato?

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

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

quando vengo questo errore si verifica:

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

Ultimo problema era la struct, ma ha funzionato bene quando era nel mio main.cpp, questa volta è in un file di intestazione e mi sta dando questo problema. Sto usando Code :: Blocks per compilare questo codice

risposta

9

Stai includendo "stdlib.h" o "cstdlib" in questo file? NULL è definita in stdlib.h/cstdlib

#include <stdlib.h> 

o

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

NULL fa parte di stddef.h, non stdlib.h – awiebe

104

NULL non è una costante incorporata nella linguaggi C o C++. Infatti, in C++ è più o meno obsoleto, basta usare un semplice letterale 0 invece, il compilatore farà la cosa giusta a seconda del contesto.

Nel nuovo C++ (C++ 11 e versioni successive), utilizzare nullptr (come indicato in un commento, grazie).

In caso contrario, aggiungere

#include < stddef.h >

per ottenere la definizione NULL.

+6

NULL fa parte di stddef.h, non stdlib.h.Tecnicamente, non sei sicuro di averlo come parte di stdlib.h, anche se ammetto che sarebbe piuttosto sorprendente se non lo facessi. –

+6

NULL è definito nelle seguenti intestazioni C: stddef.h, stdlib.h, stdio.h, locale.h, string.h e time.h (e wchar.h se si conta C99). –

+0

OK, sono corretto. Mi chiedo perché C++ abbia bisogno di menzionare esplicitamente il contenuto di cstddef e non le altre intestazioni. Forse è considerato il luogo canonico "C++" per NULL, mentre le altre posizioni sono per la compatibilità C? –

14

NULL non è una parte nativa del linguaggio C++ principale, ma fa parte della libreria standard. È necessario includere uno dei file di intestazione standard che include la sua definizione. #include <cstddef> o #include <stddef.h> dovrebbero essere sufficienti.

La definizione di NULL è garantita per essere disponibile se si include cstddef o stddef.h. Non è garantito, ma è molto probabile che venga inclusa la sua definizione se si includono invece molte altre intestazioni standard.

5

Non utilizzare NULL, C++ consente di utilizzare la disadorna 0 invece:

previous = 0; 
next = 0; 

E, come in C++ 11, in genere non dovrebbe essere utilizzando NULLo0 dal ti fornisce nullptr di tipo std::nullptr_t, che è più adatto all'attività.

+28

Tendo a pensare che NULL sia una documentazione utile che si intenda utilizzare una costante puntatore nullo piuttosto che una costante intera, anche se non obietto all'uso di 0. Ammetto che non si ottengono vantaggi pratici momento, ma se/quando si adotta la prossima versione C++ dà un buon inizio per i luoghi da cambiare per usare la nuova costante nullptr. –

+1

Sono d'accordo con entrambi, naturalmente. Per inciso, è positivo che un documento utilizzi un puntatore, ma anche un buon documento che in realtà metta un intero in avanti. considera printf ("% p \ n", NULL); // OH, UB. Oppure se hai due sovraccarichi, void f (int); void f (void *); potresti pensare che f (NULL); chiama la versione void * quando ha una rapida occhiata alla chiamata. f (0); documenterà il fatto che chiamerà effettivamente la versione int, ma non documenterà il fatto che intendi passare un puntatore :(Bene che nullptr lo aggiusta :) –

29

Utilizzare NULL. È solo # definito come 0 ed è molto utile distinguerlo semanticamente dal numero intero 0.

Ci sono problemi con l'uso di 0 (e quindi NULL). Per esempio:

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

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

La prossima versione di C++ (C++ 0x) include nullptr per risolvere questo problema.

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

È definito come '((void *) 0)' da la maggior parte delle implementazioni di libreria standard C. – Triang3l

+1

Questa è la migliore ** risposta ** breve (e tecnicamente precisa) che abbia mai letto sull'argomento: NULL vs. 0 vs. nullptr. Grazie! –

+1

@SiPlus '((void *) 0)' non è corretto in C++, perché 'void *' non è coercibile ad altri tipi di puntatori come in C. glibc, ad esempio, '#define NULL 0' quando' __cplusplus' è definito. – rpjohnst

Problemi correlati