C语言函数参数传递模式入门详解

一、引言
函数是C源程序的基本模块,通过对函数模块的调用可以实现特定的功能。在定义函数的时候,函数的参数几乎是必备的选项。要想熟练使用函数的调用,必须清楚函数参数的传递模式。函数又可以分为主调函数和被调函数,其中主调函数是指在该函数内部调用了其它函数,而被其它函数(包括主函数)调用的函数称为被调函数。正因为有主调函数和被调函数,也就有了函数参数的分类——形参和实参。当然了,函数又可以分为有参函数与无参函数。下面将针对函数参数分类和参数传递方式分别进行阐述。
二、函数参数的分类
函数的参数可以分为实参(实际参数)和形参(形式参数)。
形参是指函数定义(声明)时出现在函数名后面括号里的参数。
当函数被调用时出现在函数名后面括号里的参数称为实参。
需要注意的是,函数参数不是必须的。
形参例子:
例如有如下的函数声明:

int max( int a[], int n );

此时,max称为函数名(亦可以称为接口),圆括号里面的a[]和n称为形参,因为此时数组a和变量n并没有实际的数据,故而称为形参。
实参例子:
例如有如下的代码:

int fun(  )
{
int a[] = { 1, 2, 3, 4, 9, 5 };
int n = 6;
int var = max( a, n );
......
}

此时函数fun称为主调函数,函数max称为被调函数。函数max后面括号里的数组a和变量n称为实参,因为此时的参数已经被赋值。
三、函数参数的传递模式
实参向形参“单向传递”:实参—>形参;
“值”传递。也就是在调用某个函数的时候,把实参的值单向传递给形参。这也做其实也是为了保护实参,避免实参被形参给带跑偏了。

Demo 1:求某个整型数组的最大值。
参考代码:

#include"stdio.h" 
int max( int a[], int n );
int main()
{
	int a[] = { 1, 2, 3, 4, 9, 5 };
	int n = 6;
	int maxV = max( a, n );//a和n为实参 
	printf( " max Value = %d\n", maxV );//向屏幕输出数组a的最大值
	printf( " n = %d\n", n );//向屏幕输出实参n的值
	return 0;
}
//求整型数组a中的最大值,a和n均是形参 
int max( int a[], int n ){
	int maxV, i;
	maxV = a[0];
	for( i = 1; i < n; i++ ){
		if( a[i] > maxV ){
			maxV = a[i];
		}
	}
	n = 10; //企图改变形参n的值 
	return maxV;
}

输出结果:
在这里插入图片描述

本例的第21行n = 10;是在函数max内部改变形参的值,但是通过第9行语句得到输出结果却是n=6,这说明了函数的参数是单向传递。
这样的函数参数传递机制,在实际编程的时候会遇到麻烦,比如想同时获得某整型数组的最大值和最小值,通过函数返回值的模式来同时返回两个值是不行的。解决的方法有很多,其中常用的有:
① 返回数组,数组中存储了最大值和最小值;
② 返回结构体变量,成员是最大值和最小值;
③ 增加指针型的函数参数。C语言对于函数参数增加了一种双向传值的机制,那就是通过指针变量来实现数据的双向传递:实参<—>形参。此时,函数参数由实参传递给实参的是指针变量的地址(因为这时候指针的值就是地址,仍旧是“值”传递),只要在函数内部不改变指针的地址,其它随便你改,其实,你也就能改改地址中的数据值而已。(本文暂不讨论改变指针地址的方法,其实也就是个双指针的问题而已,依然是“值”传递)。

Demo 2:求某个整型数组的最大值和最小值。
方法一:返回数组
参考代码:

#include"stdio.h" 
#include"malloc.h"
int *max( int a[], int n );
int main()
{
	int a[] = { 1, 2, 3, 4, 9, 5 };
	int n = 6;
	int *mV = max( a, n );//a和n为实参 
	printf( " max Value = %d\n min Value = %d\n", mV[0], mV[1] );
	return 0;
}
//求整型数组a中的最大值,a和n均是形参 
int *max( int a[], int n ){
	int maxV, minV, i;
	maxV = a[0];
	minV = a[0];
	for( i = 1; i < n; i++ ){
		if( a[i] > maxV ){
			maxV = a[i];
		}
		if( a[i] < minV ){
			minV = a[i];
		}
	}
	//动态分配空间,存储最大值和最小值 
	int *mv = ( int * )malloc( 2 * sizeof( int ) ) ;
	mv[0] = maxV;
	mv[1] = minV; 
	return mv;
}

方法二:返回结构体变量
参考代码:

#include"stdio.h" 
typedef struct
{
	int maxV;
	int minV;	
}MValue;
MValue max( int a[], int n );
int main()
{
	int a[] = { 1, 2, 3, 4, 9, 5 };
	int n = 6;
	MValue mV = max( a, n );//a和n为实参 
	printf( " max Value = %d\n min Value = %d\n", mV.maxV, mV.minV );
	return 0;
}
//求整型数组a中的最大值,a和n均是形参 
MValue max( int a[], int n ){
	int maxV, minV, i;
	maxV = a[0];
	minV = a[0];
	for( i = 1; i < n; i++ ){
		if( a[i] > maxV ){
			maxV = a[i];
		}
		if( a[i] < minV ){
			minV = a[i];
		}
	}
	MValue mv;
	mv.maxV = maxV;
	mv.minV = minV; 
	return mv;
}

方法三:增加指针型的函数参数
参考代码:

#include"stdio.h" 
#include"malloc.h"
void max( int a[], int n, int *maxV, int *minV );
int main()
{
	int a[] = { 1, 2, 3, 4, 9, 5 };
	int n = 6;
	int *maxV = ( int * )malloc( sizeof( int ) );
	int *minV = ( int * )malloc( sizeof( int ) );
	max( a, n, maxV, minV );//a、n、maxV和minV为实参 
	printf( " max Value = %d\n min Value = %d\n", *maxV, *minV );
	free( maxV );
	free( minV );
	return 0;
}
/*求整型数组a中的最大值
a、n、maxV和minV均是形参 
maxV和minV用来实现双向传值 
*/ 
void max( int a[], int n, int *maxV, int *minV ){
	int i;
	*maxV = a[0];
	*minV = a[0];
	for( i = 1; i < n; i++ ){
		if( a[i] > *maxV ){
			*maxV = a[i];
		}
		if( a[i] < *minV ){
			*minV = a[i];
		}
	}
}

补充说明:
① 上述三个方法中,使用结构体相对简单一些;
② 在上述三个方法中,函数max的参数a是数组名,因此也可以实现双向传值,例如Demo 3。
Demo 3:对某个整型数组进行从小到大排序。
参考代码:

#include"stdio.h" 
void sort( int a[], int n);
int main()
{
	int a[] = { 1, 2, 3, 4, 9, 5 };
	int n = 6;
	sort( a, n );
	for( int i = 0; i < n; i++ )
		printf( "%5d", a[i]  );
	return 0;
}
//对数组a使用选择排序法进行排序
//参数a在函数sort被调用时,传入的是数组的元素,
//当函数sort调用结束后,a中存储的是排序结果 
void sort( int a[], int n){
	int i, j, t;
	for( i = 0; i < n - 1; i++ ){
		for( j = i + 1; j < n; j++ )
		if( a[j] < a[i] ){
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值