命名空间
变体
操作

可变参数

来自 cppreference.cn
< c‎ | language

可变参数函数是指可以使用不同数量的参数调用的函数。

只有带原型声明的函数声明才可以是可变参数的。这通过 ... 形式的参数来指示,该参数必须出现在参数列表的末尾 并且必须跟随至少一个命名参数(直到 C23)。省略号参数和前面的参数必须用 , 分隔。

// Prototyped declaration
int printx(const char* fmt, ...); // function declared this way
printx("hello world");     // may be called with one
printx("a=%d b=%d", a, b); // or more arguments
 
int printz(...); // OK since C23 and in C++
// Error until C23: ... must follow at least one named parameter
 
// int printy(..., const char* fmt); // Error: ... must be the last
// int printa(const char* fmt...);   // Error in C: ',' is required; OK in C++

函数调用时,作为可变参数列表一部分的每个参数都会经历特殊的隐式转换,称为默认参数提升

在使用可变参数的函数体内部,可以使用<stdarg.h> 库设施访问这些参数的值

定义在头文件 <stdarg.h>
启用对可变参数函数参数的访问
(函数宏) [编辑]
访问下一个可变参数函数参数
(函数宏) [编辑]
复制可变参数函数参数
(函数宏) [编辑]
结束对可变参数函数参数的遍历
(函数宏) [编辑]
保存 va_start、va_arg、va_end 和 va_copy 所需的信息
(类型定义) [编辑]

目录

[编辑] 注释

尽管旧式(无原型)函数声明允许后续函数调用使用任意数量的参数,但它们不允许是可变参数的(从 C89 开始)。此类函数的定义必须指定固定数量的参数,并且不能使用 stdarg.h 宏。

// old-style declaration, removed in C23
int printx(); // function declared this way
printx("hello world");     // may be called with one
printx("a=%d b=%d", a, b); // or more arguments
// the behavior of at least one of these calls is undefined, depending on
// the number of parameters the function is defined to take

[编辑] 示例

#include <stdio.h>
#include <time.h>
#include <stdarg.h>
 
void tlog(const char* fmt,...)
{
    char msg[50];
    strftime(msg, sizeof msg, "%T", localtime(&(time_t){time(NULL)}));
    printf("[%s] ", msg);
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}
 
int main(void)
{
   tlog("logging %d %d %d...\n", 1, 2, 3);
}

输出

[10:21:38] logging 1 2 3...

[编辑] 参考

  • C17 标准 (ISO/IEC 9899:2018)
  • 6.7.6.3/9 函数声明符(包括原型)(页码:96)
  • 7.16 可变参数 <stdarg.h>(页码:197-199)
  • C11 标准 (ISO/IEC 9899:2011)
  • 6.7.6.3/9 函数声明符(包括原型)(页码:133)
  • 7.16 可变参数 <stdarg.h>(页码:269-272)
  • C99 标准 (ISO/IEC 9899:1999)
  • 6.7.5.3/9 函数声明符(包括原型)(页码:119)
  • 7.15 可变参数 <stdarg.h>(页码:249-252)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 3.5.4.3/5 函数声明符(包括原型)
  • 4.8 可变参数 <stdarg.h>

[编辑] 参见

C++ 关于可变参数的文档 for Variadic arguments