C语言 我们如何检查指针是否为 NULL 指针?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6185821/
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
How do we check if a pointer is NULL pointer?
提问by cpuer
I always think simply if(p != NULL){..}will do the job. But after reading this Stack Overflow question, it seems not.
我一直认为只是if(p != NULL){..}会做这项工作。但是在阅读了这个 Stack Overflow 问题之后,似乎不是。
So what's the canonical way to check for NULL pointers after absorbing all discussion in that questionwhich says NULL pointers can have non-zero value?
那么在吸收了该问题中的所有讨论之后检查 NULL 指针的规范方法是什么,该问题说 NULL 指针可以具有非零值?
回答by cnicutar
I always think simply if(p != NULL){..} will do the job.
我总是认为简单的 if(p != NULL){..} 会完成这项工作。
It will.
它会。
回答by James Kanze
First, to be 100% clear, there is nodifference between C and C++ here. And second, the Stack Overflow question you cite doesn't talk about null pointers; it introduces invalid pointers; pointers which, at least as far as the standard is concerned, cause undefined behavior just by trying to compare them. There is no way to test in general whether a pointer is valid.
首先,要 100% 清楚,这里C 和 C++ 之间没有区别。其次,您引用的 Stack Overflow 问题并未涉及空指针;它引入了无效的指针;至少就标准而言,指针仅通过尝试比较它们就会导致未定义的行为。通常没有办法测试指针是否有效。
In the end, there are three widespread ways to check for a null pointer:
最后,有三种普遍的方法来检查空指针:
if ( p != NULL ) ...
if ( p != 0 ) ...
if ( p ) ...
All work, regardless of the representation of a null pointer on the
machine. And all, in some way or another, are misleading; which one you
choose is a question of choosing the least bad. Formally, the first two
are indentical for the compiler; the constant NULLor 0is converted
to a null pointer of the type of p, and the results of the conversion
are compared to p. Regardless of the representation of a null
pointer.
不管机器上的空指针的表示如何,所有的工作都是有效的。而所有这些,在某种程度上,都是误导性的;你选择哪一个是选择最不坏的问题。形式上,前两个对于编译器是相同的;将常量NULLor0转换为 类型的空指针p,并将转换结果与 进行比较p。与空指针的表示无关。
The third is slightly different: pis implicitly converted
to bool. But the implicit conversion is defined as the results of p
!= 0, so you end up with the same thing. (Which means that there's
really no valid argument for using the third style—it obfuscates
with an implicit conversion, without any offsetting benefit.)
第三个略有不同:p隐式转换为bool. 但是隐式转换被定义为 的结果p
!= 0,所以你最终会得到同样的结果。(这意味着使用第三种风格确实没有有效的论据——它使用隐式转换进行混淆,没有任何抵消好处。)
Which one of the first two you prefer is largely a matter of style,
perhaps partially dictated by your programming style elsewhere:
depending on the idiom involved, one of the lies will be more bothersome
than the other. If it were only a question of comparison, I think most
people would favor NULL, but in something like f( NULL ), the
overload which will be chosen is f( int ), and not an overload with a
pointer. Similarly, if fis a function template, f( NULL )will
instantiate the template on int. (Of course, some compilers, like
g++, will generate a warning if NULLis used in a non-pointer context;
if you use g++, you really should use NULL.)
您更喜欢前两个中的哪一个主要是风格问题,可能部分取决于您在其他地方的编程风格:根据所涉及的习语,其中一个谎言会比另一个更麻烦。如果这只是一个比较问题,我认为大多数人会赞成NULL,但在类似的情况下f( NULL ),将选择的重载是f( int ),而不是带有指针的重载。同样,如果f是一个函数模板,f( NULL )将在 上实例化模板int。(当然,一些编译器,比如 g++,如果NULL在非指针上下文中使用会产生警告;如果你使用 g++,你真的应该使用NULL.)
In C++11, of course, the preferred idiom is:
在C++11 中,当然,首选的习惯用法是:
if ( p != nullptr ) ...
, which avoids most of the problems with the other solutions. (But it is not C-compatible:-).)
,这避免了其他解决方案的大部分问题。(但它不是 C 兼容的:-)。)
回答by Simon Richter
The compiler must provide a consistent type system, and provide a set of standard conversions. Neither the integer value 0 nor the NULL pointer need to be represented by all-zero bits, but the compiler must take care of converting the "0" token in the input file to the correct representation for integer zero, and the cast to pointer type must convert from integer to pointer representation.
编译器必须提供一致的类型系统,并提供一组标准转换。整数值 0 和 NULL 指针都不需要用全零位表示,但编译器必须注意将输入文件中的“0”标记转换为整数零的正确表示,以及转换为指针类型必须从整数转换为指针表示。
The implication of this is that
这意味着
void *p;
memset(&p, 0, sizeof p);
if(p) { ... }
is not guaranteed to behave the same on all target systems, as you are making an assumption about the bit pattern here.
不能保证在所有目标系统上的行为都相同,因为您在这里对位模式做出假设。
As an example, I have an embedded platform that has no memory protection, and keeps the interrupt vectors at address 0, so by convention, integers and pointers are XORed with 0x2000000 when converted, which leaves (void *)0 pointing at an address that generates a bus error when dereferenced, however testing the pointer with an ifstatement will return it to integer representation first, which is then all-zeros.
例如,我有一个没有内存保护的嵌入式平台,并将中断向量保持在地址 0,因此按照惯例,整数和指针在转换时与 0x2000000 进行异或,这使得 (void *)0 指向一个地址取消引用时会生成总线错误,但是使用if语句测试指针将首先将其返回为整数表示,然后是全零。
回答by Mike Seymour
The actual representation of a null pointer is irrelevant here. An integer literal with value zero (including 0and any valid definition of NULL) can be converted to any pointer type, giving a null pointer, whatever the actual representation. So p != NULL, p != 0and pare all valid tests for a non-null pointer.
空指针的实际表示在这里无关紧要。具有零值的整数文字(包括0和 的任何有效定义NULL)可以转换为任何指针类型,给出空指针,无论实际表示如何。所以p != NULL,p != 0和p都是对非空指针的有效测试。
You might run into problems with non-zero representations of the null pointer if you wrote something twisted like p != reinterpret_cast<void*>(0), so don't do that.
如果你写了一些像 那样扭曲的东西p != reinterpret_cast<void*>(0),你可能会遇到空指针的非零表示的问题,所以不要这样做。
Although I've just noticed that your question is tagged C as well as C++. My answer refers to C++, and other languages may be different. Which language are you using?
尽管我刚刚注意到您的问题被标记为 C 和 C++。我的回答是指C++,其他语言可能不一样。你使用哪种语言?
回答by pmg
Apparently the thread you refer is about C++.
显然,您所指的线程是关于C++.
In Cyour snippet will always work. I like the simpler if (p) { /* ... */ }.
在C您的代码段中将始终有效。我喜欢简单的if (p) { /* ... */ }。
回答by R.. GitHub STOP HELPING ICE
The representation of pointers is irrelevant to comparing them, since all comparisons in C take place as valuesnot representations. The only way to compare the representation would be something hideous like:
指针的表示与比较它们无关,因为 C 中的所有比较都是作为值而不是表示进行的。比较表示的唯一方法是一些可怕的东西,例如:
static const char ptr_rep[sizeof ptr] = { 0 };
if (!memcmp(&ptr, ptr_rep, sizeof ptr)) ...
回答by JohnJohn
Well, this question was asked and answered way back in 2011, but there is nullptrin C++11. That's all I'm using currently.
好吧,这个问题早在 2011 年就有人问过并得到了回答,但nullptr在C++11 中有。这就是我目前正在使用的所有内容。
You can read more from Stack Overflowand also from this article.
您可以从 Stack Overflow和这篇文章中阅读更多内容。
回答by Misha Taylor
//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.

