名前空間
変種
操作

可変長引数

From cppreference.com
< c‎ | language

可変関数とは、異なる数の引数で呼び出し可能な関数のことです。

可変関数とできるのは、プロトタイプ宣言された関数宣言のみです。これは、パラメータリストの最後に配置される...という形式のパラメータで示されます。この省略記号パラメータは(C23まで)少なくとも1つの名前付きパラメータに続く必要があります。省略記号パラメータとそれに先行するパラメータは、,で区切る必要があります。

// 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 で必要とされる情報を保持する
(typedef) [編集]

目次

[編集] 注釈

古い形式(プロトタイプなし)の関数宣言では、後続の関数呼び出しで任意の数の引数を使用できますが、(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++ ドキュメント可変引数
English 日本語 中文(简体) 中文(繁體)