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

C言語の可変個引数関数(va_arg)で合計・最大値・最小値を求めるプログラム

固定された引数の個数を持たず、複数の引数を受け取れる関数を作りたい場面はよくあります。ここでは、与えられた数値の合計を計算する sum()、最大値を求める max()、最小値を求める min() の3つの関数を作成します。いずれの関数も、第1引数として「引数の個数」を受け取る仕様とします。

このような関数を定義するには、関数の引数リストに省略記号(...)を使用します。また、これらを利用するためには stdarg.h ヘッダーファイルをインクルードする必要があります。この種の関数は可変個引数関数(variadic function)と呼ばれます。

可変個引数を扱うための4つの要素

可変個引数にアクセスするために、以下の4つの機能を使用します。

  • va_list:渡されたすべての引数を保持する型
  • va_start:可変個引数へのアクセスを開始するマクロ
  • va_arg:指定した型で次の引数を取り出すマクロ
  • va_end:可変個引数リストへのアクセスを終了するマクロ

呼び出し例と期待される出力

例えば、次のように関数を呼び出した場合を考えます。

  • sum(5, 5, 2, 8, 9, 3)
  • max(3, 5, 9, 2)
  • min(6, 8, 5, 2, 6, 7, 9)

このとき、出力はそれぞれ 27(5つの数値の合計)、9(3つの数値の最大値)、2(6つの数値の最小値)となります。

アルゴリズムの手順

sum() 関数の定義

  1. 引数 cnt と可変個の引数を受け取る関数 sum() を定義する
  2. va_list 型の変数 ap を宣言する
  3. va_start(ap, cnt) で ap を初期化する
  4. n := 0 とする
  5. i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
    • n := n + va_arg(ap, int) で次の引数を加算する
  6. va_end(ap) でアクセスを終了する
  7. n を返す

min() 関数の定義

  1. 引数 cnt と可変個の引数を受け取る関数 min() を定義する
  2. va_list 型の変数 ap を宣言する
  3. va_start(ap, cnt) で ap を初期化する
  4. minimum := 99999 とする
  5. i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
    • current := va_arg(ap, int) で次の引数を取得する
    • current < minimum ならば minimum := current と更新する
  6. va_end(ap) でアクセスを終了する
  7. minimum を返す

max() 関数の定義

  1. 引数 cnt と可変個の引数を受け取る関数 max() を定義する
  2. va_list 型の変数 ap を宣言する
  3. va_start(ap, cnt) で ap を初期化する
  4. maximum := 0 とする
  5. i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
    • current := va_arg(ap, int) で次の引数を取得する
    • current > maximum ならば maximum := current と更新する
  6. va_end(ap) でアクセスを終了する
  7. maximum を返す

実装例

以下の実装を見ると、理解がより深まるでしょう。

#include <stdio.h>
#include <stdarg.h>
int sum (int cnt,...) {
    va_list ap;
    int i, n;
    va_start(ap, cnt);
    n = 0;
    for (i=0;i<cnt;i++){
        n += va_arg(ap, int);
    }
    va_end(ap);
    return n;
}
int min(int cnt,...) {
    va_list ap;
    int i, current, minimum;
    va_start(ap, cnt);
    minimum = 99999;
    for (i=0;i<cnt;i++){
        current = va_arg(ap, int);
        if (current < minimum)
            minimum = current;
    }
    va_end(ap);
    return minimum;
}
int max(int cnt,...) {
    va_list ap;
    int i, current, maximum;
    va_start(ap, cnt);
    maximum = 0;
    for (i=0;i<cnt;i++){
        current = va_arg(ap, int);
        if (current > maximum)
            maximum = current;
    }
    va_end(ap);
    return maximum;
}
int main(){
    printf("%d\n",sum(5, 5, 2, 8, 9, 3));
    printf("%d\n",max(3, 5, 9, 2));
    printf("%d\n",min(6, 8, 5, 2, 6, 7, 9));
}

入力

sum(5, 5, 2, 8, 9, 3)
max(3, 5, 9, 2)
min(6, 8, 5, 2, 6, 7, 9)

出力

27
9
2
  1. ExcelのMIN・MAX・AVERAGE関数の使い方|平均値・最小値・最大値の求め方

    Excelの関数は、セル範囲に対して数学的な計算を実行するための便利な機能です。特によく使われる関数には、SUM(合計)、AVERAGE(平均)、COUNT(個数)、MIN(最小値)、MAX(最大値)などがあります。データの平均値・最小値・最大値を調べたいときは、AVERAGE、MIN、MAX関数を使えば簡単に求められます。この記事では、Excelでこれらの値を計算する具体的な手順をわかりやすく解説します。 ExcelのAVERAGE・MIN・MAX関数とは AVERAGE関数:指定したセル範囲内の数値の平均値(相加平均)を返します。数値のほか、名前、配列、数値を含むセル参照なども引数として

  2. Pythonで二分木の各ノードを左右の部分木の合計値で更新するプログラム

    問題の概要 二分木が与えられたとき、各ノードの値を「自分自身の値 + 左右の部分木の合計」に置き換えた木を求めることを考えます。つまり、木を葉から根へ(ポストオーダー)たどりながら、すべてのノードを部分木の総和で更新していく処理です。 例えば、次のような二分木が入力として与えられたとします。 この場合、出力は次のようになります。 アルゴリズム この問題は再帰を使ったポストオーダー走査でシンプルに解けます。手順は以下の通りです。 関数 tree_sum() を定義します。引数として木のルートを受け取ります。 ルートが None(空)の場合は 0 を返します。 そうでなければ、ルートの値を