變長引數
來自 cppreference.com
可變引數函式是指可以以不同數量的引數呼叫的函式。
只有帶原型的函式宣告才能是可變引數的。這透過形如...的引數表示,它必須出現在引數列表的最後,並且必須至少跟在一個命名引數之後(直至 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> 中 | |
啟用對變長函式引數的訪問 (函式宏) | |
訪問下一個變長函式引數 (函式宏) | |
(C99) |
複製變長函式引數 (函式宏) |
結束變長函式引數的遍歷 (函式宏) | |
儲存 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 函式宣告符(包括原型)(p: 96)
- 7.16 可變引數 <stdarg.h> (p: 197-199)
- C11 標準 (ISO/IEC 9899:2011)
- 6.7.6.3/9 函式宣告符(包括原型)(p: 133)
- 7.16 可變引數 <stdarg.h> (p: 269-272)
- C99 標準 (ISO/IEC 9899:1999)
- 6.7.5.3/9 函式宣告符(包括原型)(p: 119)
- 7.15 可變引數 <stdarg.h> (p: 249-252)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 3.5.4.3/5 函式宣告符(包括原型)
- 4.8 變長引數 <stdarg.h>
[編輯] 另請參閱
C++ 文件關於可變引數
|