在 C 语言中,各种零值之间似乎存在差异——NULL
、NUL
和 0
。
我知道 ASCII 字符 '0'
的计算结果为 48
或 0x30
。
NULL
指针通常定义为:
#define NULL 0
或者
#define NULL (void *)0
此外,还有一个 NUL
字符 '\0'
,它的计算结果似乎也是 0
。
有时这三个值不能相等吗?
在 64 位系统上也是如此吗?
最佳答案
注意:此答案适用于 C 语言,不适用于 C++。
空指针
整型常量 0
具有不同的含义,具体取决于使用它的上下文。在所有情况下,它仍然是一个整数常量,值为0
,只是描述方式不同而已。
如果将指针与常量文字 0
进行比较,则检查该指针是否为空指针。这个 0
然后被称为空指针常量。 C 标准定义将 0
转换为类型 void *
既是空指针又是空指针常量。
此外,为了提高可读性,头文件stddef.h
中提供了宏NULL
。根据您的编译器,可能会 #undef NULL
并将其重新定义为古怪的东西。
因此,这里有一些检查空指针的有效方法:
if (pointer == NULL)
NULL
被定义为比较等于空指针。 NULL
的实际定义是由实现定义的,只要它是一个有效的空指针常量即可。
if (pointer == 0)
0
是空指针常量的另一种表示。
if (!pointer)
此 if
语句隐式检查“不为 0”,因此我们将其反转为“为 0”。
以下是检查空指针的无效方法:
int mynull = 0;
<some code>
if (pointer == mynull)
对于编译器来说,这不是对空指针的检查,而是对两个变量的相等性检查。这可能如果代码中的 mynull 永远不会改变并且编译器优化常量将 0 折叠到 if 语句中,这可能工作,但这不能保证并且编译器必须产生至少一个诊断消息(警告或错误) 根据 C 标准。
请注意,C 语言中空指针的值与底层架构无关。如果底层架构有一个定义为地址 0xDEADBEEF 的空指针值,则由编译器来解决这个问题。
因此,即使在这个有趣的架构上,以下方法仍然是检查空指针的有效方法:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
以下是检查空指针的无效方法:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
因为这些被编译器视为正常比较。
空字符
'\0'
被定义为空字符 - 即所有位都设置为零的字符。 '\0'
是(与所有字 rune 字一样)整数常量,在本例中值为零。所以 '\0'
完全等同于一个朴素的 0
整数常量 - 唯一的区别在于它传达给人类读者的意图 (“我将其用作空字符。”)。
'\0'
与指针无关。但是,您可能会看到类似于此代码的内容:
if (!*char_pointer)
检查 char 指针是否指向空字符。
if (*char_pointer)
检查 char 指针是否指向非空字符。
不要将它们与空指针混淆。仅仅因为位表示是相同的,并且这允许一些方便的交叉情况,所以它们实际上不是一回事。
引用资料
参见 Question 5.3 of the comp.lang.c FAQ更多。 参见 this pdf对于C标准。查看 6.3.2.3 指针部分,第 3 段。
关于c - NULL、 '\0' 和 0 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1296843/