va_list
という型があり、これを使って可変長引数リストを操作できる。
va_list
は、SYSTEM_DATA_TYPES(7)
に説明がある。
example
#include <stdio.h> static void myprintf(char *first_arg, ...) { va_list ap; va_start(ap, first_arg); printf("%s\n", va_arg(ap, char *)); printf("%d\n", va_arg(ap, int)); va_end(ap); } int main(int argc, char **argv) { myprintf("first", "second", 3); return 0; }
output
second 3
va_list
を操作するマクロ
va_start
void va_start(va_list ap, last)
apを初期化する。 lastに指定するのは可変長引数の直前の引数。
va_end
void va_end(va_list ap);
va_listを他の関数でも使えるように、va_startを呼び出したら、その関数内でva_endは呼び出すことになっている。
va_endを呼び出すと、va_listはundefinedになる。
va_arg
type va_arg(va_list ap, type);
apが現在指している値の次の値を取得し、apが指すポイントを一つ進める。
va_startを呼び出した直後はapは可変長引数の直前の引数を指しているので、va_argをよびだすと、可変長引数の先頭の引数が返る。
va_copy
void va_copy(va_list dest, va_list src);
va_listの値をコピーするのに使用する。
srcが指す引数の位置ポインタの情報も含めてコピーする。
va_copyを呼び出したら、va_endでfreeしてやる必要がある。
example
#include <stdio.h> static void myprintf(char *first_arg, ...) { va_list ap; va_start(ap, first_arg); printf("1. ap: %s\n", va_arg(ap, char *)); va_list aq; va_copy(aq, ap); printf("1. aq: %s\n", va_arg(aq, char *)); printf("2. ap: %s\n", va_arg(ap, char *)); va_end(ap); va_end(aq); } int main(int argc, char **argv) { myprintf("first", "second", "third", "forth"); return 0; }
example
1. ap: second 1. aq: third 2. ap: third