C/C++的可变参数函数之C风格

前言

        可变参函数有C++版本通过模板实现和C风格通过函数和宏定义实现,本章对C风格的可变参函数做详细讲解,C++版本后面再上。

函数和类型

        实现可变参功能,需要引用头文件#include,还要熟悉类型va_list和一个宏va_arg两个函数va_start,va_end。

va_list 类型

        其实va_list就是char* 的typedef。用于保存参数“...”中的数据值。

va_arg 宏

原型: type va_arg(va_list ap, type)
功能:检索函数参数列表中类型为 type 的下一个参数。它无法判断检索到的参数是否是传给函数的最后一个参数
ap: 这是一个 va_list 类型的对象,存储了有关额外参数和检索状态的信息。该对象应在第一次调用 va_arg 之前通过调用 va_start 进行初始化。
type: 这是一个类型名称。该类型名称是作为扩展自该宏的表达式的类型来使用的。
返回值:返回从ap中获取到的类型为type的值。

va_start 函数

原型:  void va_start(va_list ap, last_arg)
功能:
 初始化 ap 变量,它与 va_arg 和 va_end 宏是一起使用的。last_arg 是最后一个传递给函数的已知的固定参数,即省略号之前的参数。这个宏必须在使用 va_arg 和 va_end 之前被调用。
ap:        这是一个 va_list 类型的对象,它用来存储通过 va_arg 获取额外参数时所必需的信息。
last_arg: 最后一个传递给函数的已知的固定参数。

va_end 函数

原型:void va_end(va_list ap)
功能:
允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义。
ap :这是之前由同一函数中的 va_start 初始化的 va_list 对象。

例子

/// C风格可变参函数

#include 
#include              // 包含头文件

// 一个可变参数计算平均数的函数,num为调用者传入参数"..."的个数
double average(int num, ...)
{
    va_list valist;
    double sum = 0.0;

    // 初始化valist
    va_start(valist,num);

    for (int i = 0; i < num; ++i)
    {
        sum += va_arg(valist,int);
    }

    // 清理
    va_end(valist);

    return sum / num;
}

int main()
{
    std::cout << " avg = " << average(3,5,10,0) << std::endl;    // num = 3

    return 0;
}

结果

你可能感兴趣的:(C/C++,c++)