stdarg.h
提供了C语言对可变参数的支持,先举一个简短的例子
//testStdArg.c
#include
#include void printIntList(int N, ...){va_list args; //存放...所代表的参数va_start(args, N); //初始化变量argsfor (int idx = 1; idx <= N; ++idx)printf("param %d: %d, ", idx, va_arg(args, int));printf("-----\n");va_end(args);
}int main(void)
{printIntList(4,1,2,3,4);printIntList(4,1,2,3);printIntList(3,1,2,3,4);
}
编译之后输出结果为
>gcc testStdArg.c
>a.exe
param 1: 1, param 2: 2, param 3: 3, param 4: 4,
-----
param 1: 1, param 2: 2, param 3: 3, param 4: 4,
-----
param 1: 1, param 2: 2, param 3: 3,
-----
其中,va_list
为stdarg.h
中声明的数据类型,用以存放...
所代表的参数,在printIntList
中,定义了va_list
类型的args
用于存储变量。
在stdarg.h中声明了三个函数,在上面的案例中都用上了,下面逐一解析
void va_start(va_list ap, last_arg)
ap
变量,last_arg
为最后一个参数的下标printIntList(4,1,2,3,4)
而言,总共输入了5
个参数,故其last_arg
应该为4。type va_arg(va_list ap, type)
type
参数printIntList
中,va_arg
被写在一个循环中,会逐个检索int
型的参数printIntList(4,1,2,3)
中,由于N
设为4,所以va_arg
会检索4次,最后返回的4
实际上是一个野指针。void va_end(va_list ap)
va_end
来释放ap
有了这个函数,就可以实现多个参数求统计参数的功能,例如求最大值
//testMax
#include
#include double getMax(int N, ...){va_list args;va_start(args, N);double val;double max = va_arg(args, double);for(int idx=2; idx <= N; ++idx){val = va_arg(args, double);max = max > val ? max : val;}va_end(args);return max;
}int main(void)
{double a = getMax(4,1.2,2.3,3.4,2.5);printf("%f", a);
}
测试结果如下
>gcc test.c
>a.exe
3.400000
最后留一个小作业,如何用C语言实现一个参数个数可变的复杂一点的应用,比如求标准差σ=1N∑i=1N(xi−xˉ)2\sigma=\sqrt{\frac1N\sum^N_{i=1}(x_i-\bar x)^2}σ=N1∑i=1N(xi−xˉ)2。
这里面的问题是,va_arg
相当于是一个不断向前的迭代器,但并没有索引的功能,所以必须一次性取出,而不能跑多次循环。一个最直接的解决方案就是开一个数组或者链表,来缓存va_arg
中的数据。