C標準ライブラリ -<stdarg.h>
<stdarg.h>C標準ライブラリ内のヘッダファイルであり、可変数の引数にアクセスするためのマクロ群を提供します。
stdarg.hヘッダファイルは1つの変数型を定義しています。va_listおよび3つのマクロを定義しています。これらのマクロは、引数の数が不明(すなわち引数の数が可変)の場合に関数の引数を取得するために使用できます。
可変引数の関数は通常、引数リストの末尾に省略記号(...)を使用して...定義されます。
ライブラリ変数
以下はヘッダファイル stdarg.h で定義されている変数型です:
| 番号 | 変数 & 説明 |
|---|---|
| 1 | va_list これは、va_start()、va_arg()とva_end()3つのマクロが情報を格納するための型です。可変引数情報を格納するために使用される型です。 |
ライブラリマクロ
以下はヘッダファイル stdarg.h で定義されているマクロです:
| 番号 | マクロ & 説明 |
|---|---|
| 1 | void va_start(va_list ap, last_arg) このマクロは、ap変数を初期化します。これはva_argとva_endマクロと一緒に使用されます。last_argは、関数に渡される最後の既知の固定引数、すなわち省略記号の前の引数です。 |
| 2 | type va_arg(va_list ap, type) このマクロは、関数の引数リストから型がtypeの次の引数を取得します。 |
| 3 | void va_end(va_list ap) このマクロにより、va_startマクロを使用した可変引数を持つ関数が戻ることができます。関数から戻る前に呼び出されなかった場合、va_end結果は未定義です。 |
例
以下は、<stdarg.h>を使用して可変引数関数を実装する例です。この関数はすべての引数の合計を計算します:
例
#include <stdio.h>
#include <stdarg.h>
// 可変引数の合計を計算する
int sum(int count, ...) {
int total = 0;
va_list args;
// 可変引数にアクセスするために args を初期化する
va_start(args, count);
// 可変引数を1つずつ取得する
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
// args をクリーンアップする
va_end(args);
return total;
}
int main() {
printf("Sum of 1, 2, 3: %d\n", sum(3, 1, 2, 3)); // 6 を出力
printf("Sum of 4, 5, 6, 7: %d\n", sum(4, 4, 5, 6, 7)); // 22 を出力
return 0;
}
#include <stdarg.h>
// 可変引数の合計を計算する
int sum(int count, ...) {
int total = 0;
va_list args;
// 可変引数にアクセスするために args を初期化する
va_start(args, count);
// 可変引数を1つずつ取得する
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
// args をクリーンアップする
va_end(args);
return total;
}
int main() {
printf("Sum of 1, 2, 3: %d\n", sum(3, 1, 2, 3)); // 6 を出力
printf("Sum of 4, 5, 6, 7: %d\n", sum(4, 4, 5, 6, 7)); // 22 を出力
return 0;
}
出力結果:
Sum of 1, 2, 3: 6 Sum of 4, 5, 6, 7: 22
解説
va_list args;:1つのva_list変数を宣言し、可変引数にアクセスします。va_start(args, count);:初期化するargs可変引数リストを走査するために、countの後の最初の引数から開始します。total += va_arg(args, int);:可変引数リストの次の引数を取得し、それをtotalに加算します。引数型はint。va_end(args);:クリーンアップするargs。
注意事項
- 可変引数リスト内の各引数の型は明確でなければならず、一貫して
va_arg。 - に渡して使用する必要があります。
va_start使用したva_end後は、va_listを使用してクリーンアップする必要があります。 va_start、va_argとva_endマクロは関数内でペアで使用する必要があります。未定義の動作を避けるためです。