是否有一个实用的理由使用“if(0 == p)”而不是“if(!p)”?

时间:2011-03-03 22:59:19

标签: c++ coding-style

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

if (!p)
    some_code();

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

if (FOO == p)
    some_code();

其中FOO是 false FALSE 0 0.0 NULL 等等。

我更喜欢简短形式,因为它是:

  • operator!=友好
  • generic programming友好
  • 简洁(甚至更美丽,对我而言)

除此之外(如果有的话)写这个实用有什么好处?

12 个答案:

答案 0 :(得分:24)

要对比@Erik's answer,我会说使用!来提高可读性。如果你发现你正在俯瞰它,那就试试你的眼睛吧。下一步是什么?避免1,改用3 - 2?

答案 1 :(得分:12)

使用(0 == p)(p == 0)提高可读性。乍一看,!== 0

更容易被忽视

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

答案 2 :(得分:12)

这取决于p代表什么。

如果p表示布尔/逻辑值,则(!p)似乎最合适 - 通常不鼓励使用“FALSE”。我不认为这有太大的争议。

如果p代表一个值,就像一个计数器,那么(p == 0)(0 == p)似乎是合适的。 (两者之间通常存在激烈的争论。我发现第一个更具可读性,但第二个避免了一些非常严重的错误。)除了两个选项中哪一个更好,我不认为这是一个辩论(如在,它应该与0比较。)

如果p表示指针,那么您有一些问题。一个称职的C ++程序员应该知道(!p)会告诉你它是否为空。然而,这种可读性的想法是一个灰色地带,我认为这是一个备受争议的争论。

答案 3 :(得分:8)

有些人声称,实用的好处是,如果你明确地与NULL,FALSE,0等进行比较,程序员会发现它更容易理解,而逻辑运算符可能会让那些不了解隐含的人感到困惑。转换和布尔值在C / C ++中工作。

(免责声明:我自己并不赞同这种观点。if (p) ...if (!p)...是用C和C ++表达这种观点的惯用方法,而那些无法理解它们的程序员也没有业务触摸C或C ++代码.Heath Hunnicutt的评论已经死了。)

答案 4 :(得分:2)

就个人而言,我对从int到boolean的隐式转换感到有点厌倦。我认为它不再对C语言增加太多。在没有布尔类型的C89中,使用整数作为布尔值是完全合理的,在这种情况下,转换会产生漂亮的代码。我明白为什么它不能被删除,特别是在处理库时出于兼容性原因无法更改为返回布尔值现在有一个。但我当然不认为它应该在所有情况下使用。

有时,0整数值表示“没有一个”,但有时它表示“有一个且它为零”。所以我很满意:

users = get_number_of_users();
if (users) {
    // there are users
    ...
} else {
    // there aren't users
}

我一点都不热衷于:

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进行比较,通常我认为同样应该为0。

答案 5 :(得分:2)

if (!Foo)版本的一个尚未提及的好处是它可以与使用safe bool idiom的类一起使用。在实现它的类中,类的比较运算符将失败(例如Foo==0将是未定义的)但!Foo将在Foo上调用转换运算符,返回指向成员函数的指针(或空指针,如果{ {1}}应视为错误)。许多Boost类,比如shared_ptr,都使用这种技术。

答案 6 :(得分:1)

在一个非常复杂的条件中,使用显式==可以帮助使其更具可读性。不幸的是,它也打开了写x = 0而不是x == 0的大门,但你可以通过写0 == x来避免这种情况(所以0 = x会引发错误)。

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

答案 7 :(得分:1)

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

如果p是类的实例,则定义运算符应使用( ! p)!避免使用0.0 == p隐式转换。

答案 8 :(得分:1)

如果语言是C并且p是指针,则应该避免(p)和if(!p)。

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

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

但是你可以保证0,因此NULL等于空指针,因为C表示它们必须是。

答案 9 :(得分:0)

我看到的唯一实用的原因是在第二种情况下,考虑用于比较的值的类型更明确(es.foo == null foo是一种ponter类型,!foo不能说它是否是指针,布尔等等)

答案 10 :(得分:0)

使用 if (0 == p) ,强制比较在这种情况下输入“if scope”。我的意思是,很明显,如果 p is equals 0 ,您希望这样做。只需使用 (!p) 就可以了解您想要了解的内容。它可以是 null, false 等。

答案 11 :(得分:0)

if (Foo)if (!Foo)似乎暗示Foo是一个布尔变量,至少对我而言。话虽如此,只要您的标识符具有足够的描述性,它确实无关紧要。我会将!Foo用于新代码,但如果有的话,请遵循现有的约定。一致性胜过一切。