名稱空間
變體
操作

變長引數

來自 cppreference.com
< c‎ | 語言

可變引數函式是指可以以不同數量的引數呼叫的函式。

只有帶原型的函式宣告才能是可變引數的。這透過形如...的引數表示,它必須出現在引數列表的最後,並且必須至少跟在一個命名引數之後(直至 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_startva_argva_endva_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++ 文件關於可變引數