【C语言日日练(四)】可变参数函数

【C语言天天练(四)】可变参数函数

可变参数函数指可以接受可变数量参数的函数。比如printf函数就是一个可变参数函数。

要完成可变参数函数的编写,需要用到定义于stdarg.h头文件中的一个类型va_list和三个宏va_start、va_arg、va_end。

注意:

1、可变参数必须从头到尾按照顺序逐个访问。如果在访问几个可变参数后想半途中止,这是可以的。但是,如果想一开始就访问列表中的参数,那是不行的。

2、由于参数列表中的可变参数部分并没有原型,所以,所有作为可变参数传递给函数的值都将执行缺省参数类型提升。

3、参数列表中的省略号,它提示此处可能传递数量和类型未确定的参数。省略号只能出现参数表的尾部。


变长参数函数的关键在于 如何处理一个甚至连名字都没有的参数表。标准头文件<starg.h>中包含一组宏定义,它们对如何遍历参数表进行了定义。

va_list类型用于声明一个变量,该变量将依次引用各参数。

va_start宏将va_list声明的变量初始化为指向第一个无名参数的指针。在使用变量之前,该宏必须被调用一次。参数表必须至少包括一个有名参数,va_start将最后一个有名参数作为起点。

va_arg宏,调用该宏,该函数都将返回一个参数,并将声明的变量指向下一个参数。va_arg使用一个类型名来决定返回的对象类型、指针移动的步长。

va_end宏,该宏必须在函数返回之前调用,以完成一些必要的清理工作。

示例:

#include <stdarg.h>
#include <stdio.h>

/*
 *计算平均值
 */

float
average(int n_values, ...)
{
	va_list	var_arg;
	int		count;
	float	sum = 0;

	va_start(var_arg, n_values);	/*准备访问可变参数׼       */

	for(count = 0; count < n_values; count+=1){
		sum += va_arg(var_arg, int);/*添加取自可变参数列表的值         ֵ*/	
	}

	va_end(var_arg);				/*完成处理可变参数       */

	return sum/n_values;
}

void
main(int argc,  char **argv)
{
	printf("the average of 3 and 8 is %f\n", average(2, 3, 8));
	printf("the average of 3 and 8 and 11 is %f\n", average(3, 3, 8, 11));
	return;}

注意:C语言中的可变参数函数没有长度检查和类型检查,可能会被利用为攻击目标。设计函数时应先考虑替补方案。