在我的GCC测试程序中,NULL似乎为零,但维基百科说NULL
只需要指向无法寻址的内存。
是否有任何编译器使NULL
非零?我很好奇if (ptr == NULL)
是否比if (!ptr)
更好。
答案 0 :(得分:63)
NULL
保证为零,可能会投放到(void *)
1 。
C99,§6.3.2.3,¶3
具有值
0
的整型常量表达式,或者此类表达式转换为类型void *
,称为空指针常量。(55)如果将空指针常量转换为a 指针类型,结果指针,称为空指针,保证比较不等 指向任何对象或函数的指针。
并注意55:
55)宏NULL在
<stddef.h>
(和其他标题)中定义为空指针常量。
请注意,由于如何制定空指针的规则,用于分配/比较空指针的值保证为零,但实际存储在指针内的位模式可以是任何其他东西(但AFAIK)只有少数非常深奥的平台利用了这个事实,这不应该是一个问题,因为要“看到”你应该进入UB - 土地的基础位模式。
因此,就标准而言,这两种形式是等价的(!ptr
相当于ptr==0
,因为§6.5.3.3¶5,而ptr==0
相当于ptr==NULL
); if(!ptr)
也非常惯用。
话虽如此,我通常会明确地写if(ptr==NULL)
而不是if(!ptr)
,以使我更清楚地知道我正在检查指针是否为无效而不是某个布尔值。
void *
强制转换不能出现,因为更严格的隐式强制转换规则会使这种NULL
的使用变得繁琐(您必须将其显式转换为比较指针的类型)每一次)。答案 1 :(得分:11)
来自语言标准:
6.3.2.3指针
...
3一个整数常量表达式,其值为0,或者此类表达式强制转换为类型void *
,称为空指针常量。 55)如果将空指针常量转换为a 指针类型,结果指针,称为空指针,保证比较不等 指向任何对象或功能的指针 ...
55)宏NULL
在<stddef.h>
(和其他标题)中定义为空指针常量;见7.17。
鉴于该语言,宏NULL 应评估为零值表达式(未修饰的文字0
,类似(void *) 0
的表达式,或其他宏或表达式最终评估为0)。表达式ptr == NULL
和!ptr
应该是等效的。第二种形式往往是更惯用的C代码。
请注意,空指针值不必为0.底层实现可以使用它想要表示空指针的任何值。但是,就源代码而言,零值指针表达式表示空指针。
答案 2 :(得分:3)
在实践中是相同的,但NULL与零不同。因为零意味着有一个值而NULL意味着没有任何值。因此,从理论上讲它们是不同的,NULL具有不同的含义,在某些情况下,差异应该是有用的。
答案 3 :(得分:2)
在实践中没有,!ptr是正确的