为什么未声明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来编译此代码

Answers:


139

NULL不是C或C ++语言中的内置常量。实际上,在C ++中,它或多或少已经过时了,仅使用简单的文字即可0,编译器将根据上下文执行正确的操作。

在较新的C ++(C ++ 11和更高版本)中,请使用nullptr(如注释中所指出,谢谢)。

否则,添加

#include <stddef.h>

得到NULL定义。


7
NULL是stddef.h的一部分,而不是stdlib.h。从技术上讲,您不能保证将其作为stdlib.h的一部分获得,尽管我承认,如果您不这样做,将非常令人惊讶。
CB Bailey 2009年

8
在以下C标头中定义了NULL:stddef.h,stdlib.h,stdio.h,locale.h,string.h和time.h(如果计数C99,则为wchar.h)。
Michael Burr

8
<cstddef>是更清洁的选项。
弗雷德·富

29
当您表示“ NULL”时,请勿使用“ 0”!有一个区别:语义。即使编译器会让您脱颖而出,也永远不要低估了解内容和使用正确单词的重要性!
imallett

13
@ 6502不是在说那个;0和NULL总是(几乎)具有相同的值,因此使用'\ 0'或0将偶然起作用。问题是语义。使用NULL更具表达性,因为它表示值是问题是一个指针,而不仅仅是一个整数。
imallett

34

请使用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*).

5
((void *)0)由大多数C标准库实现定义。
Triang3l 2013年

1
这是我所读过的关于该主题的最佳简短答案(技术上也是精确的):NULL vs. 0 vs. nullptr。谢谢!
jose.angel.jimenez 2014年

2
@SiPlus((void *)0)在C ++中是不正确的,因为void*它不能像在C中那样强制转换为其他指针类型。例如,glibc#define NULL 0__cplusplus定义时执行。
rpjohnst

16

NULL不是核心C ++语言的本机部分,但它是标准库的一部分。您需要包括一个包含其定义的标准头文件之一。#include <cstddef>#include <stddef.h>应该足够。

NULL如果包含cstddef或,则保证可以使用的定义stddef.h。不能保证,但是如果包含许多其他标准标头,则很有可能将其定义包括在内。


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设置为stddef.h,7.20节在stdlib.h中要求使用它,并且可能还有很多其他内容。
AJM-恢复莫妮卡

4

不要使用NULLC ++,您可以使用无装饰的0代替:

previous = 0;
next = 0;

而且,就像在C ++ 11上一样,您通常不应该使用或者NULL 0因为它为您提供nullptr了type std::nullptr_t,它更适合于该任务。


33
我倾向于认为NULL是有用的文档,您打算使用空指针常量而不是整数常量,尽管我不反对使用0。我承认您目前没有获得任何实际好处。 ,但如果/当您采用下一个C ++版本时,它为更改位置以使用新的nullptr常量提供了一个良好的开端。
CB Bailey

1
我当然同意你们俩。顺便说一句,一个文档使用一个指针是很好的,但是一个文档实际上是将一个整数放在了前面也很好。考虑printf(“%p \ n”,NULL); //哦,UB。或者,如果有两个重载,则使f(int); 无效f(void *); 您可能会认为f(NULL); 快速查看通话时,调用void *版本。f(0); 将记录一个事实,它将实际调用int版本,但不会记录您打算传递一个指针的事实:(很好的是nullptr修复了它:)
Johannes Schaub-litb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.