学了四年的计算机,一直让自己比较苦恼的问题是C语言的参数传递问题,之所以说是苦恼,是因为在某年的一个学期,不幸接触到数据结构,光一个链表就把自己弄得死去活来的,而且自已一直就楞以为在操作的过程中,传递参数的指针也在发生变化,结果可想而知,数据结构成了自己专业课里面险些挂彩的一门课程。
直至最近,拿出数据结构打算恶补一下前些年欠下的债,第一件事情,还是先解决好当时困扰自己半年之久的C语言参数传递问题吧。
C语言课堂上,自己明明记得参数传递问题我已经搞懂了,只不过当时没有接触过C plus plus,所以除了值传递和地址传递,我就根本不知道还有一种引用传递。现在想起来,自己那时候学的还是马马虎虎,太过自信认为自己已经完全掌握参数传递的实质。闲话少说,直入正题。
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 }
实参和行参共享一个存储单元,对行参的操作相应的就改变了实参,此时参数传递是双向的。
小结:
值传递:作为参数的变量,传递给函数执行后,自己的变量值是不变的。它(实参)仅仅只是把值赋给了形参,自己实际上是没有参与函数运算的,参与的是形参,这个就是参数的值传递。值传递好比是你把文件复制一份,通过网络传给他,然后他可以在他本机上对文件做任何的修改,修改会保存下来,但是你机器上的文件不会发生任何的变化。即形参与实参是两个不同的变量,各自占用不同的存储单元。
地址传递:地址传递跟值传递也没有什么不同,值传递是把变量的值传递给形参去参与函数运算,而地址传递则把变量的地址传递给形参去参与函数运算。当然,如果函数改变了变量地址的值,实参的值也会变化的。地址传递好比是你把文件在网络上的地址告诉他人,他人通过网络访问你机器上的文件,他可以对文件进行修改并保存,此时,文件的内容就会发生变化。即形参与实参是相同的变量,占用同一段内存空间。
原文:http://www.cnblogs.com/ryanlin/p/3594253.html