关于指针和形参结合的一个程序的分析

来源:互联网 发布:端口号是干嘛的 编辑:程序博客网 时间:2024/06/04 18:13
今天在组里打赌打输了,发现指针还是有需要理解的部分...特将这个例子记录如下。
故事的发展梗概是,我认为下列程序会输出正确答案(10),而组内的另外两名同学则认为会出现错误(不能输出10)。于是,打赌开始。

#include <stdio.h>
int b = 10;
void fun(int* a)
{
 a = &b;
}

int main()
{
int *p=NULL;
fun(p);
printf("%d",*p);
}


遗憾的是,我输掉了。正确的解决思路如下:
一开始,p初始化为空,假如p存在地址为2000H的地方,那么2000H这里的值应该是0(这里需要区分指针存放的地址和指针指向的地址)。
当调用fun函数的时候,传过去的是0,而非2000H,也即传过去的是p的值,而非p的地址,这里一定要注意!
当调用函数的时候,参数是通过堆栈来传递的。在这个例子中,main函数调用fun时,参数p入栈,因此,这里入栈的值为0(不是2000H,切记)。当fun函数执行的时候,从堆栈中拿出相应的值(0)并赋值给相应的形参,因此就相当于有一个默认的初始化,int *a = 0;
也即,a是一个指针,指向的地址为0。因此,当修改了a = &b的时候,实际是让a的值(也就是指针指向的地址)变成了b的地址,但是a是在堆栈中的,其地址肯定不等于p的地址。当fun函数返回时,堆栈释放,a中的内容也就消失了。因此,尽管a指向了b,但是p没有指向b
随后返回,printf,出错,因为p仍然指向NULL。

因此,还是应该深刻理解函数调用时,传递参数的过程,以及理解当传递的参数是指针的时候,编译器是如何处理的。