代码片段-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给出的输出是x=3 & p=3,但snippet-2给出的是x=3 & p=。一些随机值
请解释
int *p=&x;
相当于
int *p;
p = &x; // <== p, not *p
p = &x
取变量x的地址,并将其置于 p
(这是一个指针)。
这就是 异于 你在snippet-2中做了什么?
*p = &x; // Not the same
*p = &x
取变量x的地址,并将其放置在变量x指向的位置。p
. 所以.., p
仍然指向同一个位置,但这个位置的值已经被写入了不同的值。(而且因为 p
没有被初始化,它没有指向任何有用的东西,导致未定义的行为)
这条线。
int *p=&x;
是一个 声明 的 p
与初始化。 它初始化了 p
,这是一个 int *
,至 &x
.
相反,这一行。
*p=&x;
是一个... 任务. 它先是引申出 p
然后指定 &x
到被取消引用的对象。 这是错的,原因有二。
p
它没有指向任何地方,所以试图去引用它就会调用 未定义行为.p
确实指向了某个地方,你会试图分配一个 int *
到一个 int
.这段代码有未定义的行为
int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);
因为指针 p
没有被初始化,并且其值不确定,不指向一个有效的对象。所以这条语句
*p=&x;
通过取消引用指针( *p
)正试图在一个无效的地址访问内存。
似乎这条语句代替了
*p=&x;
你的意思是
p = &x;
也就是指针获得的变量地址 x
.
请注意,这样的调用printf的输出信息
printf("p= %d\n",*p);
是令人困惑的。最好写成
printf("*p= %d\n",*p);
就是说输出的不是指针本身的值,而是输出的是指向对象的值。
你应该区分声明和表达式中星号的含义。
在像这样的声明中
int *p=&x;
星号表示这里声明了一个指针,它得到的是变量x的地址。
在这样的表达式语句中
*p=&x;
星号表示去引用操作符,该操作符用于通过存储在作为地址的指针中的值来访问指向的对象。
int *p = &x;
(在第一个片段中)
与
int *p;
*p = &x;
(下)
在第一种情况下,你初始化了 p
按地址 x
.
在第二种情况下,当使用 *p
在第二句话中,你转引自 p
的地址,并试图将其分配给无有效对象。x
到不存在的对象 p
指的是 未定义行为.
通常这应该在编译时给你至少一个警告。如果没有显示,则发出编译器警告。
这个 *
在声明处用来表示指针。
语句处的 *
后的声明用于取消对指针的引用。
如果您想让代码段 2 正常运行,您需要省略声明后的 *
在任务。
int x;
int *p;
x = 3;
p = &x; // No * operator here.
printf("x = %d\n", x);
printf("*p = %d\n", *p);