C NULL和#x27之间有什么区别\0';0呢?

C NULL和#x27之间有什么区别\0';0呢?,c,pointers,null,C,Pointers,Null,在C语言中,各种零值--NULL、NUL和0之间似乎存在差异 我知道ASCII字符'0'的计算结果为48或0x30 NULL指针通常定义为: #define NULL 0 或 此外,还有NUL字符'\0',它的计算结果似乎也是0 这三个值是否有时不相等 这对64位系统也是如此吗?< < P> > P> 注:< /强>此答案适用于C语言,而不是C++ +< /P> 空指针 整数常量literal0具有不同的含义,具体取决于其使用的上下文。在所有情况下,它仍然是一个值为0的整数常量,只是用不同的

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

我知道ASCII字符
'0'
的计算结果为
48
0x30

NULL
指针通常定义为:

#define NULL 0

此外,还有
NUL
字符
'\0'
,它的计算结果似乎也是
0

这三个值是否有时不相等


这对64位系统也是如此吗?< < P> > P> <强>注:< /强>此答案适用于C语言,而不是C++ +< /P>


空指针 整数常量literal
0
具有不同的含义,具体取决于其使用的上下文。在所有情况下,它仍然是一个值为
0
的整数常量,只是用不同的方式描述了它

如果将指针与常量文本
0
进行比较,则这是检查指针是否为空指针。该
0
随后被称为空指针常量。C标准定义类型
void*
0
cast既是空指针又是空指针常量

if (pointer == 0)
if (!pointer)
此外,为了帮助可读性,头文件
stddef.h
中提供了宏
NULL
。根据编译器的不同,可以
#undef NULL
并将其重新定义为古怪的内容

因此,以下是一些检查空指针的有效方法:

if (pointer == NULL)
int mynull = 0;
<some code>
if (pointer == mynull)
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
NULL
定义为与空指针进行比较。只要是有效的空指针常量,
NULL
的实际定义就是实现定义的

if (pointer == 0)
if (!pointer)
0
是null指针常量的另一种表示形式

if (pointer == 0)
if (!pointer)
这个
if
语句隐式地检查“is not 0”,所以我们将其反转为“is 0”

以下是检查空指针的无效方法:

if (pointer == NULL)
int mynull = 0;
<some code>
if (pointer == mynull)
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
以下是检查空指针的无效方法:

if (pointer == NULL)
int mynull = 0;
<some code>
if (pointer == mynull)
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
因为这些被编译器视为正常的比较

空字符
“\0”
定义为空字符-即所有位均设置为零的字符<代码>“\0”与所有字符文字一样是一个整数常量,在本例中为零。因此,
'\0'
完全等同于一个未经修饰的
0
整数常量-唯一的区别在于它传达给人类读者的意图(“我将其用作空字符”)

“\0”
与指针无关。但是,您可能会看到类似于此代码的内容:

if (!*char_pointer)
检查字符指针是否指向空字符

if (*char_pointer)
检查字符指针是否指向非空字符

if (*char_pointer)
不要将这些与空指针混淆。仅仅因为位表示是相同的,并且这允许一些方便的交叉情况,它们实际上并不相同

工具书类 更多信息,请参阅。
有关C标准,请参见。查看第6.3.2.3节指针,第3段。

NULL
不保证为0——其精确值取决于体系结构。大多数主要架构都将其定义为
(void*)0

“\0”
将始终等于0,因为字节0在字符文字中的编码方式是这样的

#include <stdio.h>

int main(void) {
    printf("%d", sizeof('\0'));
    return 0;
}
我不记得C编译器是否需要使用ASCII——如果不是,则
'0'
可能并不总是等于48。无论如何,除非您使用的是非常模糊的系统,否则您不太可能遇到使用EBCDIC等替代字符集的系统

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


一些评论者表示怀疑NULL是否等于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;
}
“NUL”不是0,而是指ASCII NUL字符。至少,我是这么看的。空指针通常定义为0,但这取决于您运行的环境,以及您使用的任何操作系统或语言的规范


在ANSI C中,null指针被指定为整数值0。因此,任何不符合ANSI C标准的世界都是不符合ANSI C标准的。

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

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


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

这三个值在不同的上下文中定义了零的含义

  • 指针上下文-使用NULL,表示指针的值为0,与它是32位还是64位无关(一种情况是4字节,另一种情况是8字节的零)
  • 字符串上下文-表示数字零的字符的十六进制值为0x30,而NUL字符的十六进制值为0x00(用于终止字符串)
当您查看内存时,这三个始终是不同的:

NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20
我希望这能澄清这一点。

C常见问题解答列表中也解决了这个问题:

C程序员必须理解这一点
NULL
0
在中可以互换 指针上下文,并且该上下文为uncast
0
这是完全可以接受的。任何使用 NULL(与
0
相反)应为空 被认为是一个温柔的提醒 涉及指针;程序员 不应依赖于