Почему NULL не объявлен?

87

У меня проблема с этим конструктором структуры, когда я пытаюсь скомпилировать этот код:

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

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

когда я прихожу, возникает эта ошибка:

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

Последней проблемой была структура, но она работала нормально, когда она была в моем main.cpp, на этот раз она находится в файле заголовка и вызывает у меня эту проблему. Я использую Code :: Blocks для компиляции этого кода

размотать
источник

Ответы:

139

NULLне является встроенной константой в языках C или C ++. Фактически, в C ++ он более или менее устарел, просто используйте 0вместо него простой литерал , компилятор будет делать правильные вещи в зависимости от контекста.

В более новом C ++ (C ++ 11 и выше) используйте nullptr(как указано в комментарии, спасибо).

В противном случае добавьте

#include <stddef.h>

чтобы получить NULLопределение.

размотать
источник
7
NULL является частью stddef.h, а не stdlib.h. Технически вам не гарантировано получить его как часть stdlib.h, хотя я признаю, что было бы довольно удивительно, если бы вы этого не сделали.
CB Bailey
8
NULL определен в следующих заголовках C: stddef.h, stdlib.h, stdio.h, locale.h, string.h и time.h (и wchar.h, если вы считаете C99).
Майкл Берр,
8
<cstddef>это более чистый вариант.
Fred Foo,
29
НЕ используйте «0», когда вы имеете в виду «NULL»! Есть разница : семантика. Никогда не недооценивайте важность знания того, что что-то такое, и использования правильного слова, даже если компилятор позволит вам избежать неприятностей!
imallett 07
13
@ 6502 Не об этом; 0 и NULL всегда имеют одно и то же значение (почти), поэтому использование '\ 0' или 0 может случайно сработать. Проблема в семантике. Использование NULL более выразительно, поскольку оно говорит, что значение является указателем, а не просто целым числом.
imallett
34

Используйте NULL. В любом случае это просто # определено как 0, и очень полезно семантически отличать его от целого числа 0.

Есть проблемы с использованием 0 (и, следовательно, NULL). Например:

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

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

Следующая версия C ++ (C ++ 0x) включает nullptrисправление этого.

f(nullptr); // Calls f(void*).
Эрик
источник
5
Он определяется как ((void *)0)большинство реализаций стандартной библиотеки C.
Triang3l
1
Это лучший короткий ответ (и технически точный), который я когда-либо читал по теме: NULL vs. 0 vs. nullptr. Спасибо!
jose.angel.jimenez
2
@SiPlus ((void *)0)неверен в C ++, потому что void*не может быть приведен к другим типам указателей, как, например, в C. glibc, #define NULL 0когда __cplusplusон определен.
rpjohnst 08
16

NULLне является встроенной частью основного языка C ++, но является частью стандартной библиотеки. Вам необходимо включить один из стандартных файлов заголовков, которые включают его определение. #include <cstddef>или #include <stddef.h>должно хватить.

NULLЕсли вы включите cstddefили, то определение будет доступно stddef.h. Это не гарантируется, но вы, скорее всего, получите его определение, если вместо этого включите многие другие стандартные заголовки.

CB Bailey
источник
12

Вы включаете в этот файл "stdlib.h" или "cstdlib"? NULL определен в stdlib.h / cstdlib

#include <stdlib.h>

или

#include <cstdlib>  // This is preferrable for c++
Энди Уайт
источник
2
NULL является частью stddef.h, а не stdlib.h
awiebe
@awiebe Это то, о чем я думал еще пять минут назад - согласно C99, довольно много разных файлов заголовков должны определять это. Раздел 7.17 требует stddef.h для, 7.20 требует его в stdlib.h, и, вероятно, есть несколько других.
AJM-Reinstate-Monica,
4

Не используйте NULL, C ++ позволяет 0вместо этого использовать неприукрашенное :

previous = 0;
next = 0;

И, как и в C ++ 11, вам обычно не следует использовать ни NULL или, 0 поскольку он предоставляет вам nullptrтип std::nullptr_t, который лучше подходит для данной задачи.

Paxdiablo
источник
33
Я склонен думать, что NULL - это полезная документация о том, что вы собираетесь использовать константу нулевого указателя, а не целочисленную константу, хотя я не возражаю против использования 0. Я признаю, что в настоящее время вы не получаете никаких практических преимуществ , но если / когда вы примете следующую версию C ++, это даст хороший старт местам, которые нужно изменить, чтобы использовать новую константу nullptr.
CB Bailey
1
Я, конечно, согласен с вами обоими. Между прочим, хорошо и то, что в одном документе используется указатель, и хорошо, когда в документе указывается целое число. рассмотрим printf ("% p \ n", NULL); // ОН, УБ. Или, если у вас есть две перегрузки, void f (int); void f (недействительно *); вы можете подумать, что f (NULL); вызывает версию void * при быстром просмотре вызова. f (0); документирует тот факт, что он действительно вызывает версию int, но не документирует тот факт, что вы намереваетесь передать указатель :( Хорошо, что nullptr исправляет это :)
Йоханнес Шауб - litb