一、可变长参数介绍
某些情况下为了完成一些功能,需要用到可变长参数的函数,例如我们最常用的printf和scanf函数:
scanf("%d %d", &a, &b);
printf("%d %d\n", a, b);
它们首先都是一个字符串打头,后面再跟上不定数量的参数,为我们的输出形式提供了多样性。
对于像这样的不定长参数的函数来说,它的声明形式为:
int func(int a, int b, ...);
...
表示不定长度的参数,和函数形参的默认值一样,...
也只能放在函数的最后,否则函数无法判断出哪些才是不定参数。
二、变参使用
变参函数内部是通过栈来实现的,对于每一个参数来说,在调用时它们都会从右到左依次被压入栈中,而栈的性质是先进后出,所以在使用时会从左到右提取。
C语言中定义了一种类型va_list
来提取这些参数,va_list类型的定义如下:
// stdarg.h
typedef va_list char*
提取需要用到的API函数为va_start
和va_arg
,其用法如下:
void f(const char *arg, ...) {
va_list args;
//初始化args指向强制参数arg的下一个参数,即第一个不定参数的地址
va_start(args, arg);
//获取当前参数内容并将args指向下一个参数,type表示当前的元素类型
va_arg(args, type);
// ... 操作
va_end(args); //释放args
}
三、使用示例
#include <stdio.h>
#include <stdarg.h>
/*
* 求和
* @param argc 参数个数
* @param ... 可变参数列表
* @return 所有参数的和
*/
int sum(int argc, ...) {
int sum = 0, tmp;
// 初始化参数
va_list argv;
va_start(argv, argc);
for (int i = 0; i < argc; i++) {
// 循环获取每一个参数
tmp = va_arg(argv, int);
printf("%d\n", tmp);
sum += tmp;
}
// 销毁参数
va_end(argv);
return sum;
}
int main() {
printf("sum = %d\n", sum(3, 10, 20, 30));
printf("sum = %d\n", sum(4, 40, 39, 38, 37));
return 0;
}
运行结果:
$ ./debug/app
10
20
30
sum = 60
40
39
38
37
sum = 154
此处评论已关闭