Namespaces
Variants

va_start

来自 zh.cppreference.net
定义于头文件 <stdarg.h>
void va_start( va_list ap, parmN );
(直到 C23)
void va_start( va_list ap, ... );
(自 C23 起)

va_start 宏允许访问可变参数跟在命名参数 parmN(直到 C23)。

va_start 应使用有效的实例调用 va_list 对象 ap 在对任何 va_arg 调用之前。

如果 parmN 声明时使用 register 存储类说明符、数组类型、函数类型,或与默认参数提升结果类型不兼容的类型,行为未定义。

(直到 C23)

如果为 va_start 提供了多于一个参数,则构成第二个及后续参数的预处理记号被丢弃。如果这些参数中的任何一个展开后包含不平衡的括号,或包含无法转换为记号的预处理记号,行为未定义。

(自 C23 起)

参数

ap - 一个 va_list 类型的实例
parmN - 第一个可变参数之前的命名参数

扩展值

(无)

示例

#include <stdarg.h>
#include <stdio.h>

int add_nums_C99(int count, ...)
{
    int result = 0;
    va_list args;
    va_start(args, count); // count can be omitted since C23
    
    for (int i = 0; i < count; ++i)
        result += va_arg(args, int);
    
    va_end(args);
    return result;
}

#if __STDC_VERSION__ > 201710L
// Same as above, valid since C23
int add_nums_C23(...)
{
    int result = 0;
    va_list args;
    va_start(args);
    
    int count = va_arg(args, int);
    for (int i = 0; i < count; ++i)
        result += va_arg(args, int);
    
    va_end(args);
    return result;
}
#endif

int main(void)
{
    printf("%d\n", add_nums_C99(4, 25, 25, 50, 50));
#if __STDC_VERSION__ > 201710L
    printf("%d\n", add_nums_C23(4, 25, 25, 50, 50));
#endif
}

可能的输出:

150
150

引用

  • C23 standard (ISO/IEC 9899:2024):
  • 7.16.1.4 The va_start macro (p: 290-292)
  • C17 standard (ISO/IEC 9899:2018):
  • 7.16.1.4 The va_start macro (p: 198-199)
  • C11 standard (ISO/IEC 9899:2011):
  • 7.16.1.4 The va_start macro (p: 271-272)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.16.1.4 The va_start macro (p: 251-252)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.8.1.1 The va_start macro

参阅

访问下一个可变参数函数参数
(函数宏)
制作可变参数函数参数的副本
(函数宏)
结束对可变参数函数参数的遍历
(函数宏)
保存以下函数所需的信息:va_start, va_arg, va_end, 以及 va_copy
(类型定义)
C++ 文档 用于 va_start