在测试时NULL
,我看到很多代码使用!var
. 是否有理由使用这种测试而不是更明确的var == NULL
. 同样,if (var)
对于非空项目是否是正确的测试?
4 回答
和...之间的不同:
!var
和
var == NULL
var
在第二种情况下,如果不是指针类型并且NULL
使用强制转换(如 )定义,编译器必须发出诊断(void *) 0
。
此外(正如评论中的@bitmask 所指出的那样)要使用NULL
宏,您需要包含一个定义NULL
宏的标准标头。在 C 中,NULL
为方便起见,宏在多个标题中定义(如stddef.h
、stdio.h
、stdlib.h
、string.h
等)。
否则,这两种表达方式是等价的,只是口味问题。使用你觉得更舒服的那个。
对于您的第二个问题,与上面提到的区别if (var)
相同if (var != NULL)
。
var == NULL 版本有一个主要优点:它使编译器和静态分析器可以找到一个特定的常见错误。
假设“var”不是指针,而是分配的变量。if(!var)
那么将是一个未被发现的错误。
NULL 通常被声明为#define NULL ((void*)0)
. 该声明不是标准的强制性声明,而是最常见的声明之一。具有半体面类型检查的编译器将能够对如下代码产生警告:
int var = ...;
if(var == NULL) // compiler warning, var is not a pointer
除了上述优点之外,不使用!
运算符在风格上也是正确的,因为它是一个逻辑运算符,旨在用于布尔变量,而不是指针。它之所以有效,是因为 C 没有强类型。
我建议在这件事上遵循 MISRA-C,它规定对 NULL 或零的检查应该明确。if(x != NULL)
而不是if(x)
. 这些规则的基本原理是更具可读性的代码。无论如何,它都会转换为相同的机器代码,因此使您的代码更易于阅读是没有害处的。
ISO/IEC 9899标准规定:
就语言而言:具有 value 的整数常量表达式
0
,或转换为 type 的此类表达式void *
称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与指向任何对象或函数的指针不相等。从库开始:
NULL
是一个扩展为实现定义的空指针常量的宏。
这意味着您给出的表达式同样“正确”。偏爱一种形式而不是另一种形式的原因主要是品味问题。
来自 C 标准:
算术类型和指针类型统称为标量类型。
一元 + 或 - 运算符的操作数应具有算术类型;~ 运算符,整数类型;的 !运算符,标量类型。
逻辑否定运算符的结果!如果其操作数的值比较不等于 0,则为 0,如果其操作数的值比较等于 0,则为 1。结果的类型为 int。表达式 !E 等价于 (0==E)。
所以,这应该回答你的问题。