2009-05-29 3 views
64

У меня есть проблема с этим STRUCT застройщик, когда я пытаюсь скомпилировать этот код:Почему NULL не объявлен?

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, чтобы скомпилировать этот код

ответ

9

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

#include <stdlib.h> 

или

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

NULL является частью stddef.h, не stdlib.h – awiebe

104

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

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

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

#include < stddef.h >

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

+6

NULL является частью stddef.h, не stdlib.h.Технически, вы не гарантируете, что получите его как часть stdlib.h, хотя я признаю, что это было бы очень сюрпризом, если бы вы этого не сделали. –

+6

NULL определяется в следующих заголовках C: stddef.h, stdlib.h, stdio.h, locale.h, string.h и time.h (и wchar.h, если вы считаете C99). –

+0

ОК, я стою исправлено. Интересно, почему C++ должен явно указывать содержимое cstddef, а не другие заголовки. Возможно, это считается каноническим местом «C++» для NULL, тогда как другие местоположения предназначены для совместимости с C? –

14

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

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

5

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

previous = 0; 
next = 0; 

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

+28

Я склонен думать, что NULL - полезная документация, в которой вы намерены использовать константу нулевого указателя, а не целочисленную константу, хотя я не возражаю против использования 0. Я признаю, что вы не получаете каких-либо практических преимуществ на момент, но если/когда вы примете следующую версию C++, это даст хороший старт для мест, которые нужно изменить, чтобы использовать новую константу nullptr. –

+1

Я согласен с вами обоими, конечно. Кстати, хорошо, что в одном документе используется указатель, но также и хороший документ, который фактически переносит целое число вперед. рассмотрим printf ("% p \ n", NULL); // OH, UB. Или, если у вас две перегрузки, void f (int); void f (void *); вы можете подумать, что f (NULL); вызывается версия void * при быстром просмотре вызова. F (0); будет документировать факт, что он фактически вызовет версию int, но не будет документировать факт, что вы намерены передать указатель :(Хорошо, что nullptr исправляет его :) –

29

Используйте NULL. Это просто #defined как 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*). 
+3

Он определяется как '((void *) 0)' by большинство реализаций библиотек C. – Triang3l

+1

Это лучший ** короткий ** ответ (и технически точный), который я когда-либо читал по теме: NULL против 0 против nullptr. Спасибо! –

+1

@SiPlus '((void *) 0)' неверно в C++, потому что 'void *' не является принудительным для других типов указателей, так как он находится в C. glibc, например, '#define NULL 0', когда' __cplusplus'. – rpjohnst

Смежные вопросы