我一直认为只需if(p != NULL){..}
即可。但在阅读this Stack Overflow question后,似乎没有。
那么在吸收该问题中的所有讨论之后检查NULL指针的规范方法是什么呢?表示NULL指针可以具有非零值?
答案 0 :(得分:49)
我总是认为是(p!= NULL){..}将完成这项工作。
会的。
答案 1 :(得分:28)
首先,要100%清除,C和C ++之间存在无差异 这里。第二,你引用的Stack Overflow问题并没有讨论空指针;它引入了无效指针;指针,至少到目前为止 标准是关注,只是通过尝试导致未定义的行为 比较它们。通常无法测试指针是否为 有效的。
最后,有三种检查空指针的方法:
if ( p != NULL ) ...
if ( p != 0 ) ...
if ( p ) ...
所有工作,无论空指针的表示如何
机。所有这些都以某种方式产生误导;哪一个你
选择是选择最不好的问题。正式,前两个
是编译器的缩写;常量NULL
或0
已转换
到p
类型的空指针,以及转换的结果
与p
进行比较。无论null的表示
指针。
第三个略有不同:p
被隐式转换
到bool
。但是隐式转换被定义为p
!= 0
的结果,所以你最终会得到同样的结果。 (这意味着有
真的没有使用第三种风格的有效论据 - 它混淆了
隐式转换,没有任何抵消利益。)
你喜欢的前两个中哪一个主要是风格问题,
也许部分由你在其他地方的编程风格决定:
根据所涉及的习语,其中一个谎言会更麻烦
比另一个。如果这只是一个比较问题,我认为最多
人们会赞成NULL
,但在类似f( NULL )
之类的内容中
将选择的重载是f( int )
,而不是a的重载
指针。同样,如果f
是一个功能模板,f( NULL )
会
在int
上实例化模板。 (当然,有些编译器,比如
g ++,如果在非指针上下文中使用NULL
,将生成警告;
如果你使用g ++,你真的应该使用NULL
。)
当然,在C++11中,首选的习语是:
if ( p != nullptr ) ...
,避免了其他解决方案的大部分问题。 (但它 与C不兼容: - )。)
答案 2 :(得分:9)
编译器必须提供一致的类型系统,并提供一组标准转换。整数值0和NULL指针都不需要用全零位表示,但编译器必须注意将输入文件中的“0”标记转换为整数零的正确表示,并转换为指针类型必须从整数转换为指针表示。
这意味着
void *p;
memset(&p, 0, sizeof p);
if(p) { ... }
不保证在所有目标系统上的行为相同,因为您在此处对位模式进行了假设。
作为一个例子,我有一个没有内存保护的嵌入式平台,并将中断向量保持在地址0,所以按照惯例,整数和指针在转换时与0x2000000进行异或,这使(void *)0指向在解除引用时生成总线错误的地址,但是使用if
语句测试指针将首先将其返回到整数表示,然后全部为零。
答案 3 :(得分:6)
空指针的实际表示与此无关。值为零的整数文字(包括0
和NULL
的任何有效定义)可以转换为任何指针类型,给出空指针,无论实际表示如何。因此p != NULL
,p != 0
和p
都是非空指针的有效测试。
如果你写了像p != reinterpret_cast<void*>(0)
这样扭曲的东西,你可能会遇到空指针的非零表示问题,所以不要这样做。
虽然我刚刚注意到你的问题被标记为C以及C ++。我的答案是指C ++,其他语言可能不同。你使用哪种语言?
答案 4 :(得分:4)
显然,您引用的主题是C++
。
在C
中,您的代码段始终有效。我喜欢更简单的if (p) { /* ... */ }
。
答案 5 :(得分:2)
指针的表示与比较它们无关,因为C中的所有比较都是以值表示而不是表示。比较表示的唯一方法是可怕的,如:
static const char ptr_rep[sizeof ptr] = { 0 };
if (!memcmp(&ptr, ptr_rep, sizeof ptr)) ...
答案 6 :(得分:1)
嗯,这个问题在2011年被问及回答,但C++11中有nullptr
。我现在正在使用它。
答案 7 :(得分:0)
//Do this
int IS_NULL_PTR(char *k){
memset(&k, k, sizeof k);
if(k) { return 71; } ;
return 72;
}
int PRINT_PTR_SAFE(char *KR){
char *E=KR;;
if (IS_NULL_PTR(KR)==71){
printf("%s\r\n",KR);
} else {
printf("%s","(null)\r\n");
}
}
int main(int argc,char *argv[]){
int i=0;
char *A=malloc(sizeof(char)*9);
;strcpy(A,"hello world");
for (i=((int)(A))-10;i<1e+40;i++){
PRINT_PTR_SAFE(i);
}
}
//Then watch the show!
//Edit as you wish. Just credit me if you really want more of this.