3

可能的重复:
C 中的 NULL 总是为零吗?

以下代码:

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

if (NULL == 0)
    printf("the NULL is same as 0\n");

printf("0 : %s\n", 0);
printf("p1 : %s\n", p1);
printf("p1 : %x\n", p1);
printf("&p1 : %x\n", &p1);

printf("NULL : %s\n", NULL);
printf("p2 : %s\n", p2);
printf("p2 : %x\n", p2);
printf("&p2 : %x\n", &p2);
printf("*p2 : %s\n", *p2);

输出:

the NULL is same as 0
0 : (null)
p1 : (null)
p1 : 0
&p1 : bf9a0204
NULL : (null)
p2 : (null)
p2 : 0
&p2 : bf9a0208
Segmentation fault (core dumped)

我想知道:

(null) 代表什么?

指针 p1 或 p2 是否指向地址 0x0?

语句是否 printf("p1 : %x\n", p1); 输出 p1 : 0 表示 p1 指向地址 0x0?

4

3 回答 3

6

所有这些初始化

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

是等价的。它们都使用类型为 的空指针值初始化这些指针char *。该空指针值的物理表示取决于平台。不保证用物理0x0地址表示。没有办法说他们通常会“指向”什么物理地址。

0x0根据输出判断,在您的平台上,空指针值恰好由物理地址表示。但是,打印指针值的正确方法printf是使用%p格式说明符,或者将指针值转换为合适的整数类型。使用%x打印指针会导致未定义的行为。

您看到的(null)输出是printf对您尝试使用%s带有空指针的说明符的反应。这会导致未定义的行为,但您对标准库的实现显然决定让您免于更糟糕的命运并(null)改为打印。

事实上,printf您的代码示例中的每一条语句的组成都不正确,每条语句都会导致未定义的行为。

于 2012-07-02T18:25:19.090 回答
3

(null) 代表什么?

当传递一个空指针值时,它显然是如何printf()处理打印字符串的请求的。指针值的标准格式说明符是%p

指针 p1 或 p2 是否指向地址 0x0?

不必要。它们指向平台上空指针指向的任何位置。

语句是否 printf("p1 : %x\n", p1); 输出 p1 : 0 表示 p1 指向地址 0x0?

不,它仅表明空指针值在转换为unsigned int作为指针传递给 printf() 时,但被重新解释为unsigned int(这是 %x 所期望的),导致值为零。同样,指针的正确格式说明符是%p.

于 2012-07-02T18:25:16.850 回答
0

NULL通常定义为数值 0,通常转换为指针类型(主要是void *)。但是,C 标准不保证 NULL 指针为零;有些平台(尤其是奇怪的旧硬件,一些嵌入式系统等)是另一个非法内存地址。

但是,您可以使用空指针进行操作,就好像它始终为零一样。写作if (pointer)转换为if (pointer != NULL); 此外,当遇到分配或与指针比较的零值时,大多数编译器将其视为其中包含 NULL 的操作,即使它在技术上非零。

于 2012-07-02T18:46:12.177 回答