C言語/標準ライブラリ/stdarg.h

出典: フリー教科書『ウィキブックス(Wikibooks)』

stdarg.hは可変長引数を扱う際に使用するヘッダーです[1]。可変長引数とは、関数に渡す引数の数を実行時に変更できる仕組みのことです。この機能は以下のようなケースで役立ちます。

  1. printf関数のような可変長引数を取る関数の実装
    printfは可変長引数を取り、フォーマット文字列に応じて任意の数の引数を出力します。
  2. ラッパー関数の実装
    既存の関数に処理を追加したり、引数を変更したりする際に使えます。
  3. グループ化された引数の渡し方
    複数の値をグループ化して1つの引数として渡せます。

使用例を見ていきましょう。

printf関数の簡易実装
#include <stdarg.h>
#include <stdio.h>

void my_printf(const char* format, ...) {
    va_list args;
    va_start(args, format);
    
    while (*format) {
        if (*format == '%') {
            format++;
            switch(*format) {
                case 'd':
                    printf("%d", va_arg(args, int));
                    break;
                ...
            }
        } else {
            putchar(*format);
        }
        format++;
    }
    
    va_end(args);
}

int main() {
    my_printf("Answer is %d\n", 42);
    return 0;
}
グループ化された引数の受け渡し
#include <stdarg.h>

typedef struct {
    int x;
    int y;
} Point;

Point make_point(int x, int y) {
    Point p = {x, y};
    return p;
}

Point make_point_var(int num, ...) {
    va_list args;
    va_start(args, num);
    Point p = {va_arg(args, int), va_arg(args, int)};
    va_end(args);
    return p;
}

int main() {
    Point p1 = make_point(1, 2);
    Point p2 = make_point_var(2, 3, 4);
    return 0;
}

可変長引数は型の安全性がなく、間違った使い方をするとセグメンテーション違反などの深刻なエラーにつながる可能性があるため、十分に注意が必要です。一方で、柔軟性が高く様々な場面で活用できるという利点もあります。

脚註[編集]

  1. ^ N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E). ISO/IEC JTC1/SC22/WG14. p. 246, §7.16 Variable arguments <stdarg.h>. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf. 

参考文献[編集]