C
编译器支持
语言
头文件
类型支持
程序工具
变参函数支持
错误处理
动态内存管理
字符串库
算法
数值
日期和时间工具
输入/输出支持
本地化支持
并发支持 (C11)
技术规范
符号索引
[编辑] C 语言
基本概念
关键词
预处理器
语句
表达式
初始化
声明
函数
杂项
C 的历史
技术规范
[编辑] 函数
函数声明
函数定义
可变参数
inline(C99)
_Noreturn(C11)
[编辑]
可变参数函数是指可以以不同数量的参数调用的函数。
只有带原型的函数声明才能是可变参数的。这通过形如...的参数表示,它必须出现在参数列表的最后,并且必须至少跟在一个命名参数之后(直至 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++
在函数调用时,作为可变参数列表一部分的每个参数都会经历特殊的隐式转换,称为默认参数提升。
在使用可变参数的函数体内,可以使用
定义于头文件
va_start
启用对变长函数参数的访问 (函数宏) [编辑]
va_arg
访问下一个变长函数参数 (函数宏) [编辑]
va_copy(C99)
复制变长函数参数 (函数宏) [编辑]
va_end
结束变长函数参数的遍历 (函数宏) [编辑]
va_list
保存 va_start、va_arg、va_end 和 va_copy 所需的信息 (类型定义) [编辑]
目录
1 注意
2 示例
3 参考
4 参见
[编辑] 注意
尽管旧式(无原型)函数声明允许随后的函数调用使用任意数量的参数,但它们不允许是可变参数的(自 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
#include
#include
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 函数声明符(包括原型)(p: 96)
7.16 可变参数
C11 标准 (ISO/IEC 9899:2011)
6.7.6.3/9 函数声明符(包括原型)(p: 133)
7.16 可变参数
C99 标准 (ISO/IEC 9899:1999)
6.7.5.3/9 函数声明符(包括原型)(p: 119)
7.15 可变参数
C89/C90 标准 (ISO/IEC 9899:1990)
3.5.4.3/5 函数声明符(包括原型)
4.8 变长参数
[编辑] 另请参阅
C++ 文档关于可变参数