va_arg

来自cppreference.com
< c‎ | variadic
在标头 <stdarg.h> 定义
T va_arg( va_list ap, T );

va_arg 宏展开成 T 类型的表达式,表达式对应来自 va_list ap 的下个实参。

调用 va_arg 前,必须调用 va_startva_copy 以初始化 ap,中间不能有 va_end 调用。每次调用 va_arg 宏都会修改 ap,令它指向下一个可变实参。

ap 中的下个实参(提升后)与 T 的类型不兼容,则行为未定义,除非:

  • 一个类型是有符号整数类型,另一类型是对应的无符号整数类型,而且值可以被两类型一同表示;或
  • 一个类型是指向 void 的指针,而另一个是指向字符类型的指针。

若在 ap 中无更多实参时调用 va_arg,则行为未定义。

参数

ap - va_list 类型的实例
T - ap 中下个参数的类型

展开值

ap 中的下个可变参数。

示例

#include <stdio.h>
#include <stdarg.h>
#include <math.h>
 
double stddev(int count, ...) 
{
    double sum = 0;
    double sum_sq = 0;
    va_list args;
    va_start(args, count);
    for (int i = 0; i < count; ++i) {
        double num = va_arg(args, double);
        sum += num;
        sum_sq += num*num;
    }
    va_end(args);
    return sqrt(sum_sq/count - (sum/count)*(sum/count));
}
 
int main(void) 
{
    printf("%f\n", stddev(4, 25.0, 27.3, 26.9, 25.7));
}

输出:

0.920258

引用

  • C11 标准(ISO/IEC 9899:2011):
  • 7.16.1.1 The va_arg macro (第 269-270 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 7.15.1.1 The va_arg macro (第 249-250 页)
  • C89/C90 标准(ISO/IEC 9899:1990):
  • 4.8.1.2 The va_arg macro

参阅

创造函数可变实参的副本
(宏函数)
结束对函数可变实参的遍历
(宏函数)
保有 va_start、va_arg、va_end 及 va_copy 所需的信息
(typedef)
令函数得以访问可变实参
(宏函数)