tva*_*son 63
是.NULL的计算结果为false,因为C认为任何非零值为true,任何零值为false.NULL本质上是zero地址,并且在比较中被视为这样,我相信将被提升为布尔检查的int.我希望你的代码对任何熟悉C的人都是可读的,尽管我可能会明确地进行检查.
在C和C++编程中,两个空指针保证比较相等; ANSI C保证在与整数类型进行比较时,任何空指针都将等于0; 此外,宏NULL被定义为空指针常量,即值0(作为整数类型或转换为指向void的指针),因此空指针将比较等于NULL.
参考:http://en.wikipedia.org/wiki/Null_pointer#Null_pointer
aka*_*tos 18
假设什么都不安全.
对您正在测试的内容进行明确检查也更清楚.
Han*_*ant 18
'C'语言可以追溯到一个时代,其中(void*)0实际上可以是一个有效的指针.不久之前,8080和Z80微处理器在地址0处有一个中断向量.面对这样的架构选择,除了让头文件声明NULL值之外,它什么也做不了.那里有一些编译器,现在很久就被遗忘了,其中NULL不等于(void*)0(0xffff是下一个选择),因此给出了if()语句未定义的行为.
C++仁慈地结束了这一点,空指针可以从0分配和测试.
是的,if(!p)有效并保证有效。
值为 0 的整型常量表达式或转换为 void * 类型的此类表达式称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与任何对象或函数的指针比较不相等。
https://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p3
这意味着这(void*)0是一个空指针。这也意味着 ifp是指针,则p==0相当于p==(void*)0。
这也意味着 ifp不是空指针,那么p==(void*)0将计算为0。
到目前为止,一切都很好。
将空指针转换为另一种指针类型会生成该类型的空指针。任意两个空指针比较相等。
http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p4
请注意,“任何两个空指针比较都应该相等”。这意味着 ifp是空指针,则将p==0评估为 true,因为0将提升为(void*)0which is 空指针。这也意味着非空指针不能等于空指针。
让我们看一下否定运算符。
逻辑非运算符的结果!如果其操作数的值比较不等于 0,则为 0;如果其操作数的值比较等于 0,则为 1。结果的类型为 int。表达式 !E 等价于 (0==E)。
http://port70.net/~nsz/c/c11/n1570.html#6.5.3.3p5
这告诉我们,与定义!p相同,与上面提到的p==0相同。p==(void*)0
考虑到所有空指针都是相等的事实,这意味着p==(void*)0仅当 是空指针时才能计算为 true p,并且如果p不是空指针则只能计算为 false。
所以是的,if(!p)这是检查是否p为空指针的完全安全的方法。
我的ISO / IEC 9899:TC3(委员会草案,2007年9月7日)副本:
6.3转换
1一些运算符会自动将操作数值从一种类型转换为另一种类型。
6.3.2.3指针
3值为0 [...]的整数常量表达式称为空指针常量。如果将空指针常量转换为指针类型,则保证生成的指针(称为空指针)将不相等的值与指向任何对象或函数的指针进行比较。
到目前为止,ptr!=0对于每个非null来说都是true(1)ptr,但是它仍然是开放的,如何比较两个null指针。
6.5.9平等经营者
5 [...]如果一个操作数是一个指针,另一个是空指针常量,则将空指针常量转换为指针的类型。
6当且仅当两个都是空指针,并且两个都是[...]时,两个指针比较相等
因此,当且仅当为空指针时,它ptr==0是1(并且ptr!=0是0)ptr。
6.5.3.3一元算术运算符
5逻辑求反运算符的结果!如果其操作数的值比较不等于0,则为0;如果其操作数的值比较等于0,则为1。结果的类型为int。表达式!E等效于(0 == E)。
因此对!ptr。
6.8.4.1 if语句
1 if语句的控制表达式应具有标量类型。
2在这两种形式中,如果表达式比较不等于0,则执行第一个子语句。
注意,标量类型是算术类型或指针类型(请参见“ 6.2.5类型”的第21节)。放在一起,我们有:
if (ptr)成功了吗?ptr!=0是1吗?ptr不是空指针。if (!ptr)成功了吗?ptr==0是1吗?ptr是一个空指针。