c语言问题

程序一
#include<stdio.h>
void fun(int *a,int *b)
{int *c;
c=a;a=b;b=c;
}
void main()
{int x=3,y=5,*p=&x,*q=&y;
fun(p,q);printf("%d,%d ",*p,*q);
fun(&x,&y);printf("%d,%d\n",*p,*q);
}
程序二
#include<stdio.h>
void swap(int *p,int *q)
{int t;
t=*p;
*p=*q;
*q=t;
}
main()
{int x,y,t;
scanf("%d%d",&x,&y);
swap(&x,&y);
printf("%d,%d\n",x,y)
请问为什么程序而可以实现两数交换,而一不可以?不都是指针吗??求解求解

关键在于“指针”和“指针所指向的值”、函数参数传递的原理,这3个概念弄明白就知道了:
程序一中代码:
void fun(int *a,int *b){
int *c; c = a; a = b; b = c;

}
这里面 c、 a 、b都是指针,*a 、 *c(程序二中的*p、*q)这是指针所指向的值。
假设程序运行时,
&x=111111,&y = 222222,
c=333333,a=111111,b = 222222 ,这么几串代表了 int值*c、*a、*b在内存中的地址(可以理解成门牌号)。

把&x、&y传给fun()函数时,只是把x、y的地址的大小数值(111111 、222222)复制了一份给a、b,
然后a、b交互,a、b大小的改变完全不会影响到x、y,所以x、y实际地址没有交换。

那么 int *c; c = a; a = b; b = c; 这几句代码只是交互了他们的门牌号,没有交换门里面的家具(原来的x、y的int值)。

而程序二,虽然也只是传递进来x、y门牌号的复制(可以理解成fun()把这两个门牌号抄写在了自己的记事本上),但是fun()函数根据这两个门牌号找到了家具,并且把家具搬运、互换了。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-08-15
注意一点,1中是指针指向的改变,而2中的是指针指向地址值的改变,函数在传递参数时传递的是参数的拷贝,不是变量本身,对变量的值的改变不影响调用部分实参的指向。追问

请问,我怎么判断是指针指向地址值的改变?

追答

对指针直接赋值就是改变他的指向

第2个回答  2015-08-15

这类问题我都回答烦了,解释半天原理还是解释不清楚。这次不求采纳,干脆直接给一个实践性的建议好了:

C语言里,如果一个函数中存在修改参数的语句(不管参数是什么类型),例如下面这样

void func(...,int a,...){
...
a=something;//对参数a进行了修改操作。
}

而且你的本意确实是想对参数本身进行修改,那就直接在该参数上加一级指针,修改成如下:

void func(...,int* /*加一级指针*/ a,...){
...
*a=something;
}

即便那个参数本身就是个指针,如果有对该指针本身的修改,就依然遵照上述规则进行代码修正。例如:

void foo(...,int ****a,...){
...
*a=something;//注意这句话不能视为对参数a本身的修改,如果没有下一句话的存在,我们并不需要修正这个函数
a=another;//这句话才是对参数a本身的修改。由于这句话的存在,我们需要对函数参数进行修正
}

应修正为:

void foo(...,int *****a/*不管原来几个星号,再加一个*/,...){
...
**a=something;
*a=another;
}