天天看点

C/C++可变参数列表

我们非常熟悉的

printf

函数就是一种变长参数,简化版本的函数原型即为:

int printf(const char * _Format, ...); 
           

其中,第一个参数即为必须指定的格式字符串,后面的省略号表示数量不定的参数列表。

使用上面提到的三个点表示的省略号即可达到定义一个变长参数的函数的目的,但是函数中如何取出这里面的所有参数呢?

这里要使用到C语言中解决变长参数问题的若干宏定义

va_start

va_arg

va_end

,他们均定义在

stdarg.h

头文件中,以va开头(表示variable-argument可变参数),可根据预先定义的系统平台自动获取相应平台上各个数据类型的偏移量。他们的使用方法为:

va_list ap;          //定义一个可变参数列表ap
va_start(ap, arg);   //初始化ap指向参数arg的下一个参数
va_arg(ap, type);    //获取当前参数内容并将ap指向下一个参数
va_end(ap);          //释放ap
           

首先定义一个

va_list

类型的变量

ap

,然后使用

va_start

初始化这个变量。初始化之后,ap即指向了参数arg后面的第一个参数,即不确定参数中的第一个。然后使用

va_arg

可以取出当前ap指向的这个参数的数值,并把ap指向了下一个参数,不断的进行这个操作可以取出变长参数中的所有参数。最后使用

va_end

清空这个变长参数列表。

简单例子

下面通过一个简单例子说明变长参数函数的具体使用方法。该函数返回输入参数指定的数据之和,其中参数的第一个变量表示这组数一共有多少个,然后紧接着对应数量的数值。

#include "cstdio"
#include "cstdarg"
int f(int num, ...){
       va_list ap;
       va_start(ap, num);
       int sum = 0;
       for (int i = 0;  i < num;  i++)
              sum+= va_arg(ap, int);
       va_end(ap);
       return sum;
}

int main(){
       int t1 = f(1, 1);
       int t2 = f(2, 1, 2);
       int t3 = f(3, 1, 2, 3);
       int t4 = f(4, 1, 2, 3, 4);
       int t10 = f(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
       printf ("%d%d %d %d %d\n", t1, t2, t3, t4, t10);
}