C++ 我可以使用 if (pointer) 而不是 if (pointer != NULL) 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17772103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:26:23  来源:igfitidea点击:

Can I use if (pointer) instead of if (pointer != NULL)?

c++pointersif-statementnullnull-pointer

提问by danijar

Is it safe to check a pointer to not being NULLby writing simply if(pointer)or do I have to use if(pointer != NULL)?

NULL通过简单地书写来检查指向 notbeing 的指针是否安全,if(pointer)还是必须使用if(pointer != NULL)

回答by Joni

You can; the null pointer is implicitly converted into boolean false while non-null pointers are converted into true. From the C++11 standard, section on Boolean Conversions:

你可以; 空指针被隐式转换为布尔值 false 而非空指针被转换为 true。来自 C++11 标准,关于布尔转换的部分

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_tcan be converted to a prvalue of type bool; the resulting value is false.

算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为 type 的纯右值 bool。零值、空指针值或空成员指针值转换为 false; 任何其他值都转换为 true. 类型的纯右值 std::nullptr_t可以转换为类型的纯右值 bool;结果值为 false

回答by billz

Yes, you could.

是的,你可以。

  • A null pointer is converted to false implicitly
  • a non-null pointer is converted to true.
  • 空指针隐式转换为 false
  • 非空指针被转换为真。

This is part of the C++ standard conversion, which falls in Boolean conversionclause:

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

§ 4.12 Boolean conversions

§ 4.12 布尔转换

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为 bool 类型的纯右值。零值、空指针值或空成员指针值转换为 false;任何其他值都将转换为 true。std::nullptr_t 类型的纯右值可以转换为 bool 类型的纯右值;结果值为假。

回答by Yu Hao

Yes, you can. In fact, I prefer to use if(pointer)because it's simpler to read and write once you get used to it.

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

Also note that C++11 introduced nullptrwhich is preferred over NULL.

另请注意,引入的 C++11nullptr优于NULL.

回答by Grijesh Chauhan

Question is answered, but I would like to add my points.

问题得到了回答,但我想补充我的观点。

I will always prefer if(pointer)instead of if(pointer != NULL)and if(!pointer)instead of if(pointer == NULL):

我将永远喜欢if(pointer)而不是if(pointer != NULL)if(!pointer)而不是if(pointer == NULL)

  • It is simple, small
  • Less chances to write a buggy code, suppose if I misspelled equality check operator ==with =
    if(pointer == NULL)can be misspelled if(pointer = NULL)So I will avoid it, best is just if(pointer).
    (I also suggested some Yoda condition in one answer, but that is diffrent matter)

  • Similarly for while (node != NULL && node->data == key), I will simply write while (node && node->data == key)that is more obvious to me (shows that using short-circuit).

  • (may be stupid reason) Because NULL is a macro, if suppose some one redefine by mistake with other value.
  • 简单,小
  • 编写错误代码的机会较少,假设如果我拼错了等式检查运算符==with=
    if(pointer == NULL)可以拼错if(pointer = NULL)所以我会避免它,最好只是if(pointer).
    (我还在一个答案中提出了一些Yoda 条件,但那是另一回事)

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

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

回答by Minqi Pan

Explicitly checking for NULL could provide a hint to the compiler on what you are trying to do, ergo leading to being less error-prone.

显式检查 NULL 可以向编译器提供有关您尝试执行的操作的提示,从而减少出错的可能性。

enter image description here

在此处输入图片说明

回答by dasblinkenlight

Yes, you can. The ability to compare values to zeros implicitly has been inherited from C, and is there in all versions of C++. You can also use if (!pointer)to check pointers for NULL.

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

回答by leftaroundabout

The relevant use cases for null pointers are

