Perché NULL non è dichiarato?


87

Ho un problema con questo costruttore della struttura quando provo a compilare questo codice:

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 si verifica questo errore:

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

L'ultimo problema era la struttura, 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

Risposte:


139

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

Nel C ++ più recente (C ++ 11 e versioni successive), usa nullptr(come sottolineato in un commento, grazie).

Altrimenti, aggiungi

#include <stddef.h>

per ottenere la NULLdefinizione.


7
NULL fa parte di stddef.h, non stdlib.h. Tecnicamente, non è garantito che lo otterrai come parte di stdlib.h anche se ammetto che sarebbe piuttosto sorprendente se non lo facessi.
CB Bailey,

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

8
<cstddef>è l'opzione più pulita.
Fred Foo

29
NON usare "0" quando intendi "NULL"! C'è una differenza : semantica. Non sottovalutare mai l'importanza di sapere cos'è qualcosa e di usare la parola giusta, anche se il compilatore ti permetterà di farla franca!
imallett

13
@ 6502 Non ne parliamo; 0 e NULL hanno (quasi) sempre lo stesso valore, quindi l'uso di '\ 0' o 0 funzionerà accidentalmente. Il problema è la semantica. L'uso di NULL è più espressivo, poiché dice che il valore è domanda è un puntatore, non solo un numero intero.
imallett

34

Usa NULL. È comunque #definito come 0 ed è molto utile distinguerlo semanticamente dall'intero 0.

Ci sono problemi con l'utilizzo 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 nullptrper risolvere questo problema.

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

5
È definito ((void *)0)dalla maggior parte delle implementazioni di librerie standard C.
Triang3l

1
Questa è la migliore risposta breve (e tecnicamente precisa) che abbia mai letto riguardo all'argomento: NULL vs 0 vs nullptr. Grazie!
jose.angel.jimenez

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

16

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

La definizione di NULLè garantita per essere disponibile se includi cstddefo stddef.h. Non è garantito, ma è molto probabile che la sua definizione venga inclusa se includi invece molte delle altre intestazioni standard.


12

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

#include <stdlib.h>

o

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

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

@awiebe Questo era quello che pensavo fino a cinque minuti fa - secondo C99 alcuni file di intestazione diversi devono definirlo. La sezione 7.17 richiede stddef.h, 7.20 lo richiede in stdlib.h, e probabilmente ce ne sono pochi altri.
AJM-Reinstate-Monica

4

Non usare NULL, C ++ ti consente di usare 0invece il disadorno :

previous = 0;
next = 0;

E, come in C ++ 11, in genere non dovresti usare nessuno dei due NULL o 0 poiché ti fornisce il nullptrtipo std::nullptr_t, che è più adatto all'attività.


33
Tendo a pensare che NULL sia una documentazione utile che intendi utilizzare una costante puntatore nullo piuttosto che una costante intera, anche se non mi oppongo all'utilizzo di 0. Ammetto che al momento non ottieni alcun vantaggio pratico , ma se / quando si adotta la prossima versione C ++ è un buon inizio per i luoghi da cambiare per utilizzare la nuova costante nullptr.
CB Bailey,

1
Sono d'accordo con entrambi, ovviamente. Per inciso, è sia bene che uno documenti si usi un puntatore, ma anche che si documenti un numero intero in realtà. considera printf ("% p \ n", NULL); // OH, UB. O se hai due sovraccarichi, void f (int); void f (void *); potresti pensare che f (NULL); chiama la versione void * quando si dà 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
risolva
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.