在C语言中,各种零值之间似乎存在差异——NULL、NUL和0。

我知道ASCII字符“0”的值为48或0x30。

NULL指针通常定义为:

#define NULL 0

Or

#define NULL (void *)0

此外,还有NUL字符“\0”,它的值似乎也是0。

是否存在这三个值不能相等的情况?

在64位系统上也是这样吗?


当前回答

一篇帮助我开始学习C语言的好文章(摘自Linden的Expert C Programming)

一个l为空,两个l为空

记住这个小押韵来回忆指针和ASCII零的正确术语:

The one "l" NUL ends an ASCII string,

The two "l" NULL points to no thing.

Apologies to Ogden Nash, but the three "l" nulll means check your spelling. 

位模式为0的ASCII字符称为“NUL”。 特殊的指针值意味着指针不指向任何地方是“NULL”。 这两个词在意思上是不可互换的。

其他回答

在ASCII表中,值为0x00的字节是称为NUL或NULL的特殊字符。在C语言中,因为你不应该在源代码中嵌入控制字符,所以这是用C字符串表示的,带有一个转义0,即\0。

但是一个真NULL不是一个值。它是一个值的缺失。对于指针来说,这意味着指针没有可指向的对象。在数据库中,它意味着字段中没有值(这与字段为空白、0或填充空格不同)。

给定的系统或数据库文件格式用来表示NULL的实际值不一定是0x00。

NULL不能保证为0——它的确切值取决于体系结构。大多数主流架构将其定义为(void*)0。

'\0'将总是等于0,因为这是字节0在字符字面值中编码的方式。

我不记得C编译器是否被要求使用ASCII——如果不是,'0'可能并不总是等于48。无论如何,除非您在非常晦涩的系统上工作,否则您不太可能遇到使用像EBCDIC这样的替代字符集的系统。

各种类型的大小在64位系统上有所不同,但整数值是相同的。


一些评论者表示怀疑NULL等于0,但不是0。下面是一个示例程序,以及在这样一个系统上的预期输出:

#include <stdio.h>

int main () {
    size_t ii;
    int *ptr = NULL;
    unsigned long *null_value = (unsigned long *)&ptr;
    if (NULL == 0) {
        printf ("NULL == 0\n"); }
    printf ("NULL = 0x");
    for (ii = 0; ii < sizeof (ptr); ii++) {
        printf ("%02X", null_value[ii]); }
    printf ("\n");
    return 0;
}

该程序可以输出:

NULL == 0
NULL = 0x00000001

一个1 - l的NUL,它结束一个字符串。

一个2l的NULL不指向任何东西。

我要赌一只金牛

没有3l null。

你如何处理NUL?

一篇帮助我开始学习C语言的好文章(摘自Linden的Expert C Programming)

一个l为空,两个l为空

记住这个小押韵来回忆指针和ASCII零的正确术语:

The one "l" NUL ends an ASCII string,

The two "l" NULL points to no thing.

Apologies to Ogden Nash, but the three "l" nulll means check your spelling. 

位模式为0的ASCII字符称为“NUL”。 特殊的指针值意味着指针不指向任何地方是“NULL”。 这两个词在意思上是不可互换的。

这三者在不同的上下文中定义了0的含义。

指针上下文-使用NULL,表示指针的值为0,与它是32位还是64位无关(一种情况是4字节,另一种情况是8字节的零)。 string context -表示数字0的字符的十六进制值为0x30,而NUL字符的十六进制值为0x00(用于终止字符串)。

当你查看内存时,这三个总是不同的:

NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20

我希望这能解释清楚。