C语言函数的可变参数

391 阅读1分钟
前言:

有时候我们需要一个函数接口可以支持可变参数以提高其泛化能力,比如说定义一个求和函数,对传入的所有参数进行求和并返回,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,具体方式是根据可变参数的前一个参数及其类型,在这里为nint计算得到的得到可变参数的首地址。
  • 然后依次用va_arg宏使ap返回可变参数的地址,得到这个地址之后,结合参数的类型,就可以得到参数的值。
  • 通过调用va_end清理ap内存。