指针给出了意想不到的值
Pointer is giving unexpected value
void first(){
int x;
int *p;
p= &x;
scanf("%d",p);
printf("The value in x or *p is: %d\n",x);
}
void second(){
int x;
int *ptr;
scanf("%d",&x);
printf("The value in *ptr is: %d\n",*ptr);
}
int main(){
first();
second();
}
在上面的代码中,second()
函数错过了 behaving.What 我为 x
变量赋予的任何值,该值被分配给 *ptr
以及X。为什么?
您没有为 p
赋值,因此它仍未初始化。试图取消引用该指针调用 undefined behavior.
给 p
一个值,您将得到您期望的结果:
int *p = &x;
您的代码仍在打印正确值的事实是未定义行为的一部分。未定义行为的表现形式之一是代码似乎可以正常工作,但随后看似无关的更改将导致它中断。
在这种特殊情况下,函数 first
和 second
分别定义了 2 个相同类型和相同顺序的局部变量。对 first
的调用完成后,包含该函数的 x
和 p
值的内存仍然包含这些值,但还没有其他函数调用覆盖它们。
当您在 first
之后立即调用 second
时。 second
中的变量 x
和 ptr
最终使用与 first
中的 x
和 p
相同的内存。而由于ptr
未初始化,所以它仍然包含旧值,即第一个x
的地址,恰好与second
中x
的地址相同.
同样,这是未定义的行为,因此您不能一直依赖这种情况。如果您向 first
添加了另一个变量或在 first
和 second
之间调用了另一个函数,这将修改之前由 first
使用的堆栈内存。然后内存将包含一些其他值,您可能会打印垃圾值或核心转储。
如果使用不同的编译器或不同的编译器选项编译,相同的代码可能会产生不同的结果。例如,另一个编译器可能会选择将每个函数中的变量以不同的顺序放在堆栈上,或者它可能会决定在函数 returns.
之后将函数使用的堆栈清零。
int *p=&x;
x 的地址存储在 p 中。
printf("%d",*p);
因为p有x的地址,所以*p的意思就是你要去p指定的位置去取物品,也就是x的值。
void first(){
int x;
int *p;
p= &x;
scanf("%d",p);
printf("The value in x or *p is: %d\n",x);
}
void second(){
int x;
int *ptr;
scanf("%d",&x);
printf("The value in *ptr is: %d\n",*ptr);
}
int main(){
first();
second();
}
在上面的代码中,second()
函数错过了 behaving.What 我为 x
变量赋予的任何值,该值被分配给 *ptr
以及X。为什么?
您没有为 p
赋值,因此它仍未初始化。试图取消引用该指针调用 undefined behavior.
给 p
一个值,您将得到您期望的结果:
int *p = &x;
您的代码仍在打印正确值的事实是未定义行为的一部分。未定义行为的表现形式之一是代码似乎可以正常工作,但随后看似无关的更改将导致它中断。
在这种特殊情况下,函数 first
和 second
分别定义了 2 个相同类型和相同顺序的局部变量。对 first
的调用完成后,包含该函数的 x
和 p
值的内存仍然包含这些值,但还没有其他函数调用覆盖它们。
当您在 first
之后立即调用 second
时。 second
中的变量 x
和 ptr
最终使用与 first
中的 x
和 p
相同的内存。而由于ptr
未初始化,所以它仍然包含旧值,即第一个x
的地址,恰好与second
中x
的地址相同.
同样,这是未定义的行为,因此您不能一直依赖这种情况。如果您向 first
添加了另一个变量或在 first
和 second
之间调用了另一个函数,这将修改之前由 first
使用的堆栈内存。然后内存将包含一些其他值,您可能会打印垃圾值或核心转储。
如果使用不同的编译器或不同的编译器选项编译,相同的代码可能会产生不同的结果。例如,另一个编译器可能会选择将每个函数中的变量以不同的顺序放在堆栈上,或者它可能会决定在函数 returns.
之后将函数使用的堆栈清零。int *p=&x;
x 的地址存储在 p 中。
printf("%d",*p);
因为p有x的地址,所以*p的意思就是你要去p指定的位置去取物品,也就是x的值。