关于c ++:有一个实用的理由使用“if(0 == p)”而不是“if(!p)”吗?

is there a pragmatic reason to use “if (0 == p) ” instead of “if (!p)”?

我倾向于使用逻辑否定运算符编写if语句:

1
2
if (!p)
    some_code();

我周围的一些人倾向于使用显式比较,因此代码看起来像:

1
2
if (FOO == p)
    some_code();

其中foo是false、false、0、0.0、null等之一。

我喜欢简短的表格,因为它是:

  • operator!=友好型
  • generic programming友好型
  • 简洁(对我来说更美)

写这篇文章(如果有的话)的实际好处是什么?


为了对比@erik的答案,我会说使用!来提高可读性。如果你发现你忽视了它,那就去检查你的眼睛。下一步是什么?避免1,改用3-2?


这取决于p代表什么。

如果p代表一个布尔值/逻辑值,那么(!p)似乎最合适-与"假"相比通常是不鼓励的。我不认为这会有什么争论。

如果p代表一个值,比如计数器,那么(p == 0)(0 == p)似乎是合适的。(通常两人之间会有激烈的辩论。我发现第一个更易读,但第二个避免了一些非常严重的错误。)除了两个选项中的哪一个更好,我不认为这是一个辩论(如中所述,它应该与0相比)。

如果p代表一个指针,那么就有一些问题。一个有能力的C++程序员应该知道,EDCOX1 7将告诉你它是否为空。然而,这篇文章的可读性是一个灰色地带,我认为这是一个有争议的争论。


使用(0 == p)(p == 0)以提高可读性。乍一看,!== 0更容易被忽视。

如果您有忽略编译器警告的习惯,并且希望知道何时使用=而不是==,请使用(0 == p)


有人声称,如果你明确地比较NULL、FALSE、0等,程序员会发现它更容易理解,而逻辑运算符可能会让不理解隐式转换和布尔运算在C/C++中如何工作的人感到困惑。

(免责声明:我本人不分享此观点。EDCOX1、0和EDCOX1、1是C和C++中表达的惯用方式,理解困难的程序员不需要触摸C或C++代码。希思·亨尼克特的评论毫无新意。)


if (!Foo)版本的一个尚未提及的好处是,它将与使用安全bool习惯用法的类一起使用。在实现这一点的类中,类的比较运算符将失败(例如,Foo==0将不定义),但!Foo将在foo上调用转换运算符,返回指向成员函数的指针(如果Foo应被视为false,则返回空指针)。许多boost类,比如shared-ptr,都使用这种技术。


就个人而言,我对从int到boolean的隐式转换有点厌烦。我认为它对C语言不再有什么帮助。在没有布尔类型的C89中,使用整数作为布尔值是完全合理的,在这种情况下,转换会导致代码美观。我明白了为什么它不能被删除,尤其是在处理由于兼容性原因不能更改为返回布尔值的库时,现在有了一个。但我当然不认为在所有情况下都应该使用它。

有时,0整数值表示"没有一个",但有时表示"有一个,它是零"。所以我很高兴:

1
2
3
4
5
6
7
users = get_number_of_users();
if (users) {
    // there are users
    ...
} else {
    // there aren't users
}

我一点也不喜欢:

1
2
3
4
5
6
length = strlen(ptr);
if (length) {
    // there is length? OK, sort of...
} else {
    // there isn't length? No, wait, there *is* a length, that length is 0
}

所以你写if (length == 0)if (!length)更为实际。""如果不是长度"在英语中没有意义,那么也不一定要用代码编写什么。

不可否认,0是作为一个特殊的地方持有者被发明的,意思是"没有任何地方"。但是,认识到在许多情况下,它可以被当作一个数字来对待,这是数学史上的一个重要突破,我认为我们不应该仅仅因为C为我们提供了一个语法来重新专门对待它,就放弃它;-)如果你想知道一个数是否是5,你可以将它与5进行比较,通常我会瘦一些。k相同的值应保持为0。


如果语言是c,如果p是指针,那么if(p)和if(!p)应避免。

C(语言)没有指定空指针将是布尔值false。它确实表示,强制转换为指针(隐式或显式)的0将给出空指针。

因此,测试p而不是p==null并不一定是相同的,而且在一些较旧的硬件上,它们肯定是不同的,因为null指针实际上是指向特定内存页的指针。

但是,您可以保证0和因此空值等于空指针,因为C说它们必须是。


我会在前后放置一个空间!:( ! p)所以!脱颖而出。但我将把这种用法限制为只包含指针的整数类型。我将使用==作为浮点,因为它将使您和其他人暂停并思考0.0 == p是否真的适合指定公差。

如果p是一个类的实例,那么应该通过定义操作符来使用( ! p)!避免与0.0 == p的隐式转换。


在非常复杂的条件中,使用显式的==有助于提高可读性。不幸的是,它还打开了写x=0而不是x==0的门,但是您可以通过写0==x来避免这一点(这样0=x将抛出一个错误)。

这也可能是其他语言的习惯,否则你必须强制转换为布尔值。


if (Foo)if (!Foo)似乎暗示Foo是一个布尔变量,至少对我来说是这样。也就是说,只要您的标识符具有足够的描述性,它就真的不重要了。我将在新代码中使用!Foo,但如果有,请遵循现有的约定。一致性胜过一切。


使用if (0 == p),在这种情况下,您强制比较输入"if scope"。我的意思是,很明显你会想这样做,以防p is equals 0。仅仅使用(!p),你想知道的并不明确。可能是null, false等。


我看到的唯一务实的原因是,在第二种情况下,用于比较的值的类型更加明确。foo==空foo是一个ponter类型,!foo不能说它是指针、bool等)