在char * p = 0之后,指针p指向地址0x0或者没有指向任何东西?

时间:2012-07-02 18:21:15

标签: c

  

可能重复:
  Is NULL always zero in C?

以下代码:

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?

3 个答案:

答案 0 :(得分:5)

所有这些初始化

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

是等价的。所有这些都使用类型为char *空指针值初始化这些指针。该空指针值的物理表示是与平台相关的。不保证由物理0x0地址表示。没有办法说出他们一般会“指向”什么物理地址。

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

您看到的(null)输出是printf对您尝试将%s说明符与空指针一起使用的反应。这会导致未定义的行为,但您的标准库实现显然决定保存您的命运并打印(null)

实际上,代码示例中的每个printf语句都是错误组合的,每个语句都会导致未定义的行为。

答案 1 :(得分:3)

  

(null)代表什么?

这是printf()显然处理传递空指针值时打印字符串的请求的方式。指针值的标准格式说明符为%p

  

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

不一定。它们指向您平台上指向空指针的任何内容。

  

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

不,它只表示转换为unsigned int 时的空指针值作为指针传递给printf(),但重新解释为unsigned int(这是什么%x期望),结果为零。同样,指针的正确格式说明符是%p

答案 2 :(得分:0)

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

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