在C中,为什么将指针初始化为0并不会产生编译时错误?

时间:2016-08-07 17:42:12

标签: c pointers segmentation-fault

我正在玩指针,我尝试使用值而不是内存位置初始化指针变量。

如果我正在初始化一个非零值的指针,那么它显然给了我一个编译时错误。

int *p = 1;
main.c:14:14: error: initialization makes pointer from integer without a cast [-Werror=int-conversion]
 int *p = 1;
          ^

但是,如果我将其初始化为值0,它不会给我一个编译时错误。

int *p = 0; //no compile time error but segmentation fault

为什么会这样?是否有一个有效的内存地址,如0?通常,地址位置显示为0xffffff或类似方式。如何将0解释为内存位置?

由于

5 个答案:

答案 0 :(得分:4)

从C11标准(草案):

  

6.3.2.3指针

     

[...]

     

3 一个整数常量表达式,其值为0,或者这样的表达式强制转换为类型   void *被称为空指针常量。如果将空指针常量转换为a   指针类型,结果指针,称为空指针,保证比较不等   指向任何对象或函数的指针。

答案 1 :(得分:3)

Usualy 0代表NULL的“无地址”。当您以这种方式使用它时,您可以检查:

if (p) {
     doSomthingWith(*p)
}

答案 2 :(得分:2)

您可以将0分配给指针,因为NULL通常被定义为0强制转换为void *。任何其他整数值都是类型不匹配。

虽然您可以将一些其他整数值转换为指针以为其赋值,但除非您正在处理特定内存位置已知用途的嵌入式环境,否则很少这样做。

你得到一个段错误不是因为你打印指针而是因为你取消引用指针并尝试打印它所指向的内容。因为指针具有NULL值,所以取消引用它会导致未定义的行为。在这种情况下,它会导致段错误。

要打印指针,请执行以下操作:

printf("%p\n", (void *)p);

答案 3 :(得分:1)

指针上下文中的文字0表示空指针常量。 1始终只是1,因此只有int

答案 4 :(得分:1)

  

为什么会这样?是否有一个有效的内存地址,如0?通常,一个   地址位置显示为0xffffff或类似方式。怎么样0   解释到内存位置?

通常,大多数操作系统都无法访问地址0,因为它们会将其保留用于其他任务。

在C中,地址0被解释为NULL指针,NULL指针是一个指针,被解释为不引用程序可访问的有效内存位置的指针。 因此,如果您定义int* p = 0int* p = NULL,则用C编写的程序假定指针指向任何内容(不是0xffffff地址)。