NULL通过简单编写来检查是否存在指针是安全的if(pointer)还是必须使用if(pointer != NULL)?
NULL从现在起,您就不应该在C ++中使用,因为NULL依赖于实现的宏可能会给您带来歧义的行为。
NULL通过简单编写来检查是否存在指针是安全的if(pointer)还是必须使用if(pointer != NULL)?
NULL从现在起,您就不应该在C ++中使用,因为NULL依赖于实现的宏可能会给您带来歧义的行为。
Answers:
是的你可以。实际上,我更喜欢使用if(pointer)它,因为一旦您习惯了它,它就更容易读写。
还要注意,引入了C ++ 11 nullptr而不是NULL。
if(som_integer)vs 应用相同的逻辑,if(some_integer != 0)因为整数也不是布尔值,对吗?我倾向于避免0或NULL在if语句。
if (pointer)自己,但if (ptr != nullptr)对我来说似乎完全合法。另一方面,如果我看到团队中有人写信,if (some_integer)我会让他们将其更改为if (some_integer != 0)。但是,我不会假装这不是相对任意的偏好-我只是不想将指针和整数视为相同。
if(isReady) if(filePtr) if(serviceNo)?在这种情况下,故意使错误的变量名称意义不大。无论如何,我已经明白了您的意思,但是我可以坚持使用自己的编码风格,好吗?
问题已经回答,但我想补充一点。
我将始终喜欢if(pointer)而不是if(pointer != NULL)和if(!pointer)而不是if(pointer == NULL):
(boolean expression)? true : false是完全没有意义的。该表达式的计算结果为true或false;你说的是“如果是真的,请给我真实,如果是错误的,请给我真实”。简而言之:它完全等同于布尔表达式本身。请注意,这node == NULL是一个布尔表达式。顺便说一句,您的两个实现返回的完全相反。您想要!=第一个,或者只想要!第二个。
=替代方法==是尽可能地使变量可变const。例如,您可以将函数定义为isEmnpy(node* const head) { ... },然后如果您不小心编写node = NULL而不是,则编译器将拒绝编译它node == NULL。当然,这仅适用于确实不需要更改的变量。
T* get() const的,而不是operator T*() const为了避免隐式转换。但是他们确实有一个operator bool() const。
是的你可以。从C继承了隐式将值与零进行比较的功能,并且在所有C ++版本中都存在。您也可以使用if (!pointer)NULL检查指针。
空指针的相关用例是
动态转换。将基类指针强制转换为特定的派生类指针(您应再次尝试避免,但有时可能会发现有必要)强制转换总是成功,但如果派生类不匹配,则将导致空指针。一种检查方法是
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
if(derived_ptr != nullptr) { ... }
(或最好是auto derived_ptr = ...)。现在,这很糟糕,因为它将派生的指针(可能无效,即null)超出了安全防护if块的范围。这是没有必要的,因为C ++允许引入布尔变量可转换内部if-condition:
if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }
它不仅更短,更安全,而且其意图也更加清楚:当您在单独的if条件中检查null时,读者会想:“好,所以derived_ptr在这里一定不能为null ...那么,为什么会它为空吗?” 单行版本非常明确地说:“如果可以安全地投射base_ptr到Derived*,则将其用于...”。
对于返回指针的其他任何可能失败的操作,同样适用,尽管IMO您通常应避免这种情况:最好将类似boost::optional“容器”之类的内容用于可能失败的操作的结果,而不是使用指针。
因此,如果空指针的主要用例应始终以隐式cast-style的变体编写,那么出于一致性的原因,总是使用这种风格是很好的,即我主张if(ptr)over if(ptr!=nullptr)。
恐怕我不得不以广告结尾:if(auto bla = ...)语法实际上只是对此类问题的真正解决方案(模式匹配)的一点繁琐的近似。您为什么首先要强制执行某些操作(例如投射指针),然后又认为可能会失败...我的意思是,这很荒谬,不是吗?就像,您有一些食品并且想要做汤。如果果汁是软蔬菜,则将其交给您的助手来提取果汁。您无需首先查看它。当您有马铃薯时,您仍将其交给助手,但他们会用失败记录将其拍回。啊,命令式编程!
更好:立即考虑您可能遇到的所有情况。然后采取相应行动。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。但这不是解释这些的地方。
⟨/广告⟩
if(ptr)而不是if(ptr != nullptr),还有很多话要说。
正如其他人已经回答的很好,它们都是可以互换的。
尽管如此,值得一提的是,在某些情况下,您可能想使用显式语句,即pointer != NULL。
“安全吗??” 是有关语言标准和生成的代码的问题。
“这是一个好习惯吗?” 这是一个问题,该问题由任何专断的人类读者理解该语句有多好。如果您问这个问题,则表明“安全”版本对将来的读者和作家不太清楚。
0or 进行测试同样有效-并且通常是首选nullptr。(NULL是C'ism,并且需要包含头文件。)