C 语言中函数的参数传递

2020-10-09 07:13秦玉平冷强奎李祥纳
关键词:数组指针变量

秦玉平,冷强奎,李祥纳

(1.渤海大学 工学院,辽宁 锦州121013;2.渤海大学 信息科学与技术学院,辽宁 锦州121013;3.北京国电通网络技术有限公司,北京100761)

关键字:C语言;函数;参数传递;传递规则

0 引言

C语言是一种功能强大且得到广泛应用的计算机高级语言[1].C语言是高校理工科专业的必修课程,主要培养学生C语言应用能力和程序设计能力[2,3].

一个C程序由一个或多个文件构成,每个文件由一个或多个函数构成,每个函数完成一个特定的功能,函数是构成C程序的基本单位.依据函数关系,函数分为主调函数和被调函数.依据函数形式,函数分为无参函数和有参函数.

在调用有参函数时,主调函数和被调用函数之间有数据传递,数据传递通过函数的参数传递实现.函数参数何时传递数据、函数参数怎样传递数据、函数参数传递的是什么数据以及如何访问参数传递的数据,是学习者学习C语言函数时的难点,只有学懂弄通这些问题,才能编写出高质量功能函数.为使学习者能够快速、熟练掌握函数参数传递,依据计算机程序设计教学方法[4,5],本文对每一种类型参数的传递时间、传递操作、传递内容和数据操作分别阐述,并通过实例进行详细解析.

1 参数传递规则

C语言中,定义函数时的参数称为形式参数,简称形参,调用函数时的参数称为实际参数,简称实参.形参是变量,每个形参前面有类型说明符.实参可以是常量、变量和表达式,实参前面没有类型说明符.函数调用开始,为形参分配存储单元,函数调用结束,释放形参占用的存储单元.参数传递是单向的赋值运算,即实参的值依次对应地传递给形参,但形参不能反传给实参.参数传递的“值”可以是数值,也可以是地址,即参数传递有传值和传址两种方式.形参与实参的数据类型要一致,否则赋值非法或按不同类型数值的赋值规则自动进行类型转换.

2 参数类型及传递方式

C语言的数据类型有基本类型、构造类型、指针类型和空类型四种.其中,基本类型包括整型、实型、字符型和枚举型.构造类型包括数组、结构体和共用体.

2.1 基本类型数据作函数参数

基本类型数据作函数参数时,参数传递是传值方式,形参和实参占用各自的存储单元,对形参值的修改不会影响实参值.

【例1】基本类型数据作为函数参数举例.

例1中,函数fun1的功能是交换形参a、b的值.函数调用开始,为形参a、b分配存储单元,同时进行参数传递,即a=x、b=y,见图1.函数fun1中对形参a、b值的修改,没有影响实参a、b的值.

2.2 基本类型指针作函数参数

基本类型指针作函数参数时,参数传递是传址方式,实参和实参指向同一对象,修改形参指向变量的值就是修改实参指向变量的值.利用指针引用所指向的变量的方式是“*指针变量”.

【例2】基本类型指针作函数参数举例.

例2中,函数fun2的功能是交换形参a指向变量和b指向变量的值.函数调用开始,为形参a、b分配存储单元,同时进行参数传递,即a=&x、b=&y,见图2.此时,*a就是x,*b就是y,交换*a、*b的值,即交换变量x、y的值.

在程序设计时,利用基本类型指针作函数的参数,可以通过一次函数调用得到多个结果.

2.3 一维数组作函数参数

一维基本类型数组、一维结构体数组、一维共用体数组和一维指针数组都可作为函数的参数.一维数组名代表数组在内存中的起始地址,一维数组作为函数参数时,参数传递是传址方式.由于一维数组名是常量,不能对其进行赋值运算,编译系统将一维数组说明格式的形参转换为指向数组元素的指针说明格式.函数调用时传递给形参的是数组的首地址,即形参数组与实参数组为同一个数组.

