在指针变量中存储除零之外的整数常量

时间:2010-03-19 12:23:57

标签: c++ c

int main()
{

int *d=0;
printf("%d\n",*d);

return 0;
}

这很好。

>cc legal.c
> ./a.out
0

如果我将语句int *d=0;更改为int *d=1; 我看到了错误。

cc: "legal.c", line 6: error 1522: Cannot initialize a pointer with an integer constant other than zero.

所以很明显它只允许为零。我想知道当我们执行此操作时int *d=0内部会发生什么,这使得它成为有效的语法。

我只是出于好奇而问这个!

6 个答案:

答案 0 :(得分:5)

我很惊讶您运行代码时没有得到SEGFAULT。 printf语句中的*d取消引用指针。但是,要回答您的问题,C ++允许将0作为任何对象的默认初始值设定项,这就是为什么它可以用于将指针初始化为null(0和null相同)的原因。值为1时,您要求编译器将整数转换为指针,这需要显式转换。

答案 1 :(得分:3)

使用0初始化指针时,0会隐式转换为空指针。空指针的外观取决于您的平台,编译器将使用正确的二进制值。

当您尝试使用1(或任何其他非零整数)初始化指针时,编译器不知道将此值转换为有效指针并发出警告。

答案 2 :(得分:2)

您正在堆栈上创建一个名为d的指针变量,该变量被称为“指向一个整数”。然后将该指针变量赋值为0,使其指向有效的内存地址0x0(与C中的NULL相同。)

为了更清楚,int *d = 0与:

相同
   int *d;
   d = 0;       // set it to address 0

如果你想指向一个整数1,那么你需要这个:

   int x = 1;
   int *d = &x; // "set it to 'address of x'"

答案 3 :(得分:0)

如果* d = 0,则整数指针d被初始化为0,这是有效的。基本上你是在声明一个整数指针,所以初始化指针是有意义的。

但是,你不想初始化指针,而是初始化它指向的内存,这是不正确的。

执行* d = 1时,指针值变为1,当执行printf语句时,它将尝试访问地址1处的值,这是不允许的。

希望这有帮助。

答案 4 :(得分:0)

在“工作”示例中,您将取消引用空指针,并且语言将它找到的任何位作为参数放入printf。它的工作原理完全取决于编译器和机器的完全依赖于实现的功能,并且可能会在另一个实现中出现段错误。

代码工作似乎表明你的编译器在幕后做了一些奇怪的事情,试图“保护”编码器免于一个非常常见的错误;这是一个坏主意。我很想看看编译器使用cc -s

生成了哪个程序集

答案 5 :(得分:0)

在ISO-C99中,有两种类型的空指针常量:值为0的整数常量表达式 - 例如01 - 1(int)0.0 - 以及此类表达式转为void * - 例如(void *)0,通常用于定义NULL

将空指针常量转换为任意指针类型会产生该类型的空指针。此转换是隐式的,但实际上可能涉及地址转换,因为标准不需要空指针来使位代表0。

此转换也是为函数指针类型定义的,即使将对象指针转换为函数指针通常也是非法的:

void (*foo)(void) = (void *)0;           // valid
void *bar = 0;                           // valid
void (*baz)(void) = (void (*)(void))bar; // invalid even with explicit cast

这也意味着您可以使用0初始化任何标量类型而不进行强制转换,并且它是唯一的值,这是真的:将0转换为指针类型将始终产生空指针,转换任何其他整数值是可能的,但需要显式转换,具有实现定义的结果,并且可能由于对齐或地址空间限制而失败。