空指针的相关用例是

  • Redirection to something like a deeper tree node, which may not exist or has not been linked yet. That's something you should always keep closely encapsulated in a dedicated class, so readability or conciseness isn't that much of an issue here.
  • Dynamic casts. Casting a base-class pointer to a particular derived-class one (something you should again try to avoid, but may at times find necessary) always succeeds, but results in a null pointer if the derived class doesn't match. One way to check this is

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

    (or, preferrably, auto derived_ptr = ...). Now, this is bad, because it leaves the (possibly invalid, i.e. null) derived pointer outside of the safety-guarding ifblock's scope. This isn't necessary, as C++ allows you to introduce boolean-convertable variables inside an if-condition:

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

    which is not only shorter and scope-safe, it's also much more clear in its intend: when you check for null in a separate if-condition, the reader wonders "ok, so derived_ptrmust not be null here... well, why would it be null?" Whereas the one-line version says very plainly "if you can safely cast base_ptrto Derived*, then use it for...".

    The same works just as well for any other possible-failure operation that returns a pointer, though IMO you should generally avoid this: it's better to use something like boost::optionalas the "container" for results of possibly failing operations, rather than pointers.

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

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

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

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

    这不仅更短且范围安全,而且其意图也更加明确:当您在单独的 if 条件中检查 null 时,读者想知道“好吧,所以derived_ptr这里不能为 null ......好吧,为什么会它是空的?” 而单行版本则非常明确地说“如果您可以安全地强制转换base_ptrDerived*,那么将其用于……”。

    对于返回指针的任何其他可能失败的操作,这同样适用,尽管 IMO 您通常应该避免这种情况:最好使用类似boost::optional“容器”之类的东西来处理可能失败的操作的结果,而不是指针。

So, if the main use case for null pointers should always be written in a variation of the implicit-cast-style, I'd say it's good for consistency reasons to alwaysuse this style, i.e. I'd advocate for if(ptr)over if(ptr!=nullptr).

所以,如果空指针的主要用例应该总是用隐式转换风格的变体来编写,我会说始终使用这种风格有利于一致性的原因,即我提倡if(ptr)over if(ptr!=nullptr)



I'm afraid I have to end with an advert: the if(auto bla = ...)syntax is actually just a slightly cumbersome approximation to the realsolution to such problems: pattern matching. Why would you first force some action (like casting a pointer) and then consider that there might be a failure... I mean, it's ridiculous, isn't it? It's like, you have some foodstuff and want to make soup. You hand it to your assistant with the task to extract the juice, if it happens to be a soft vegetable. You don't first look it at it. When you have a potato, you still give it to your assistant but they slap it back in your face with a failure note. Ah, imperative programming!

恐怕我必须以一个广告结束:if(auto bla = ...)语法实际上只是对此类问题的真正解决方案的稍微麻烦的近似:模式匹配。为什么要先强制执行某些操作(例如投射指针),然后再考虑可能会失败...我的意思是,这很荒谬,不是吗?就像,你有一些食物,想要做汤。如果它碰巧是一种软蔬菜,您将它交给您的助手,负责提取果汁。你不会先看它。当你有一个土豆时,你仍然把它交给你的助手,但他们用失败的笔记把它打回你的脸上。啊,命令式编程!

Much better: consider right away all the cases you might encounter. Then act accordingly. 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 also has special tools for when there is really a serious possibility of failure (as well as for a whole bunch of other stuff): monads. But this isn't the place for explaining those.

Haskell 也有一些特殊的工具,用于在非常有可能失败的情况下(以及一大堆其他东西):monads。但这不是解释这些的地方。

⟨/advert⟩

⟨/广告⟩

回答by Palak Jain

yes, of course! in fact, writing if(pointer) is a more convenient way of writing rather than if(pointer != NULL) because: 1. it is easy to debug 2. easy to understand 3. if accidently, the value of NULL is defined, then also the code will not crash

是的当然!其实写if(pointer)是比if(pointer != NULL)更方便的写法,因为:1.容易调试2.容易理解3.如果不小心定义了NULL的值,那么代码也不会崩溃

回答by z3moon

As others already answered well, they both are interchangeable.

由于其他人已经回答得很好,它们都是可以互换的。

Nonetheless, it's worth mentioning that there could be a case where you may want to use the explicit statement, i.e. pointer != NULL.

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

See also https://stackoverflow.com/a/60891279/2463963

另见https://stackoverflow.com/a/60891279/2463963

回答by darshandzend

Yes. In fact you should. If you're wondering if it creates a segmentation fault, it doesn't.

是的。事实上你应该。如果您想知道它是否会创建分段错误,则不会。