前言:
有时候我们需要一个函数接口可以支持可变参数以提高其泛化能力,比如说定义一个求和函数,对传入的所有参数进行求和并返回,C语言提供了一种可变参数的方式来帮助我们实现。
原理:
函数参数是从右向左线性连续依次入栈,如果我们可以知道可变参数列表的前一个参数的地址和类型,就可以得知可变参数列表的首地址,进而根据每个参数的类型取出相应的数据。简单来说就是将栈里面的数据,按照指定类型的大小,依次取出。
具体实现:
#include <stdarg.h>
/*最后一个参数必须是省略号既...*/
int Sum(int n, ...)
{
int sum = 0;
va_list ap; //用于指向可变参数的变量
/*获取可变参数的首地址,第二个传入的参数必须是可变参数的前一个参数*/
va_start(ap, n);
for(int i = 0; i < n; ++i)
{
/*根据类型获取可变参数,获取后ap会自动递进*/
sum += va_arg(ap, int);
}
/*与start成对出现,清理ap变量的内存*/
va_end(ap);
return sum;
}
步骤解析:
- 首先定义一个
va_list
类型的变量ap
,用于存储可变参数的地址。 - 通过
va_start
获取可变参数的首地址并赋值给ap
,具体方式是根据可变参数的前一个参数及其类型,在这里为n
和int
计算得到的得到可变参数的首地址。 - 然后依次用
va_arg
宏使ap
返回可变参数的地址,得到这个地址之后,结合参数的类型,就可以得到参数的值。 - 通过调用
va_end
清理ap
内存。