7

在测试时NULL,我看到很多代码使用!var. 是否有理由使用这种测试而不是更明确的var == NULL. 同样,if (var)对于非空项目是否是正确的测试?

4

4 回答 4

11

和...之间的不同:

!var

var == NULL

var在第二种情况下,如果不是指针类型并且NULL使用强制转换(如 )定义,编译器必须发出诊断(void *) 0

此外(正如评论中的@bitmask 所指出的那样)要使用NULL宏,您需要包含一个定义NULL宏的标准标头。在 C 中,NULL为方便起见,宏在多个标题中定义(如stddef.hstdio.hstdlib.hstring.h等)。

否则,这两种表达方式是等价的,只是口味问题。使用你觉得更舒服的那个。

对于您的第二个问题,与上面提到的区别if (var)相同if (var != NULL)

于 2012-09-30T19:38:05.937 回答
3

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). 这些规则的基本原理是更具可读性的代码。无论如何,它都会转换为相同的机器代码,因此使您的代码更易于阅读是没有害处的。

于 2012-09-30T20:48:30.823 回答
2

ISO/IEC 9899标准规定:

  1. 就语言而言:具有 value 的整数常量表达式0,或转换为 type 的此类表达式void *称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与指向任何对象或函数的指针不相等。

  2. 从库开始:NULL是一个扩展为实现定义的空指针常量的宏。

这意味着您给出的表达式同样“正确”。偏爱一种形式而不是另一种形式的原因主要是品味问题。

于 2012-09-30T19:44:31.683 回答
2

来自 C 标准:

算术类型和指针类型统称为标量类型

一元 + 或 - 运算符的操作数应具有算术类型;~ 运算符,整数类型;的 !运算符,标量类型。

逻辑否定运算符的结果!如果其操作数的值比较不等于 0,则为 0,如果其操作数的值比较等于 0,则为 1。结果的类型为 int。表达式 !E 等价于 (0==E)。

所以,这应该回答你的问题。

于 2012-09-30T19:48:00.700 回答