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.8 传值和传址 - 图1

图 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.8 传值和传址 - 图2

图 1-7 传址