1.8 传值和传址
传值,函数调用过程中参数传递的是实参的值,就是把实参传递给形参。对形参的修改不会影响到实参,这就相当于一个对实参备份的操作,即对形参的修改只是修改实参的备份,不会影响到实参。
传址,函数调用过程中参数传递的是地址,形参和实参共用一个空间,所以对于形参的修改会影响到实参。
下面通过一段代码来学习传值。
include<stdio.h>
void swap(int p1,int p2){
printf("\np1和p2交换前\n");
printf("p1=%d\tp2=%d\n",p1,p2);
int temp;
temp=p1;
p1=p2;
p2=temp;
printf("\np1和p2交换后\n");
printf("p1=%d\tp2=%d\n",p1,p2);
return;
}
void main()
{
int a,b;
a=20;
b=30;
printf("调用swap()函数以前\n");
printf("a=%d\tb=%d\n",a,b);
swap(a,b);
printf("\n调用swap()函数以后\n");
printf("a=%d\tb=%d\n",a,b);
return;
}
运行结果:
调用swap()函数以前
a=20 b=30
p1和p2交换前
p1=20 p2=30
p1和p2交换后
p1=30 p2=20
调用swap()函数以后
a=20 b=30
分析上面的运行结果发现,main()函数中调用swap()函数前后a和b的值并没有改变,但是在swap()函数中交换前后p1和p2的值的确交换成功了,而在main()函数中为什么没有成功地实现交换呢?为了方便说明,我们用图1-6来展示参数是如何进行传值的。
图 1-6 传值
从图1-6中清楚地发现,在函数的调用过程中实现的是参数a和b的传值,即把a和b的值传递给p1和p2,swap()函数中的p1和p2拥有自己的存储空间,所以接下来在swap()函数中进行的交换操作仅仅是对p1和p2进行的,不会影响到main()函数中a和b的值。这也就是为什么在传值时修改形参不会影响实参。接下来再通过下面一段代码来看看传址。
include<stdio.h>
void swap(intp1,intp2)
{
printf("\np1和p2交换前\n");
printf("p1=%d\tp2=%d\n",p1,p2);
int temp;
temp=*p1;
p1=p2;
*p2=temp;
printf("\np1和p2交换后\n");
printf("p1=%d\tp2=%d\n",p1,p2);
return;
}
void main()
{
int a,b;
a=20;
b=30;
printf("调用swap()函数以前\n");
printf("a=%d\tb=%d\n",a,b);
swap(&a,&b);
printf("\n调用swap()函数以后\n");
printf("a=%d\tb=%d\n",a,b);
return;
}
运行结果:
调用swap()函数以前
a=20 b=30
p1和p2交换前
p1=20p2=30
p1和p2交换后
p1=30p2=20
调用swap()函数以后
a=20 b=30
分析上面的运行结果发现,此时不仅在swap()函数中成功交换了p1和p2,而且在main()函数中也成功实现了a和b的交换。为了能够更加直观地说明交换的实现,在此使用图1-7来展示参数是如何进行传递的。
在图1-7中可以清楚地发现,在函数的调用过程中实现的是参数a和b的传址,即把a和b存储单元的地址传递给p1和p2,swap()函数中的形参不再拥有自己的存储空间,它们分别指向a和b的存储单元,所以接下来在swap()函数中对p1和p2指向的存储单元进行交换的操作其实是对a和b进行的。这也是在采用传址的时候修改形参也会影响实参的原因。
图 1-7 传址