C中的NULL是否需要/定义为零?

NULL在我的GCCtesting程序中似乎为零,但维基百科说只有NULL指向不可寻址的内存。

任何编译器是否使NULL非零? 我很好奇是否if (ptr == NULL)if (!ptr)更好。

NULL保证为零,也许被转换为(void *) 1

C99,§6.3.2.3,¶3

一个整数常量expression式的值为0 ,或者这样一个expression式转换为void *types,被称为一个空指针常量(55)如果一个空指针常量被转换为一个指针types,结果指针称为空指针,保证比较不等于指向任何对象或函数的指针。

注55说:

55)macrosNULL在<stddef.h> (和其他头文件)中定义为空指针常量。

请注意,由于空指针的规则是如何制定的,所以用来分配/比较空指针的值保证为零,但实际上存储在指针内的位模式可以是任何其他的东西(但AFAIK只有很less深奥的平台利用了这个事实,而且这也不应该成为一个问题,因为无论如何“看到”你应该进入UB的底层位模式)。


因此,就标准而言,这两种forms是等价的(由于第6.5.3.3节, !ptr相当于ptr==0ptr==0相当于ptr==NULL )。 if(!ptr)也相当习惯。

也就是说,我通常会明确地写if(ptr==NULL)而不是if(!ptr) ,以便更清楚地指出我正在检查一个指向if(ptr==NULL)的指针,而不是一些布尔值。


  1. 请注意,在C ++中,由于更严格的隐式转换规则, void *不能存在,因为这会使得使用这种NULL繁琐(您必须每次都将其显式转换为比较指针的types)。

从语言标准来看:

6.3.2.3指针

3值为0的整数常量expression式,或转换为void *types的expression式称为空指针常量55)如果一个空指针常量被转换为一个指针types,那么被调用的空指针所产生的指针将被保证与指向任何对象或函数的指针进行比较。

55)macrosNULL<stddef.h> (和其他头文件)中定义为空指针常量; 见7.17。

给定该语言,macrosNULL 计算为一个零值expression式(或者未修饰的文字0 ,一个expression式(void *) 0或者最终计算为0的另一个macros或expression式)。 expression式ptr == NULL!ptr应该是等价的。 第二种forms往往是更习惯的C代码。

请注意,空指针不一定是0.底层实现可能使用任何值来表示一个空指针。 但是,就你的源代码而言,一个零值指针expression式表示一个空指针。

在实践中是相同的,但NULL不同于零。 由于零表示有一个值,NULL表示没有任何值。 所以,理论上它们是不同的,NULL具有不同的含义,在某些情况下这种差别应该是有用的。

在实践中不,!ptr是正确的