来自C17草案(6.3.2.3 ¶3):
值为0的整数常量表达式,或将这样的表达式强制转换为类型
void *
,被称为空指针常量67)。如果将空指针常量转换为指针类型,则所得到的指针,称为空指针,保证与任何对象或函数的指针比较时都不相等。67)宏
NULL
在<stddef.h>
(和其他头文件)中被定义为一个空指针常量[...]。
由此可见,以下是空指针常量:0
、0UL
、(void *)0
、(void *)0UL
、NULL
。
(int *)0
,(int *)0UL
,(int *)(void *)0
,(int *)(void *)0UL
,(int *)NULL
。有趣的是,这些都不是“空指针常量”;请参阅here。以下的空指针常量是空指针(因为
void *
是一个指针类型,0
和0UL
是空指针常量):(void *)0
,(void *)0UL
。关于这一点,根据C17草案(6.2.5 ¶19-20):
void
类型包括一组空值;它是一个不完整的对象类型,无法完成。
[...]
指针类型可以从函数类型或对象类型派生出来,称为引用类型。[...] 指针类型是一个完整的对象类型。
void
本身不是指针类型,它是一个不完全的对象类型。但是void *
是一个指针类型。
但是以下似乎是空指针常量,但并非空指针(因为没有将其强制转换为指针类型):0
,0UL
,NULL
。(准确地说,虽然标准只要求将NULL
定义为“空指针常量”,但也可以将其定义为既是空指针常量又是空指针的情况。但是似乎标准并不要求NULL
以同时是空指针的方式进行定义。)
每个空指针常量都是空指针吗?(NULL
真的不是空指针吗?)
nullptr
来自 C23。关键字 nullptr 表示预定义的空指针常量。它是 nullptr_t 类型的非左值。nullptr 可以转换为指针类型或 bool 类型,其中结果分别为该类型的空指针值或 false。 - Ayxan HaqverdiliNULL
传递给可变参数函数时,例如execl()
中的最后一个参数,应该将其转换为指针类型的原因。 - Barmar