我可以使用if(指针)而不是if(指针!= NULL)吗?

时间:2013-07-21 12:00:35

标签: c++ pointers if-statement null null-pointer

通过简单地NULL或是否必须使用if(pointer)来检查指针不是if(pointer != NULL)是否安全?

14 个答案:

答案 0 :(得分:173)

你可以;空指针被隐式转换为布尔值false,而非空指针转换为true。从C ++ 11标准,布尔转换:

部分
  

算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为a   类型的prvalue   bool。将零值,空指针值或空成员指针值转换为   false;   任何其他值都转换为   true   。一个类型的prvalue   std::nullptr_t   可以转换为prvalue   类型   bool   ;结果值是   false   

答案 1 :(得分:38)

是的,你可以。

  • 空指针被隐式转换为
  • 非空指针转换为true。

这是C ++标准转换的一部分,它属于布尔转换子句:

§4.12布尔转换

  

算术,无范围枚举,指针的prvalue或成员类型的指针可以转换为bool类型的prvalue。 零值,空指针值或空成员指针值转换为false;任何其他值都转换为true。 std :: nullptr_t类型的prvalue可以转换为bool类型的prvalue;结果值为false。

答案 2 :(得分:29)

是的,你可以。事实上,我更喜欢使用if(pointer),因为一旦你习惯它就更容易读写。

另请注意,C ++ 11引入了nullptr,优先于NULL

答案 3 :(得分:12)

问题已得到解答,但我想补充一点。

我总是更喜欢if(pointer)而不是if(pointer != NULL)if(!pointer)而不是if(pointer == NULL)

  • 简单,小巧
  • 编写错误代码的机会较少,假设我使用==拼写错误检查操作符= if(pointer == NULL)可能拼写错误if(pointer = NULL)所以我会避免它,最好只是if(pointer)
    (我还提出了一些Yoda condition in one answer,但那是不同的事情)

  • 同样对while (node != NULL && node->data == key),我只会写while (node && node->data == key),这对我来说更明显(显示使用短路)。

  • (可能是愚蠢的原因)因为NULL是一个宏,如果假设某个人错误地重新定义了其他值。

答案 4 :(得分:10)

显式检查NULL可能会向编译器提供关于您尝试执行的操作的提示,这样可以减少错误。

enter image description here

答案 5 :(得分:8)

是的,你可以。隐式地将值与零进行比较的能力是从C继承的,并且在所有版本的C ++中都存在。您还可以使用if (!pointer)检查指针是否为NULL。

答案 6 :(得分:2)

空指针的相关用例是

  • 重定向到更深层的树节点,可能不存在或尚未链接。这是你应该始终密切封装在一个专门的课程中的东西,所以这里的可读性或简洁性并不是一个很大的问题。
  • 动态演员。将基类指针强制转换为特定的派生类(您应该再次尝试避免,但有时可能会发现必要的东西)总是成功,但如果派生类不匹配则会产生空指针。检查这个的一种方法是

    Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
    if(derived_ptr != nullptr) { ... }
    

    (或者,最好是auto derived_ptr = ...)。现在,这很糟糕,因为它将(可能无效的,即null)派生指针留在安全保护if块的范围之外。这不是必需的,因为C ++允许您在if - 条件中引入布尔可转换变量

    if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }
    

    不仅更短且范围更安全,它的意图也更加明确:当你在一个单独的if条件中检查null时,读者想知道“ok,所以derived_ptr不能为null在这......好吧,为什么它会无效?“虽然单行版本非常明确地说“如果你可以安全地将base_ptr投射到Derived*,那么就将它用于......”。

    对于返回指针的任何其他可能失败操作,同样的工作也是如此,尽管IMO通常应该避免这种情况:最好使用boost::optional之类的东西作为“容器”,以获得可能失败的结果操作,而不是指针。

因此,如果空指针的主要用例应该总是用隐式转换样式的变体来写,我会说出于一致性的原因,总是使用这种风格是好的,即我主张if(ptr)超过if(ptr!=nullptr)


我担心我必须以广告结束:if(auto bla = ...)语法实际上只是对这些问题的真实解决方案的稍微麻烦的近似:模式匹配< / em>的。你为什么要先强迫一些动作(比如施放指针),然后认为可能会失败......我的意思是,这太荒谬了,不是吗?就像,你有一些食物,想要做汤。如果它恰好是一种柔软的蔬菜,你可以把它交给你的助手来完成提取果汁的任务。你不要先看它。当你有一个土豆时,你仍然把它交给你的助手,但他们用失败的记录将它拍回你的脸上。啊,命令式编程!

好多了:立即考虑你可能遇到的所有情况。然后采取相应行动Haskell中:

makeSoupOf :: Foodstuff -> Liquid
makeSoupOf p@(Potato{..}) = mash (boil p) <> water
makeSoupOf vegetable
 | isSoft vegetable  = squeeze vegetable <> salt
makeSoupOf stuff  = boil (throwIn (water<>salt) stuff)

Haskell还有一些特殊工具可用于确实存在严重失败的可能性(以及其他一些东西):monads。但这不是解释这些问题的地方。

⟨/advert⟩

答案 7 :(得分:0)

是。实际上你应该。如果您想知道它是否创建了segmentation fault,那么它就不会。

答案 8 :(得分:0)

是的,当然! 事实上,写if(指针)是一种更方便的写法而不是if(指针!= NULL),因为: 1.它易于调试 2.易于理解 3.如果意外地定义了NULL的值,那么代码也不会崩溃

答案 9 :(得分:0)

其他人已经很好地回答了,他们都是可以互换的。

尽管如此,值得一提的是,在某些情况下,您可能想使用显式语句,即pointer != NULL

另请参阅https://stackoverflow.com/a/60891279/2463963

答案 10 :(得分:0)

是的,两者在功能上是相同的。但是在C ++中,您应该切换到nullptr代替NULL;

答案 11 :(得分:-1)

是的,您可以随时执行此操作,因为'IF'条件仅在其中的条件成立时才进行评估。 C没有布尔返回类型,因此当条件为真时返回非零值,而当'IF'中的条件变为假时返回0。默认返回的非零值为1.因此,编写代码的两种方式都是正确的,而我总是更喜欢第二种方式。

答案 12 :(得分:-1)

我认为根据经验,如果您的 if-expression 可以重写为

const bool local_predicate = *if-expression*;
if (local_predicate) ...

这样会导致NO WARNINGS,那么这应该是 if-expression 的首选样式。 (我知道当我将旧的C BOOL#define BOOL int)分配给C ++ bool时,我会收到警告,更不用说指针了。)

答案 13 :(得分:-1)

“安全吗??”是关于语言标准和生成的代码的问题。

“这是一个好习惯吗?”这是一个关于声明如何被任何人类读者理解的问题。如果你问这个问题,它表明未来的读者和作家对“安全”版本不太清楚。