要想一个函数接能收任意个参数有两种方法:第一可以用指向数组的指针作为参数间接实现(即传数组的方式);第二可以使函数本身能接受任意个参数(使用可变参数列表)。
当我们使用printf
打印多个变量的值,这里其实就用到了可变参数列表。
使用可变参数列表需要用到省略号,如int a_function (int x , ... );
,告诉编译器该函数可接收任意多个参数,参数个数至少等于1,其中x为第一个参数。
当我们调用上述a_function
函数,并传递多个参数:a_function(1,2,3);
。为了使用这些参数,需要用到一个能存储可变参数列表的变量,该变量的类型为va_list
(可以把va_list
理解为类似int
、float
的变量类型)。va_list
类型的变量需要宏va_start
来初始化,它接受两个参数,即va_list和直接在省略号(“ ...”)之前的变量的名称。 代码如下:
#include <stdarg.h>
int a_function ( int x, ... )
{
va_list a_list;
va_start( a_list, x ); //初始化a_list列表,初始化过程就是让a_list变量指向可变参数的第一个参数(这里为x)
}
使用va_arg
可以访问列表中的参数,va_arg
接受两个参数:一个va_list和变量类型。返回值为列表中的下一个参数(类型为传递进来的变量类型),因此使用可变参数列表需要知道列表中每个参数的类型,因为在取参数时需要指定参数类型,这也是为什么printf
需要使用格式化字符串的原因。当多次调用va_arg
取完参数时,用va_end(a_list);
清空参数列表。
使用示例:(注意包含头文件stdarg.h)
#include <stdarg.h>
#include <stdio.h>
/* 此函数用来求平均值,num表示后面参数的个数(用来计算平均值) */
double average ( int num, ... )
{
va_list arguments;
double sum = 0;
/* 初始化参数列表,使argument指向num,即num为参数列表中的第一个参数 */
va_start ( arguments, num );
/* 计算输入的总和,num表示传入参数的个数*/
for ( int x = 0; x < num; x++ )
{
//每次以double类型取列表中的下一个参数
sum += va_arg ( arguments, double );
}
va_end ( arguments ); // 清空列表
return sum / num;
}
int main()
{
/* 计算13.2, 22.3, 4.5的平均值 (3表示需要计算的数的个数) */
printf( "%f\n", average ( 3, 12.2, 22.3, 4.5 ) );
/*计算5个数的平均值*/
printf( "%f\n", average ( 5, 3.3, 2.2, 1.1, 5.5, 3.3 ) );
}