第43章 可変個の引数を取る関数  


さて、今回は可変個の引数を取る関数を自作しようというものです。 すでにおなじみのprintfは

printf("%d\n", 3);

print("%d, %s\n", 4, "test");

など引数の個数は任意ですね。このような関数を 可変個の引数を取る関数と言います。

おーっ!こりゃ難しそうだな。

そんなことはありません。理屈は確かに難しいのですが、 やり方さえ覚えれば、そんなに大変ではありません。 「猫でもわかる」式に覚えてしまいましょう!

手順 0.#include <stdarg.h>これをインクルード 1.可変個の引数を取る関数を int func(x, ...); のように書く。...の所は、実際にピリオドを3つ書く。   関数の戻り値は任意でよい。もちろん関数名も何でもよい。   上の例の場合、xを必須の引数...をオプション引数という。 2.この関数の中に、   va_list型の変数を1つ宣言する。 たとえば、 va_list ptr;   のように。 3.va_start(ptr, x);と   va_end(ptr);でサンドイッチされた所で   オプション引数を取得する   これにはva_arg(ptr, 引数の型名); を使う。   これが呼ばれるごとに自動的にポインタが進み   次々に引数を取得できる

どうです。意味は分からないとしても作り方はわかったような気になるでしょう。 では、実際にどんなふうになるか実験のプログラムを書いてみましょう。 これは、実験のためのプログラムで実際は間違ったプログラムです。

va_start(ptr, x);とva_end(ptr);で挟まれた位置で オプション引数を取得します。 これには、va_arg(ptr, 型);を使います。 va_arg(ptr, 型);が呼ばれる(これは、マクロなので 「呼ばれる」という表現は正しくないのですが・・) たびにオプション引数が次々に取得できます。

でも、オプション引数の個数がわからないので 何回引数を取得すればいいのでしょう???

最初の引数は、必須引数です。次からは オプション引数です。2,3,4までは、 正しいですね。この場合オプション引数は、3個しかないので それ以上に引数を取得しようとするとまずいことが起こります。 場合によっては暴走するかもしれませんので、 このようなプログラムは あまり実験しないでください。

書き方は、何となくわかったが、引数の個数が わからなきゃあんまり意味がないな・・と、お思いのあなた、 いくつかうまい方法があります。 最初の必須引数を引数の個数にするとか、引数の最後に 「もう引数がないよ」というマーカーをつけるとか・・

最初の方法でプログラムを書き直してみましょう。

func関数の最初の引数は、(全部の)引数の個数としました。 全部で引数が5個あるならfunc(5, 1, 2, 3, 4);という具合に 使います。

今度はうまく行ったようです。

今度は、引数の最後は−1という約束で 関数を作ってみました。 上のものとどちらが好きかは、個人の好みの問題です。 他にもいろいろ方法があると思います。 みなさんも、考えてみてください。

当然、うまく動作していますね。


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Dec/13/1996 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。