C语言之可变参数列表

对于函数参数的个数或者类型在编写函数时未确定的情况, C语言允许使用 可变参数列表, 用 , ... 来表示. 使用可变参数列表要注意:

  • 含有可变形参的形参列表中, 至少要有一个确定类型的形参
  • 在可变参数列表 (, ...) 的后面不能再跟其他形参
  • 由于可变参数列表中的形参类型不确定, 所以编译器将对传入的实参执行默认 实参提升, 比如传入实参为char型, 将自动提升为int型
  • 需要借助 stdarg.h 头文件中的宏迭代获取可变参数列表中的形参
double function(int n_value, ...); // 正确的声明

下面介绍 stdarg.h 及其中的 va_list 类型和 va_start, va_arg, va_end, va_copy 四个宏函数的用法

  • va_list
    va_list类型代表一种数据对象, 该数据对象用于存放可变参数列表中的形参.
va_list ap; // 定义一个用于存放形参的va_list型对象
  • va_start
    va_start宏函数执行va_list对象的初始化工作, 即将整个形参列表复制到va_list对象中去, 其第一个参数是va_list类型的对象, 第二个参数是可变参数列表之前的那个参数, 用以在指明在整个参数列表中可变参数列表开始的位置. 执行va_start后va_list对象将指向输入的第一个实参..
va_start(ap, n_value); // 初始化ap
  • va_arg
    va_arg宏函数用以指定函数调用中va_list对象所指向实参的下一个实参的类型(注意默认实参提升), 并返回va_list对象所指实参的下一个实参的值, 同时每调用一次va_arg, va_list对象都自动指向下一个实参. va_arg函数第一个参数为va_list对象, 第二个参数为va_list对象所指实参的下一个实参的类型. 初始化时va_list已经指向第一个实参, 所以第一次调用va_arg时返回第二个实参的值(该实参对应的形参可能已经确定, 也可能在可变参数列表中).

  • va_end
    在获取完参数列表后, 使用va_end无效化va_list对象.

va_end(ap); // 无效化ap
  • va_copy
    va_copy宏函数用其第二个参数src初始化其第一个参数dest, 两参数都是va_list类型的对象. 如果src已经已经使用va_start初始化或者va_arg移动, 则dest相当于也经过了同样的操作.

总结起来使用可变参数需要5步:
1. 在函数原型中使用 , ... 表示可变参数列表
2. 在函数定义中创建一个va_list型对象
3. 用宏将对象初始化为一个参数列表
4. 用宏访问参数列表
5. 用宏清理参数列表

下面是用可变参数列表求平均值的例子:

#include <stdarg.h>
float average(int n_values, ...); // 声明可变参数的函数
int main(void)
{
    return 0;
}

// 定义可变参数的函数
float average(int n_values, ...)
{
    va_list var_arg;
    int count;
    float sum = 0.0;

    va_start(var_arg, n_values); // va_start宏函数对var_arg对象初始化

    for(count = 0; count < n_values; count += 1)
    {
        sum += va_arg(var_arg, int); // va_arg宏指定下一个实参的类型与值
    }

    va_end(var_arg); // va_end无效化var_arg对象 

    return sum / n_values;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值