ご存知の方もいるかもしれないがC言語には可変引数という概念がある。
一般的なC言語での関数の宣言は
int sum(int a, int b);みたいな感じだろう。
関数定義の際に必要なのは
戻り値の型 関数名 仮引数の型 仮引数名
となる。ここで仮引数は必要な数だけ定義し、関数呼び出しの際にも、定義した型、数の実引数を渡す。
しかし、普段からよく使うあのprintf()関数はどうなっているだろう。
様々な型の、様々な数の引数を渡しても正しく動作する。
これはprintf()関数を前述の感覚で捉えていると違和感を覚える。
様々な型の、不特定数の引数を受け取れるようにするのが
可変引数
という仕組みだ
可変引数を用いた関数定義はprintf()を例に取ると
int printf(const char *format, ...);となる。
この...の部分が可変引数の実体である。
可変引数を用いる為の関数等はstdarg.hで定義されている。
基本的な例は
#include <stdarg.h>
void (int last, ...){
va_list ap;
va_start(ap, last);
int arg[last];
for(int i; i < last; i++){
arg[last] = va_arg(ap, int);
}
va_end(ap);
}みたいな感じだ。
stdarg.h
受け取った複数の引数を一つにまとめる構造体。
va_start(va_list ap, last);last(引数郡の最初の変数)とapを受け取り、last以後の引数をapに格納する。
初期化処理だと思って良い。
型を指定しapから順番に引数を取り出す。
apをクリアする。
これらを上手く組み合わせることで、可変引数を受け取る関数を作れる。
以下は数値とその個数を与えると平均が帰ってくる関数
#include <stdarg.h>
float avg(int amnt, ...){
va_list list;
va_start(list, amnt);
float sum = 0;
for(int i = 0; i < amnt; i++){
sum += va_arg(list, int);
}
va_end(list);
return sum/amnt;
}