将指针传递给函数值不改变
#include void foo(int*); int main() { int i = 97, *p = &i; foo(p); printf("%d ", *p); getch(); } void foo(int *p) { int j = 2; p = &j; printf("%d ", *p); }
输出是2 97为什么不是2 2? 指针p现在保存j的地址,为什么要打印97?
你可以通过以下方式想象函数调用及其定义。 为清楚起见,我将函数参数重命名为q
。
foo(p); void foo( /*int *q*/ ) { int *q = p; int j = 2; q = &j; printf("%d ", *q); }
可以看出,函数参数(在本例中为q
)是函数的局部变量,该函数由参数的值初始化(在本例中由参数p
的值)
因此局部变量( q
)的任何变化都不会影响原始参数( p
)。
退出函数后,局部变量将不会处于活动状态。
如果要更改参数本身,则应通过引用传递它。 例如
void foo( int **p ) { int j = 2; *p = &j; printf("%d ", **p); }
但是在退出函数之后,原始参数/变量p
将是无效的,因为它存储函数j
的非活动局部变量的地址。
因此,尝试访问函数的局部变量j
占用的内存会导致程序的未定义行为。
您可以通过将局部变量j
声明为具有静态存储持续时间来使程序正确。 例如
void foo( int **p ) { static int j = 2; *p = &j; printf("%d ", **p); }
并调用函数
foo(&p);
在foo
,为p
分配一个新值。 但是,这是main
中p
值的副本 ,因此在main
中看不到更改。
如果你取消引用 p
,那么如果i
在main中它将改变值:
void foo(int *p) { *p = 2; printf("%d ", *p); }
p = &j;
只是改变局部变量p
的值。 这对调用者的p
变量没有影响(因为p
是按值传递的)或者是之前指向的p
的变量(因为你没有间接通过它)。 如果要更改调用者的数据,请写入:
*p = j;
逐行浏览上面的代码。 在这里我写了评论,因为控制遍历每一行……
#include void foo(int*); int main() { int i = 97, *p = &i; //Lets assume i has address 2000 foo(p); //p contains 2000 which is passed to foo. go to foo at 1. printf("%d ", *p); // when control comes back no change to p it //still points to 2000 which stores 97 getch(); } void foo(int *p) 1: // in foo another local variable p is created. //Let's call this lp. lp has now address 2000. ie lp //and p both point to i but one locally exists in a // function and will be destroyed when control comes out // of the function { int j = 2; p = &j; // now local p ie lp points to another var j // address. Suppose lp has address 3000 now. printf("%d ", *p); //val at address in lp is 2 }