这些空指针,还是地址为0的指针?
如果我写
int zero = 0; void *p1 = (void *)0; void *p2 = (void *)(int)0; void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0); void *p4 = (void *)zero; // For reference, this is a pointer to address zero void *p5 = 0; // For reference, this is a null pointer void *p6 = NULL; // For reference, this is a null pointer void *p7 = nullptr; // For reference, this is a null pointer (C++11) static const int static_zero_1 = 0; // Is this a literal zero when used? static const int static_zero_2 = 1 - 1; // No "literals 0" per se... is it? void *p8 = (void *)static_zero_1; // I have seen weird substitution rules... void *p9 = (void *)static_zero_2; // do they apply for NULL too?
p1
, p2
和p3
哪一个( 编辑:我添加了p8
和p9
)将是空指针 (即== NULL
,可能或可能不是地址零),以及它们中的哪一个是地址为零的指针(可以或可能不是== NULL
)?
如果答案在C和C ++中有所不同,那么它们中的每一个是什么?
p1
和p2
是空指针; p3
是实现定义的,可能是其他的。 (逗号运算符不能是常量表达式的一部分。并且非常量整数值0到指针的映射是实现定义的。)C与此处的C ++相同。
p8
和p9
都是C ++中的空指针,但不是C语言。
关于你对static_zero_2
的评论,在任何一种语言中都没有要求在任何地方都存在文字零。 例如,g ++将NULL
定义为编译器内置的__null
,您可以使用(1 - 1)
或'\0'
,或任何其他常量表达式求值为0。
并用C完成Andy的答案:
从C99标准 :
6.3.2.3指针
1指向void的指针可以转换为指向任何不完整或对象类型的指针。 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针。
3 值为
0
的整型常量表达式或类型为void *
的表达式称为空指针常量 。 55)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较。
因此,任何求值为0
整型常量表达式都是空指针常量,可以转换为NULL
指针。 在你的例子中,除了p4
, p8
和p9
之外的所有指针都是空指针。 p4
, p8
和p9
不需要是空指针,因为它们的初始化不是常量表达式,因为它包含变量(即使const
限定)。
这是关于C ++中NULL
的另一个答案 ,用于记录。
p1
,p2
和p3
哪一个是空指针?
在C ++ 11中,所有这些。 根据C ++ 11标准的第4.10 / 1段:
空指针常量是整数类型的整数常量表达式(5.19)prvalue,其求值为零或者类型为
std::nullptr_t
。 […]
因此,根据标准的术语,作为常量 (整数)表达式并且求值为0
都是空指针常量 (还不是空指针 )。 唯一不是求值为0
的常量表达式或示例中类型为nullptr_t
的prvalue的值zero
,因为它不是常量表达式。
该段继续:
空指针常量可以转换为指针类型; 结果是该类型的空指针值 ,并且可以与对象指针或函数指针类型的每个其他值区分开。 这种转换称为空指针转换 。 相同类型的两个空指针值应相等。
因此在您的示例中,除了p4
之外的所有指针都是空指针值,并且它们之间的比较相等。