为什么不开心(int * p)改变指针的值?

时间:2018-01-08 18:54:38

标签: c pointers

void fun(int *p) 
{ 
  int q = 10; 
  p = &q; 
}     

int main() 
{ 
  int r = 20; 
  int *p = &r; 
  fun(p); 
  printf("%d", *p); 
  return 0; 
}

我对指针有所了解,但是我猜我printf应该显示10,尽管网站的编译器和其他编译器说这个值仍为20.

任何人都可以解释原因吗?

fun()对指针p有影响吗?为什么或为什么不呢?

8 个答案:

答案 0 :(得分:2)

如果p是函数参数,则函数体内的p = something不会更改调用站点的值。 p是否为指针并不重要。

您将其与*p = somethingp[foo] = something混淆。

答案 1 :(得分:1)

指针按值传递,更改本地化为fun()。如果你要改变主要看到的* p,而不是改变指针本身。

答案 2 :(得分:1)

变量" p" inside fun()内部是堆栈上的本地指针。你重新分配p指向q(也是一个本地指针)但是当该函数存在时,弹出堆栈帧,值和指针消失。

如果您希望fun()实际修改调用函数中变量的值,请尝试更改该行:

p = &q;

是:

*p = q;

这实际上将q(10)的值写入p指向的地址,而不是重新分配 p以指向某事物其他

答案 3 :(得分:1)

您将函数指针的副本作为参数提供。所以功能不能改变原来的功能 您可能想要指向指针,这使该函数能够改变指向指针。

void fun(int **p) 
{ 
  static int q = 10; 
  *p = &q; 
}     

int main() 
{ 
  int r = 20; 
  int *p = &r; 
  fun(&p); 
  printf("%d", *p); 
  return 0; 
}
然而,这很危险,更不用说疯了 在我的例子中,我将局部变量更改为静态,以避免将指针返回到局部变量时最可怕的后果。
您可能需要在相当大的范围内重新设计,以便为您正在尝试的任何事情获得一个干净的解决方案。

答案 4 :(得分:0)

函数中的p得到p的值,因此得到r的地址,然后在函数中将q的地址赋给函数中的p。但是main中的指针p完全不受指针p的影响,因此main中的指针p仍然具有变量r的地址。显然现在你知道为什么打印20。

答案 5 :(得分:0)

如果您在函数中的代码是:

,那么您的期望将成立
*p = q;

这会将p指向的地址内的值更改为变量q(该函数的本地值)所持有的值。

答案 6 :(得分:0)

在C中,传递给函数的值按值传递 ;也就是说,它们被复制到函数中。 fun中的pmainfun的副本。此副本已更改,然后在p返回时被丢弃,main中的printf保持不变。

顺便说一句,如果 按预期工作,10可能不会打印qfun中的变量fun是本地变量,只要printf退出就会被销毁。在实践中,这通常意味着它仍然在内存中,但在堆栈结束后*;对q的调用可能会使用printf的某些参数或其他本地数据覆盖p

*实际上,由于除了使用-O0的地址之外从未使用它,而YesNoControl的地址从未使用过,实际上编译器会完全优化它,除非你使用<div id="yes_no"> <input id="yes_no_1" name="yes_no" value="1" type="radio"/> <label for="yes_no_1">Yes</label> <input id="yes_no_2" name="yes_no" value="2" type="radio"/> <label for="yes_no_2">No</label> </div>

答案 7 :(得分:0)

在函数fun之外(main内部),变量'q'不存在,因此它的地址不存在于p中。当您在main函数中取消引用'p'时,它的地址为'r'而不是'q'。如果您在乐趣中取消引用'p',它将具有'q'的地址并显示10。