赞
踩
要通过函数调用修改实参的值,首先我们要明白函数调用过程中的传参方式与返回方式:
传参方式:在c语言里面,所有的参数传递都是单向的值传递,就算是我们常说的地址传递,其本质上也是一种值传递,不过地址传递传递的是一串地址数字
返回方式:我所总结的返回方式有两种,一种是可以返回主函数的,一种是无法返回主函数的,具体如下:
比如我们常用的递归调用
int func(int n){
int sum;
if(n<0)printf("请输入大于0的整数!");
else if(n==1||n==0)sum=1;
else sum=n*func(n-1);
return sum;
}
int main(){
int num,multi;
int func(int n);
scanf("%d",&num);
multi=func(num);
printf("%d",sub);
}
func函数里面的临时变量sum,是我们创建出来的,可以直接返回主函数,而func函数里面的形参n,虽然系统调用函数时也会创建’'n"这个临时变量,但是这个形参是无法返回的,这个形参的改变也影响不到主函数里面实参num的值
相信大家已经了解到我想说的了,我总结出来的,这个临时变量能不能返回,看的就是这个临时变量是谁创建的
好,那我们接下来步入本博文的重点,关于如何调用函数来修改主函数里实参的值
通过不调用函数的思路,我们可以总结出三种貌似可行的方法:
我们先来看第一种方法——调用函数—实参本身改变
int main(){
int x=3,y=4;
change(x,y);
if(x==3&&y==4)printf("修改失败!");
else if(x==4&&y==3) printf("修改成功!");
return 0;
}
int change(int a,int b){
int temp;
temp=a;
a=b;
b=temp;
}
结果如下:修改失败! Process returned 0 (0x0) execution time : 0.316 s Press any key to continue.
这是为什么呢?首先我们知道,函数实参传参过去之后,系统会自动创建两个形参a和b,a和b的值即x与y的值,但是当change函数执行完成之后,a和b这两个变量会被释放,而x与y则毫无改变,用一张图解释这个过程:
接下来我们来看第二种方法—调用函数—指针指向改变<即修改指针变量的值>
int main(){
int x=3,y=4,*point_1=&x,*point_2=&y;
change(point_1,point_2);
if(x==3&&y==4)printf("修改失败!");
else if(x==4&&y==3) printf("修改成功!");
return 0;
}
int change(int *p1,int *p2){
int *temp;
temp=p1;
p1=p2;
p2=temp;
}
结果如下:修改失败! Process returned 0 (0x0) execution time : 0.310 s Press any key to continue.
这又是为什么呢?原因很简单,这一思路是改变指针的指向,也就是改变指针变量存的地址,而这个指针变量的值也是一个实参,而形参本身是无法改变实参的,引文函数调用过程的数据传递是单向的值传递,具体原理如下图所示:
可见,形参中p1与p2确实成功地交换了指向,**但是!**当函数调用完成后这俩是要被释放掉的,而point_1与point_2根本没有改变
最后我们来看第三种方法——调用函数—指针指向的变量改变
int main(){
int x=3,y=4,*point_1=&x,*point_2=&y;
change(point_1,point_2);
if(x==3&&y==4)printf("修改失败!");
else if(x==4&&y==3) printf("修改成功!");
return 0;
}
int change(int *p1,int *p2){
int temp;
temp=*p1;//*p1=x
*p1=*p2;
*p2=temp;
}
结果如下:修改成功! Process returned 0 (0x0) execution time : 0.290 s Press any key to continue.
可以看到我们修改成功了,那到底是为什么呢?我们用一个代码检验这个过程:
int main(){ int a,b,*p1,*p2; scanf("%d %d",&a,&b); p1=&a; p2=&b; printf("修改前地址:%d %d\n",p1,p2); printf("修改前a:%d,b:%d\n",*p1,*p2); change(p1,p2); printf("修改后地址:%d %d\n",p1,p2); printf("修改后a:%d,b:%d\n",*p1,*p2); return 0; } int change(int *p1,int *p2){ int temp;//不能用*temp?--------初始未赋值,值不可预见,这个未知单元可能存储着一个有用的数据,就可能对整个系统的正常工作造成破坏 temp=*p1;//*p1=a *p1=*p2; *p2=temp; }
运行结果如下:
3 4
修改前地址:6422028 6422024
修改前a:3,b:4
修改后地址:6422028 6422024
修改后a:4,b:3
Process returned 0 (0x0) execution time : 2.220 s
Press any key to continue.
可见,整个过程中两个实参的地址并无任何改变,改变掉的是地址内存储的值,也就是调用函数改变掉了指针指向的变量,用一个图解释整个过程:
由此可见,要调用函数修改实参的值,必须通过指针,并且形参指针要修改的是地址内存储的值
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。