我一直认为只会if(p != NULL){..}
做这项工作.但在阅读Stack Overflow问题后,似乎没有.
那么在吸收了那个说明NULL指针可能具有非零值的问题的所有讨论之后检查NULL指针的规范方法是什么?
cni*_*tar 52
我总是认为,如果(p!= NULL){..}将完成这项工作.
它会.
Jam*_*nze 29
首先,要100%清楚,这里C和C++之间没有区别.第二,你引用的Stack Overflow问题并没有讨论空指针; 它引入了无效指针; 指针,至少就标准而言,仅通过尝试比较它们就会导致未定义的行为.通常无法测试指针是否有效.
最后,有三种检查空指针的方法:
if ( p != NULL ) ...
if ( p != 0 ) ...
if ( p ) ...
Run Code Online (Sandbox Code Playgroud)
所有工作,无论机器上的空指针表示如何.所有这些都以某种方式产生误导; 你选择哪一个是选择最不好的问题.形式上,前两个是编译器的缩写; 常量NULL
或0
转换为类型的空指针p
,并将转换结果进行比较p
.无论空指针的表示如何.
第三个略有不同:p
隐式转换为bool
.但是隐式转换被定义为结果p
!= 0
,所以你最终会得到同样的结果.(这意味着使用第三种样式确实没有有效的参数 - 它与隐式转换混淆,没有任何抵消利益.)
你喜欢的前两个中哪一个主要是风格问题,也许部分取决于你在其他地方的编程风格:根据所涉及的习语,其中一个谎言将比另一个更麻烦.如果它只是一个比较的问题,我认为大多数人会喜欢NULL
,但在类似的情况下f( NULL )
,将选择f( int )
的重载,而不是指针的重载.同样,如果f
是函数模板,f( NULL )
则将实例化模板int
.(当然,一些编译器,比如g ++,如果NULL
在非指针上下文中使用,会产生警告;如果你使用g ++,你真的应该使用NULL
.)
当然,在C++ 11中,首选的习惯是:
if ( p != nullptr ) ...
Run Code Online (Sandbox Code Playgroud)
,这避免了其他解决方案的大多数问题.(但它不兼容C :-).)
Sim*_*ter 10
编译器必须提供一致的类型系统,并提供一组标准转换.整数值0和NULL指针都不需要用全零位表示,但编译器必须注意将输入文件中的"0"标记转换为整数零的正确表示,并转换为指针类型必须从整数转换为指针表示.
这意味着
void *p;
memset(&p, 0, sizeof p);
if(p) { ... }
Run Code Online (Sandbox Code Playgroud)
并不保证在所有目标系统上的行为相同,因为您在此处对位模式进行了假设.
作为一个例子,我有一个没有内存保护的嵌入式平台,并将中断向量保持在地址0,所以按照惯例,整数和指针在转换时与0x2000000进行异或,这使得(void*)0指向一个地址在解除引用时生成总线错误,但是使用if
语句测试指针将首先将其返回到整数表示,然后全部为零.
空指针的实际表示在这里是无关紧要的.值为零的整数文字(包括0
和任何有效的定义NULL
)可以转换为任何指针类型,给出空指针,无论实际表示如何.所以p != NULL
,p != 0
并且p
都是非空指针的有效测试.
如果你写了类似扭曲的东西p != reinterpret_cast<void*>(0)
,你可能会遇到空指针的非零表示问题,所以不要这样做.
虽然我刚刚注意到你的问题被标记为C以及C++.我的答案是指C++,其他语言可能不同.你使用哪种语言?