va_arg、va_end、va_start
Stdarg.h:インデックス への移動
ヘッダー ファイル
stdarg.h
カテゴリ
可変引数リスト ルーチン
プロトタイプ
void va_start(va_list ap, lastfix);
type va_arg(va_list ap, type);
void va_end(va_list ap);
説明
可変引数リストを実装します。
vfprintf や vprintf など、一部の C 関数は、いくつかの固定(既知)パラメータに加えて、可変引数リストを受け取ります。va_arg、va_end、va_start の各マクロは、このような引数リストにアクセスするための移植性の高い方法を提供します。これらは、呼び出された関数で、渡された引数の数と型がわからない場合に、引数リスト内を順に調べるために使用されます。
ヘッダー ファイル stdarg.h では、1 つの型(va_list)と 3 つのマクロ(va_start、va_arg、va_end)が宣言されています。
- va_list: この配列には、va_arg と va_end で必要になる情報が格納されています。呼び出される関数では、可変引数リストを受け取る場合、va_list 型の変数 ap を宣言します。
- va_start: このルーチン(マクロとして実装)は、関数に渡された可変引数の先頭を指すように ap を設定します。va_arg または va_end を初めて呼び出す前に va_start を使用する必要があります。
- va_start は ap と lastfix の 2 つのパラメータを取ります。ap については、上記 va_list の段落で説明しています。lastfix は、呼び出される関数に渡される最後の固定パラメータの名前です。
- va_arg: このルーチン(これもマクロとして実装)は、次に渡される引数(可変引数の 1 つ)と同じ型と値の式に展開されます。va_arg に渡される変数 ap は、va_start で初期化した ap と同じでなければなりません。
メモ: 型の昇格がデフォルトで行われるため、va_arg で char、unsigned char、float の各型を使用することはできません。
メモ: va_arg を初めて使用したとき、va_arg はリスト内の最初の引数を返します。その後 va_arg を使用するたびに、va_arg はリスト内の次の引数を返します。これを実現するために、va_arg では、最初は ap を逆参照し、それ以降は次の項目を指すように ap をインクリメントします。va_arg では型を使用して、逆参照の実行と次の項目の検索の両方を行います。va_arg が続けて呼び出されるたびに、リスト内の次の引数を指すように ap が変更されます。
- va_end: このマクロは、呼び出された関数が正常に戻るのに役立ちます。va_end は ap を変更する可能性があり、その場合は va_start を再度呼び出さない限り ap を使用できません。va_end を呼び出すのは、va_arg がすべての引数を読み取ってからでなければなりません。そうしないと、不明な未定義の動作がプログラムで発生するおそれがあります。
戻り値
va_start と va_end は値を返しません。va_arg はリスト内の現在の引数(ap が指している引数)を返します。
例
#include <stdio.h> #include <stdarg.h> /* 0 で終了するリストの合計を計算する */ void sum(char *msg, ...) { int total = 0; va_list ap; int arg; va_start(ap, msg); while ((arg = va_arg(ap,int)) != 0) { total += arg; } printf(msg, total); va_end(ap); } int main(void) { sum("The total of 1+2+3+4 is %d\n", 1,2,3,4,0); return 0; }
移植性
POSIX | Win32 | ANSI C | ANSI C++ |
---|---|---|---|
+ |
+ |
+ |
+ |