繁体   English   中英

为什么指针在声明后初始化和取消引用时会给出垃圾/随机值?

[英]Why does a pointer gives a garbage/random value on initializing and de-referencing after declaration?

代码片段-1

int x=3;   
int *p=&x; 
printf("x= %d\n",x);
printf("p= %d\n",*p);

代码片段-2

int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);

Snippet-1 给出 output x=3 & p=3,但 snippet-2 给出 x=3 & p=一些随机值

请解释

这一行:

int *p=&x;

是带有初始化的p声明 它将p (一个int * )初始化为&x

相比之下,这一行:

*p=&x;

是一个任务 它首先取消引用p ,然后将&x分配给取消引用的 object。 这是错误的,原因有二:

  • p没有指向任何地方,因此尝试取消引用它会调用undefined behavior
  • 即使p确实指向某个地方,您也会尝试将int *分配给int

此代码段具有未定义的行为

int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);

因为指针p未初始化并且具有不指向有效 object 的不确定值。 所以这个说法

*p=&x;

通过取消引用指针 ( *p ) 试图访问无效地址的 memory。

似乎相反,这种说法

*p=&x;

你的意思是

p = &x;

即指针获取变量x的地址。

注意printf这种调用的输出信息

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

令人困惑。 最好写

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

即输出的不是指针本身的值,而是输出的指向的object的值。

您应该区分声明和表达式中星号的含义。

在这样的声明中

int *p=&x; 

星号表示这里声明了一个指针,它获取变量 x 的地址。

在这样的表达式语句中

*p=&x;

星号表示解引用运算符,用于通过存储在用作地址的指针中的值访问指向的 object。

int *p=&x; 相当于

int *p;
p = &x; // <== p, not *p

p = &x获取变量 x 的地址,并将其放在p (它是一个指针)中。

这与您在片段 2 中所做的不同

*p = &x; // Not the same

*p = &x获取变量 x 的地址,并将其放在p指向的位置。 因此, p仍然指向同一个位置,但该位置写入了不同的值。 (并且因为p没有初始化,它没有指向任何有用的东西,导致未定义的行为)

int *p = &x;

(在第一个片段内)

不同于

int *p;
*p = &x;

(在第二个片段内)

在第一种情况下,您通过x的地址初始化p

在第二种情况下,当在第二个语句中使用*p时,您取消引用指向无效 object 的p并尝试将x的地址分配给不存在的 object p应指向的地址,这会调用未定义的行为

通常这应该在编译时至少给你一个警告。 如果未显示,请引发编译器警告。

声明中的*用于指示指针。

声明后的*用于取消引用指针。


如果您希望代码段 2 正常运行,则需要在分配时省略*

int x;
int *p;

x = 3;
p = &x;            // No * operator here.

printf("x = %d\n", x);
printf("*p = %d\n", *p);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM