6-5 <発展> 可変長引数

この記事は約2分で読めます。

本トピックは発展的な内容を扱うので飛ばして構いません。一通りC言語の学習を終えてから見ることをお勧めします。

C言語の関数は、原則として引数の個数やその型はコンパイル時に決まっています。例えば、2つ引数を受け取る関数に対して3つの引数で呼び出そうとするとコンパイルエラーとなります。

しかし、printfやscanfは第一引数に応じていくつでも引数を受け取ることができます。これはコンパイルエラーにならないのでしょうか?

C言語には、任意の型、任意の個数の引数を受け取る機能があります。それを可変長引数といいます。今回は、int型の整数を任意の数受け取れるような関数を作ります。まず、ヘッダファイルstdarg.hをインクルードします。プロトタイプ宣言は次のようになります。

void PrintInt(int,...);

第一引数にint型の値を指定しています。第2引数以降は可変長引数を表す記号…を使います。第一引数を消すことはできません。可変長引数を使う場合は、少なくとも一つの通常の引数が必要です。その次、可変長引数にアクセスするには

va_start(va_list型の変数,引数の個数);

と書く必要があります。そして、

va_arg(va_list型の変数,型);

を使用して引数にアクセスします。最後に

va_end(va_list型の変数);

として終了です。これらの関数は、多くの処理系ではマクロで定義されています。

#include <stdio.h>
#include <stdarg.h>
void PrintInt(int,...);
int main(void){
	PrintInt(3,6,5,-65);
	return 0;
}
void PrintInt(int argn,...){
	va_list args;
	int value,i;
	if (argn<1) return;
	printf("第1引数=%d\n",argn);
	va_start(args,argn);
	for(i=0;i<argn;i++){
		value=va_arg(args,int);
		printf("第%d引数=%d\n",i+2,value);
	}
	va_end(args);
}

実行結果

第1引数=3
第2引数=6
第3引数=5
第4引数=-65

まとめ

printfやscanf関数は第一引数に応じて、第2引数以降の引数の個数、型を自由に受け取ることができ、これを可変長引数という。

stdarg.hをインクルードすると、可変長引数を持つ関数を自由に定義できる。

コメント