Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語の可変長引数(stdarg.h)の使い方をわかりやすく解説


プログラミングをしていると、引数の数をあらかじめ固定せず、呼び出しのたびに異なる個数の引数(パラメータ)を受け取れる関数を作りたい場面に出くわすことがあります。C/C++言語では、このニーズに応える仕組みが標準で用意されており、要件に合わせて可変個の引数を受け取る関数を定義できます。以下に、そのような関数の定義例を示します。

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

ここで注目すべきは、関数 func() の最後の引数が省略記号(エリプシス、3つの点 ... )になっている点です。また、省略記号の直前に置かれる引数は必ず int 型とし、そこで渡された可変引数の総数を表します。この機能を利用するには、可変引数を実現するための関数やマクロを提供している stdarg.h ヘッダーをインクルードし、以下の手順に従います。

  • 最後の引数を省略記号(...)として関数を定義します。省略記号の直前には、引数の個数を表す int 型の引数を必ず配置します。
  • 関数定義の中で va_list 型の変数を宣言します。この型は stdarg.h ヘッダーで定義されています。
  • int 型の引数と va_start マクロを使って、va_list 変数を引数リストとして初期化します。va_start マクロも stdarg.h で定義されています。
  • va_arg マクロと va_list 変数を使って、引数リスト内の各要素に順番にアクセスします。
  • va_end マクロを使って、va_list 変数に割り当てられたメモリをクリーンアップします。

それでは、上記の手順に沿って、可変個の引数を受け取り、その平均値を返すシンプルな関数を実際に書いてみましょう。

サンプルコード

#include <stdio.h>
#include <stdarg.h>

double average(int num, ...) {
    va_list valist;
    double sum = 0.0;
    int i;

    va_start(valist, num); /* num個の引数のためにvalistを初期化 */
    for (i = 0; i < num; i++) {
        /* valistに割り当てられたすべての引数へアクセス */
        sum += va_arg(valist, int);
    }
    va_end(valist); /* 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", average(3, 5, 10, 15));
}

実行結果

Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000

可変長引数を使う際の注意点

可変長引数を利用する際には、いくつかのポイントに注意が必要です。まず、省略記号(...)の前には少なくとも1つの名前付き引数を配置する必要があります。また、va_arg マクロで指定する型が、実際に渡された引数の型と一致しない場合、動作は未定義となります。さらに、引数の個数や型はコンパイラによってチェックされないため、「個数を最初の引数で渡す」「printf のように形式文字列で型と個数を示す」など、呼び出し側と関数側の間での取り決めを明確にしておくことが非常に重要です。

  1. CおよびC++における可変長配列(VLA)の徹底解説

    本記事では、CおよびC++における可変長配列(Variable Length Array:VLA)について詳しく解説します。可変長配列を利用すると、実行時にサイズが決まる自動配列(スタック上の配列)を柔軟に確保できます。C99での可変長配列のサポートC言語では、C99規格以降、可変長配列が正式にサポートされており、次のように引数で渡された値をもとに配列サイズを指定できます。void make_arr(int n){     int array[n]; } int main(){     make_arr(10);

  2. C++プログラムで文字列を「X」字型に表示する方法

    文字列が与えられたとき、その文字列を「X」字型のパターンとして出力するプログラムを作成します。完成イメージは以下の通りです。考え方このパターンを実現するには、3つの変数を活用します。i:行ごとに左から右へ進む位置を表す変数j:右から左へ進む位置を表す変数(len-1-i で計算)k:各行内のスペースと文字の出力位置を判定するための変数各行では、k の位置が i または j と一致した場合にのみ該当する文字を出力し、それ以外の位置にはスペースを表示します。これにより、対角線上に文字が配置された「X」字型のパターンが描かれます。アルゴリズム 関数 void print(string str, in