我们如何检查指针是否为NULL指针?

时间:2011-05-31 09:52:41

标签: c null-pointer

我一直认为只需if(p != NULL){..}即可。但在阅读this Stack Overflow question后,似乎没有。

那么在吸收该问题中的所有讨论之后检查NULL指针的规范方法是什么呢?表示NULL指针可以具有非零值?

8 个答案:

答案 0 :(得分:49)

  

我总是认为是(p!=   NULL){..}将完成这项工作。

会的。

答案 1 :(得分:28)

首先,要100%清除,C和C ++之间存在差异 这里。第二,你引用的Stack Overflow问题并没有讨论空指针;它引入了无效指针;指针,至少到目前为止 标准是关注,只是通过尝试导致未定义的行为 比较它们。通常无法测试指针是否为 有效的。

最后,有三种检查空指针的方法:

if ( p != NULL ) ...

if ( p != 0 ) ...

if ( p ) ...

所有工作,无论空指针的表示如何 机。所有这些都以某种方式产生误导;哪一个你 选择是选择最不好的问题。正式,前两个 是编译器的缩写;常量NULL0已转换 到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)

空指针的实际表示与此无关。值为零的整数文字(包括0NULL的任何有效定义)可以转换为任何指针类型,给出空指针,无论实际表示如何。因此p != NULLp != 0p都是非空指针的有效测试。

如果你写了像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。我现在正在使用它。

您可以阅读more from Stack Overflow以及this article

答案 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.