C语言中,函数参数传递有三种形式:值传递、地址传递和引用传递。
弄懂C语言参数传递之前,我们先要清楚以下几个概念:函数参数中的形式参数和实际参数
首先定义上面
: ,在整个函数体内都可以使用,离开该函数则不能使用。 : ,进入被调函数后,实参变量也不能使用。
(2)行参的存储空间是函数被调用时才分配的。调用开始,系统为行参开辟一个临时存储区,然后将各实参之值传递给行参,这时行参就得到了实参的值。
(3)函数返回时,临时存储区也被撤销。
传值的特点:单向传递,即函数中对行参变量的操作不会影响到调用函数中的实参变量。
示例:
1 #include <stdio.h>
以下为值传递的被调函数
1 void change_by_value( int x ){
2 //函数change_by_value接受的参数即为形参
3
4 x = x + 10; //x的值为13,但其值的变化不会影响到a的值
5 }主函数,调用被调函数并输出
1 int main(){
2 int a = 3;
3 printf( " a = %d\n" , a );
4 change_by_value( a ); // 此时的a作为实参传递给函数
5 printf( "a = %d\n",a ); //a的值并没有改变
6 return 0;7 }程序的输出为:
a = 3 a = 3
void change_by_value(int x)内部发生的动作应当是当函数被调用时(堆栈调用)在堆栈上临时分配了一块区域,调用结束,出栈。其详细解释如下:
1 void change_by_value( int x ){
2 int _x = x; //拷贝一份传递给临时变量_x
3 _x = _x + 10; //改变的是_x,不是x
4 }
对于函数参数地址传递形式,其原理和值传递方式一样,当调用函数时也要为形式参数分配内存,被调函数执行完毕后也要回收内存。不同的是:地址传递传递的是实参变量地址的拷贝值,而不是实参变量的值。被调函数中对地址所指对象的操作会改变实参的值。例如:
1 #include <stdio.h>
以下为地址传递的被调函数
1 void change_by_address( int *x ){
2 *x = *x + 10;
3 }主函数,用于调用被调函数
1 int main(){
2 int a = 7 ;
3 printf( "a = %d\n", a );
4 change_by_address( &a ); //如果定义的不是指针变量或者数组,变量名前要加上取址符号
5 printf( "a = %d\n", a );
6 return 0;
7 }
程序输出为:
a = 3 a = 13
地址传递方式:参数是地址
1 void change_by_address( int *x ){
2 *x = *x + 10;
3 }实参和行参共享一个存储单元,对行参的操作相应的就改变了实参,此时参数传递是双向的。
小结:
值传递:作为参数的变量,传递给函数执行后,自己的变量值是不变的。它(实参)仅仅只是把值赋给了形参,自己实际上是没有参与函数运算的,参与的是形参,这个就是参数的值传递。值传递好比是你把文件复制一份,通过网络传给他,然后他可以在他本机上对文件做任何的修改,修改会保存下来,但是你机器上的文件不会发生任何的变化。即形参与实参是两个不同的变量,各自占用不同的存储单元。
地址传递:地址传递跟值传递也没有什么不同,值传递是把变量的值传递给形参去参与函数运算,而地址传递则把变量的地址传递给形参去参与函数运算。当然,如果函数改变了变量地址的值,实参的值也会变化的。地址传递好比是你把文件在网络上的地址告诉他人,他人通过网络访问你机器上的文件,他可以对文件进行修改并保存,此时,文件的内容就会发生变化。即形参与实参是相同的变量,占用同一段内存空间。

