我可以用if(指针)代替if(指针!=空)?

通过简单地写入if(pointer)来检查不是NULL的指针是否安全,或者我是否必须使用if(pointer != NULL)

126250 次浏览

你可以;NULL指针隐式转换为布尔值FALSE,而非NULL指针转换为TRUE.根据C++11标准,关于布尔转换:的部分

算术、无作用域枚举、指针或指向成员类型的指针

的prValue可以转换为 类型的PR值 bool。值、空指针值或空成员指针值转换为 false; 任何其他值都将转换为 true .类型的prValue std::nullptr_t 可以转换为PRValue 类型 bool ;结果值为 false

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

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

还要注意,C++11引入了nullptr,它优于NULL

是的,你可以。

  • NULL指针隐式转换为FALSE
  • 非NULL指针转换为TRUE.

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

§4.12布尔转换

算术、无作用域枚举、指针或指向成员类型的指针的prValue可以转换为bool类型的prValue.零值、空指针值或空成员指针值转换为false.任何其他值都将转换为true.可以将STD:nullptr_t类型的prValue转换为bool类型的pr Value.结果值为false.

是的。事实上你应该。如果您想知道它是否创建了分段错误,那么它没有。

问题已经回答了,但我想补充我的观点。

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

  • 它很简单,很小
  • 编写错误代码的机会
  • 更少,假设我拼错了相等检查运算符===
    if(pointer == NULL)可能会被拼错if(pointer = NULL),所以我会避免它,最好是只if(pointer)
    (我还建议了一些一个答案中的尤达条件,但这是不同的问题)

  • 类似地,对于while (node != NULL && node->data == key),我将简单地写while (node && node->data == key),这对我来说更明显(显示使用短路)。

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

空指针的相关用例如下

  • 重定向到更深的树节点,该节点可能不存在或尚未链接。这是您应该始终将其紧密封装在专用类中的内容,因此可读性或简洁性在这里并不是什么大问题。
  • 动态强制转换。将基类指针强制转换为特定的派生类指针(您应该再次尝试避免,但有时可能会发现这是必要的)总是成功的,但如果派生类不匹配,则会导致空指针。检查这个的一种方法是

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

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

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

    这不仅更简短和范围安全,而且其意图也更加明确:当您在单独的if条件中检查NULL时,读者想知道OK,因此derived_ptr在这里不能为NULL..。好吧,为什么它会是空的?“而单行版本则非常明确地表示:”如果您可以安全地将base_ptr转换为Derived*,则将其用于.."。

    这同样适用于任何其他返回指针的可能失败的操作,但在我看来,您通常应该避免这样做:最好使用类似boost::optional的内容作为可能失败的操作结果的“容器”,而不是使用指针。

因此,如果空指针的主要用例应该始终以隐式强制转换样式的变体编写,我会说,出于一致性原因,总是使用此样式是有好处的,即,我会提倡if(ptr)而不是if(ptr!=nullptr)


恐怕我必须用一个广告来结束:if(auto bla = ...)语法实际上只是实际的的一个稍微麻烦的近似解决方案:模式匹配。为什么要先强制执行某些操作(如强制转换指针),然后再考虑可能会失败..我是说,这很荒谬,不是吗?这就像,你有一些食物,想要做汤。你把它交给你的助手,任务是榨汁,如果它碰巧是一种软蔬菜。你不会先看它。当你有一个土豆时,你仍然把它给你的助手,但他们用一张失败的纸条把它打回你的脸上。啊,命令式编程!

更好的办法是:马上考虑你可能遇到的所有情况。然后采取相应的行动。哈斯克尔:

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也有特殊的工具,当确实存在严重的失败可能性时(以及一大堆其他东西):单子。但这里不是解释这些的地方。

&langle;/广告&rangle;

是的,你总是可以这样做,因为“ if ”条件只有当它里面的条件为真时才会求值。C没有布尔返回类型,因此当条件为真时返回非零值,而每当' if '中的条件为假时返回0。默认返回的非零值为1。因此,两种代码编写方式都是正确的,而我总是倾向于第二种。

我认为根据经验,如果您的如果表达式可以重写为

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

使得其不引起警告,则这应该是如果表达式的优选样式。(我知道,当我将旧的CBOOL#define BOOL int)分配给C++bool时,会收到警告,更不用说指针了。)

“它是否安全.?”是一个关于语言标准和生成代码的问题。

“ Is is a good practice?”是一个关于语句的任意人类读者对语句的理解程度的问题。如果你问这个问题,它表明“安全”版本对未来的读者和作者来说不太清楚。

显式检查NULL可以向编译器提供有关您正在尝试执行的操作的提示,因此更不容易出错。

enter image description here

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

正如其他人已经回答的那样,它们都是可以互换的。

然而,值得一提的是,在某些情况下,您可能希望使用显式语句,即pointer != NULL

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

是的,两者在功能上是一样的。但是在C++中,你应该切换到nullptr来代替null.