例3中,函数fun3的功能是交换数组第一个元素和最后元素的值.编译时编译系统将函数fun3中的形参说明“int x[]”转换为“int*x”.函数调用开始,为形参x分配存储单元,同时进行参数传递,即x=a,见图3.此时,x[i]与a[i](0≤i≤N-1)表示同一数组元素,对形参数组x操作等同于对实参数组a操作.

2.4 二维数组作函数参数

二维基本类型数组、二维结构体数组、二维共用体数组和二维指针数组都可作为函数的参数.C语言对二维数组的处理方法是将其分解成多个一维数组,即将每一行看作一个一维数组,并按行存储.二维数组的数组名代表数组在内存中的起始地址,二维数组作为函数参数时,参数传递是传址方式.由于二维数组名是常量,不能对其进行赋值运算,编译系统将二维数组说明格式的形参转换为指向一维数组的指针说明格式.调用函数时传递给形参的是数组的首地址,即形参数组与实参数组是同一个数组.

【例4】二维数组作为函数参数举例.

例4中,函数fun4的功能是互换二维数组最大值与最小值的位置.编译时编译系统将函数fun4中的形参说明“int x[M][N]”转换为“int(*x)[N]”.函数调用开始,为形参x分配存储单元,同时进行参数传递,即x=a,见图4.此时,x[i][j]与a[i][j](0≤i≤M-1,0≤j≤N-1)表示同一数组元素,对形参数组x操作等同于对实参数组a操作.

2.5 结构体(或共用体)类型数据作函数参数

结构体类型数据和共用体类型数据都可作函数的参数,但实参也必须是变量,其原因是共用体变量不能初始化,结构体变量除初始化外不能整体赋值.结构体和共用体变量作函数参数时,参数传递是传值方式,参数传递形式是一个赋值运算,实际是多个赋值运算,即将实参各成员的值依次赋给形参的相应成员.由于形参和实参占用各自的存储单元,所以对形参值的修改不会影响实参.

【例5】结构体变量作为函数参数举例.

例5中,函数fun5的功能是输出结构体变量x各成员的值.函数调用开始,为形参x分配存储单元,同时进行参数传递,即x=a(x.c=a.c,x.h=a.h,scrcpy(x.str,a.str)),见图5.

2.6 结构体(或共用体)指针作函数参数

结构体(或共用体)指针作函数参数时,参数传递是传址方式,实参和实参指向同一变量,修改形参指向变量的成员值就是修改实参指向变量的成员值.利用结构体(或共用体)指针变量引用结构体变量成员的方式是“指针变量->成员”或“(*指针变量).成员”.

【例6】结构体指针作为函数参数举例.

例6中,函数fun6的功能是输出指针变量x指向变量的各成员的值.函数调用开始,为形参x分配存储单元,同时进行参数传递,即x=a,见图6.此时,是用指针变量x引用变量a的成员.

另外,结构体、共用体的成员和数组元素都可作为函数的参数,传递方式和数据处理与同类型的数据相同.

3 结论

在调用有参函数时,先为形参分类存储单元,同时进行参数传递,然后再执行规定的操作.函数参数传递规则是将实参表达式的值依次对应地传给形参表中的各形参变量,即参数传递是单向的赋值运算.参数传递信息有两种,一种是数值,另一种是地址.传值时,对应的形参是基本类型、结构体类型或共用体类型的变量,在被调函数中对形参的操作,不会影响到主调函数中的实参值.传址时,对应的形参是指针变量,此时,实参和形参指向同一个对象,在被调函数中可利用形参修改和访问实参指向的对象.传址常用于两种情况,一是通过一次函数调用带回多个值,二是在被调函数中修改主调函数中某些变量的值.

猜你喜欢
数组指针变量
JAVA稀疏矩阵算法
抓住不变量解题
垂悬指针检测与防御方法*
JAVA玩转数学之二维数组排序
更高效用好 Excel的数组公式
为什么表的指针都按照顺时针方向转动
寻找勾股数组的历程
分离变量法:常见的通性通法
浅析C语言指针
不可忽视变量的离散与连续