C 为什么';t fun(int*p)改变指针的值?
我对指针有一定的了解,但是我猜C 为什么';t fun(int*p)改变指针的值?,c,pointers,C,Pointers,我对指针有一定的了解,但是我猜printf应该显示10,尽管网站的编译器和其他编译器说值仍然是20 有人能解释为什么吗 fun()对指针p有影响吗?为什么或为什么不?如果p是一个函数参数,则函数体内部的p=something不会更改调用站点的值。无论p是否是指针 你把它和*p=something和p[foo]=something混淆了,如果p是一个函数参数,那么函数体内部的p=something不会改变调用站点的值。无论p是否是指针 你把它和*p=something和p[foo]=somethi
printf
应该显示10,尽管网站的编译器和其他编译器说值仍然是20
有人能解释为什么吗
fun()对指针
p
有影响吗?为什么或为什么不?如果p
是一个函数参数,则函数体内部的p=something
不会更改调用站点的值。无论p
是否是指针
你把它和
*p=something
和p[foo]=something
混淆了,如果p
是一个函数参数,那么函数体内部的p=something
不会改变调用站点的值。无论p
是否是指针
你把它和
*p=something
和p[foo]=something
混淆了,函数中的p主要得到p的值,因此是r的地址,然后在函数中你把q的地址分配给函数中的p。但是main中的指针p完全不受fun中的指针p的影响,因此main中的指针p仍然具有变量r的地址。显然,现在你知道它为什么打印20了。函数中的p得到main中p的值,从而得到r的地址,然后在函数中你将q的地址分配给函数中的p。但是main中的指针p完全不受fun中的指针p的影响,因此main中的指针p仍然具有变量r的地址。显然,现在您知道它为什么打印20了。指针按值传递,更改被本地化为fun()。如果要更改main可以看到的*p,而不是指针本身的更改。指针是按值传递的,更改将本地化为fun()。如果要更改*p,main将看到它,而不是指针本身的更改。如果函数中的代码是:
void fun(int *p)
{
int q = 10;
p = &q;
}
int main()
{
int r = 20;
int *p = &r;
fun(p);
printf("%d", *p);
return 0;
}
这会将p所指地址内的值更改为变量q(函数的本地变量)所持有的值。如果函数内的代码为:
void fun(int *p)
{
int q = 10;
p = &q;
}
int main()
{
int r = 20;
int *p = &r;
fun(p);
printf("%d", *p);
return 0;
}
这会将p所指向的地址内的值更改为变量q所持有的值(函数的本地值)。fun()内的变量“p”是堆栈上的本地指针。您将p重新指定为指向q(也是一个本地指针),但当该函数存在时,堆栈帧将弹出,值和指针将消失
如果希望fun()
实际修改调用函数中变量的值,请尝试更改行:
*p = q;
将是:
p = &q;
这实际上是将q
(10)的值写入p
指向的地址,而不是重新分配p
指向其他对象。中的变量“p”是堆栈上的本地指针。您将p重新指定为指向q(也是一个本地指针),但当该函数存在时,堆栈帧将弹出,值和指针将消失
如果希望fun()
实际修改调用函数中变量的值,请尝试更改行:
*p = q;
将是:
p = &q;
这实际上是将
q
(10)的值写入p
指向的地址,而不是重新分配p
指向其他地址。在C中,传入函数的值是按值传递的;也就是说,它们被复制到函数中。fun
中的p
是main
中的p
的副本。此副本被更改,然后在fun
返回时丢弃,使main
中的p
保持不变
顺便说一句,如果它像您预期的那样工作,printf
可能不会打印10
。fun
中的变量q
是本地变量,并在fun
退出后立即销毁。实际上,这通常意味着它仍在内存中,但在堆栈结束之后*;调用printf
可能会用一些printf
的参数或其他本地数据覆盖q
*事实上,由于它从来没有被使用过,除了为
p
获取它的地址,而p
也从来没有被使用过,在实践中,编译器将完全优化它,除非在C中使用-O0,传递到函数中的值是按值传递的;也就是说,它们被复制到函数中。fun
中的p
是main
中的p
的副本。此副本被更改,然后在fun
返回时丢弃,使main
中的p
保持不变
顺便说一句,如果它像您预期的那样工作,printf
可能不会打印10
。fun
中的变量q
是本地变量,并在fun
退出后立即销毁。实际上,这通常意味着它仍在内存中,但在堆栈结束之后*;调用printf
可能会用一些printf
的参数或其他本地数据覆盖q
*事实上,由于它从来没有被使用过,除了为p
获取其地址之外,而p
的地址也从来没有被使用过,因此在实践中,编译器将完全优化它,除非您使用-O0将指向函数的指针的副本作为参数。因此,该函数无法更改原始值。
您可能希望给出指向指针的指针,这使函数能够更改指向的指针
*p = q;
然而,这是相当危险的,更不用说疯狂了。
在我的示例中,我将局部变量更改为static,以避免返回指向局部变量的指针的最可怕后果。
您可能需要在相当大的范围内重新设计以获得干净的解决方案