C 可変引数

時には、関数が事前定義された数の引数ではなく、可変数の引数を持つようにしたい場合があるかもしれません。

C言語はこのような状況に対する解決策を提供します。特定のニーズに応じて可変数の引数を受け取る関数を定義できます。

宣言方法は次のとおりです:

int func_name(int arg1, ...);

ここで、省略記号は...可変引数リストを表します。

次の例は、このような関数の使用法を示しています:

int func(int, ... ) { . . . } int main() { func(2, 2, 3); func(3, 2, 3, 4); }

注意してください。関数func()の最後の引数は省略記号、つまり3つのドット(...)で記述されています。省略記号の前の引数はintであり、渡される可変引数の総数を表します。この機能を使用するには、stdarg.hヘッダーファイルが必要です。このファイルには、可変引数機能を実装するための関数とマクロが用意されています。具体的な手順は次のとおりです:

  • 最後の引数が省略記号である関数を定義します。省略記号の前にカスタム引数を設定できます。
  • 関数定義内にva_list型変数を作成します。この型は stdarg.h ヘッダーファイルで定義されています。
  • 使用してint引数とva_start()マクロで初期化しますva_list変数を引数リストとして。マクロva_start()は stdarg.h ヘッダーファイルで定義されています。
  • 使用してva_arg()マクロとva_list変数で引数リストの各項目にアクセスします。
  • マクロを使用してva_end()、割り当てられたva_list変数のメモリをクリーンアップします。

一般的に使用されるマクロは次のとおりです:

  • va_start(ap, last_arg):可変引数リストを初期化します。apはva_list型の変数であり、last_argは最後の固定引数の名前です(つまり、可変引数リストの前の引数)。このマクロはapを可変引数リストの最初の引数に向けます。

  • va_arg(ap, type):可変引数リストの次の引数を取得します。apはva_list型の変数であり、typeは次の引数の型です。このマクロは型typeの値を返し、apを次の引数に向けます。

  • va_end(ap):可変引数リストへのアクセスを終了します。apはva_list型の変数です。このマクロはapを NULL に設定します。NULL。

それでは、上記の手順に従って、可変数の引数を持つ関数を作成し、それらの平均値を返すようにしましょう:

例

#include <stdio.h> #include <stdarg.h> double average(int num,...) { va_list valist; double sum = 0.0; int i; /*num 個の引数に対して valist を初期化する*/ va_start(valist, num); /*valist に割り当てられたすべての引数にアクセスする*/ for (i = 0; i < num; i++) { sum += va_arg(valist, int); } /*valist のために確保されたメモリをクリーンアップする*/ va_end(valist); return sum/num; } int main() { printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5)); printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15)); }

上記の例では、average() 関数は整数 num と任意の数の整数引数を受け取ります。関数内部では、va_list 型の変数 va_list を使用して可変引数リストにアクセスします。ループ内では、毎回 va_arg() マクロを使用して次の整数引数を取得し、出力します。最後に、関数の終了時に va_end() マクロを使用して可変引数リストへのアクセスを終了します。

上記のコードをコンパイルして実行すると、次の結果が生成されます。なお、関数 average()は2回呼び出され、毎回最初の引数は渡された可変引数の総数を示します。省略記号は可変数の引数を渡すために使用されます。

Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000
その他の拡張