可变参数函数指可以接受可变数量参数的函数。比如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语言中的可变参数函数没有长度检查和类型检查,可能会被利用为攻击目标。设计函数时应先考虑替补方案。