浅析C语言中函数参数传递方式
浅析C语言中函数参数传递方式
[摘 要]函数是C程序基本构造模块,是构造结构化程序的基础。对C函数的调用做全面的分析和研究,总结主调函数调用被调函数时的数据传递有值传递方式、地址传递方式以及值传递和地址传递并存方式,并对每一种调用方式的调用过程从内存分配给予说明和解释。
[关键词]函数形参 函数实参 值传递 地址传递 单向 双向
中图分类号:TP311.11 文献标识码:A 文章编号:1671-7597(2008)1010068-01
一、引言
C语言程序是由函数组成的,函数是程序的基本单位。设计C程序时,通常将一个大的程序按功能分成若干个较小的模块,每个模块编写成结构清晰、接口简单、容易理解的程序函数。并且这种方法就叫模块化程序设计方法,而在划分模块时要求模块的“内聚性”强,与其他模块的“耦合性”弱,所以一般要求把C程序中的函数做成一个封闭体,函数之间的联系渠道主要由函数的参数承担。因此在C程序设计中函数的参数是不容忽视的角色。
二、函数的参数
在C程序中,函数之间存在调用与被调用的关系,当被调函数是有参函数时,主调函数和被调函数间通过参数有数据传递关系。函数的参数有形参和实参之分,定义函数时的参数称为形式参数,简称形参。形参在该函数未被调用时没有确定的值,只是形式上的参数,常用变量表示;调用函数时的参数称为实参,实参可以是变量、常量或表达式,有确定的值,是实实在在的参数。函数定义时的形参不占内存,只有发生调用时,形参才被分配内存单元,接受实参传来的值。
函数的形参与实参个数要求相等,对应类型一致,且顺序相同。形参和实参可以同名,形参是局部于该函数的变量,即使形参和实参同名,也是两个不同的变量,占不同的内存单元,因此形参也需要类型说明,函数可不带参数,也可以带多个参数,当有多个参数时,每个参数之间用逗号分隔。例如:
float max(float a,float b)
{……}
main()
{float x,y;
……
max(x,y);}
以上a、b是形参,x、y是实参。在程序执行时,形参与实参之间存在着数据传递的关系。
为了论述函数的参数传递方式,先看一个简单的程序。调用交换两数的函数 swap( ),观察程序的运行结果。
#include
void swap(int a,int b)
{int t;
t=a;a=b;b=t;
printf(“调用中:a=%d ,b=%d\n”,a,b);}
main( )
{int a=1,b=2;
printf(“调用前:a=%d,b=%d\n”,a,b);
swap(a,b );
printf(“调用后:a=%d,b=%d\n”,a,b);}
程序运行的结果是:调用前:a=1,b=2
调用中:a=2,b=1
调用后:a=1,b=2
运行结果表明,尽管形参a、b在 swap( )函数中交换了,但主函数main( )在调用swap( )的前后,实参a、b的值都没有改变。那么,为什么形参a、b的交换,并不影响实参a、b的值,实参与形参之间的数据到底是如何传递的呢?这是由参数的单向值传递方式决定的。
三、参数的“值传递”方式
在c中,参数的值传递具有如下特点:(1)实参与形参各自占据独立的存储单元。(2)调用时,将实参的值传入形参单元。(3)在被调用的函数内,访问相应的形参单元。??)函数调用结束后,释放形参单元。
因此,在被调用函数中改变形参的值不会改变实参的值。函数调用时,是把实参的值拷贝到相应的形参中去,这样,被调用函数得到的是实参的拷贝,而不是实参本身。例如上例中调用函数swap( )时,函数参数传递过程可用图1形象地表示出来。
方框表示一个特定的存储单元,箭头表示将一个存储单元的值复制到另一个存储单元中。
由于一个数组元素相当于一个同类型的变量,即在c语言中,简单变量或数组元素作为函数参数都是按“值传递”方式处理的,数据传递是单向的,即只能把实参的值传递给形参,而不能将形参的值传递给实参,形参值的改变
不影响实参。
四、参数的“地址传递”方式
从上例中可以看出,由于以简单变量作为函数的形参和实参时是“值传递”,且是“单向”的,也就是说,对被调用函数来说,参数值只能“传入”不能“传出”。其实这只是表面现象,实际上实因为形实参分别对应于不同的存储单元。
如果将程序修改为用指针变量作为函数的形参,以变量的地址作为实参来调用swap( )函数,情况就不一样了。程序修改如下:
#incl