【问题标题】:What is the difference between if (NULL == pointer) vs if (pointer == NULL)?if (NULL == pointer) 与 if (pointer == NULL) 有什么区别?
【发布时间】:2014-02-28 22:04:54
【问题描述】:

使用有什么区别:

if (NULL == pointer) 

并使用:

if (pointer == NULL)    

我的教授说要使用前者而不是后者,但我看不出两者之间的区别。

【问题讨论】:

  • 没有区别。
  • 你需要犯标准的新手错误并使用 = 而不是 ==
  • 前者丑陋而烦人,并且被体面的工具完全不需要。
  • 你也可以把你的教授介绍给if (!pointer)
  • FWIW,即使在与新手无关的代码中,我仍然偶尔会发现 if (pointer=NULL) ... 错误。出于某种原因,工具并不总是用来抱怨这些错误的实例。然而,我也发现if (NULL==pointer) ... 太丑了,以至于我仍然不使用它,即使是为了防止那些错字错误。我个人的偏好是 jrok 的建议:if (!pointer).

标签: c++ coding-style conditional-statements


【解决方案1】:

没有区别。你的教授喜欢的叫Yoda conditions,另见"Yoda Conditions", "Pokémon Exception Handling" and other programming classics

它应该防止在比较中错误地使用赋值(=)而不是相等(==),但是现代编译器现在应该警告这一点,所以这种类型的防御性编程不应该是必要的。例如:

if( pointer = NULL )

当程序员真正的意思是:

if( pointer == NULL )

这应该是一个比较,哎呀。使用 Yoda 条件 将其设为错误 (see it live),并显示与此类似的消息:

错误:表达式不可赋值

正如 jrok 指出的那样:

if (!pointer)

在这种情况下一起避免了这个问题。

这是一个具体的例子,说明为什么现代编译器不再需要这种技术(see it live):

#include <iostream>

int main()
{
    int *ptr1 = NULL ;

    if( ptr1 = NULL )
    {
            std::cout << "It is NULL" << std::endl ;
    }

}

注意所有警告:

warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
    if( ptr1 = NULL )
        ~~~~~^~~~~~

note: place parentheses around the assignment to silence this warning
    if( ptr1 = NULL )
             ^
        (          )

use '==' to turn this assignment into an equality comparison
    if( ptr1 = NULL )
             ^
             ==

这使得很难错过这个问题。值得注意的是,在 C++nullptr 应该优先于NULL,您可以查看What are the advantages of using nullptr? 了解所有详细信息。

注意,在 C++ 中,运算符重载的不太可能的情况是可能存在一些人为的情况,它们并不相同。

注意,-Wparentheses warning 在某些方面会强制选择样式,您要么需要在生成警告的地方放弃潜在有效的赋值用法,例如如果您使用 -Werror 或选择将这些情况括起来, 有些人可能会发现 ugly 正如下面的评论所暗示的那样。我们可以使用-Wno-parentheses 来关闭gccclang 中的警告,但我不推荐这种选择,因为通常警告会表明存在真正的错误。

【讨论】:

  • 这些“现代”警告通常是虚假的,例如if ( n = scanf("%d%d", &amp;x, &amp;y) ) 可能会在代码正确并按预期工作时触发警告。所以程序员要么禁用警告,要么丑化代码。我个人觉得多余的(....) != 0 比尤达条件更丑。
  • @MattMcNabb 现代编程充满了艰难的选择,有时您必须在保留可以捕获真正错误的警告和对代码样式进行细微更改之间做出选择。我不能告诉你要做出什么样的选择,因为这通常是一个团队的选择。在大多数情况下,我个人会选择将作业移出,但我确信在某些情况下可以为此提出论据。
【解决方案2】:

编译器没有区别。唯一的一点好处是,如果您忘记了“=”,第一种形式会导致语法错误(您不能将指针分配给 NULL),而第二种形式可能不会发出警告并愉快地破坏您的指针。

【讨论】:

    【解决方案3】:

    它们都是相同的(它们都检查指针是否为0),不同之处在于如果要防止无意分配,通常会使用第一个示例:

    if (pointer = NULL) // This compiles, but probably not what you meant
    
    if (NULL = pointer) // Syntax error!
    

    【讨论】:

      【解决方案4】:

      如果本课程吹捧C++11 兼容,那么真正应该使用的不是一直存在的 NULL 宏检查(至少在 C 语言生命周期内)。应该比较的是 nullptr 类型。供参考:nullptrWhat exactly is nullptr?

      来自上述 cplusplus.com 页面,截至 2014 年 2 月 28 日:

      空指针类型 (C++) 空指针常量 nullptr 的类型。

      这种类型只能取一个值:nullptr,当转换为指针类型时,它取正确的空指针值。

      尽管 nullptr_t 它不是关键字,但它标识了一个独特的基本类型:nullptr 的类型。因此,它作为不同的类型参与重载决议。

      此类型仅为 C++ 定义(自 C++11 起)。

      C++11(clang++、C++Builder 64 位(基于 clang++)、Visual Studio 2010 和更新版本;也可能只有 64 位、GCC 4.7.3 可能,不确定,可以是 GCC 4.8, ...):

      if (pointer == nullptr)
      
      // this looks odd, but does compile
      if (nullptr == pointer)
      

      如果这是一门严格的 C11 课程,那么看起来没有改进的方法可以替换 NULL 宏。 C99 标准规定 NULL 宏可以可移植地表示为整数值零,隐式或显式转换为 void* 类型 (from Wikipedia: Null pointer)。据我所知,C11 标准并未修改 C99 标准的这一方面。

      【讨论】:

      【解决方案5】:
      String pointer = "Some value";
      

      pointer 的初始值为"Some value",所以如果你错误地检查它 if(pointer = NULL)而不是if(pointer == NULL),空值将分配给pointer;但是在(NULL = pointer ) 的情况下,编译器将永远不允许您将任何内容分配给NULL。所以在条件语句中继续使用NULL == pointer

      【讨论】:

        猜你喜欢
        • 2016-12-05
        • 2022-12-27
        • 2021-10-01
        • 2013-07-20
        • 2019-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多