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() 関数の定義
- 引数 cnt と可変個の引数を受け取る関数 sum() を定義する
- va_list 型の変数 ap を宣言する
- va_start(ap, cnt) で ap を初期化する
- n := 0 とする
- i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
- n := n + va_arg(ap, int) で次の引数を加算する
- va_end(ap) でアクセスを終了する
- n を返す
min() 関数の定義
- 引数 cnt と可変個の引数を受け取る関数 min() を定義する
- va_list 型の変数 ap を宣言する
- va_start(ap, cnt) で ap を初期化する
- minimum := 99999 とする
- i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
- current := va_arg(ap, int) で次の引数を取得する
- current < minimum ならば minimum := current と更新する
- va_end(ap) でアクセスを終了する
- minimum を返す
max() 関数の定義
- 引数 cnt と可変個の引数を受け取る関数 max() を定義する
- va_list 型の変数 ap を宣言する
- va_start(ap, cnt) で ap を初期化する
- maximum := 0 とする
- i := 0 から i < cnt の間、i を1ずつ増やしながら繰り返す
- current := va_arg(ap, int) で次の引数を取得する
- current > maximum ならば maximum := current と更新する
- va_end(ap) でアクセスを終了する
- 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
-
ExcelのMIN・MAX・AVERAGE関数の使い方|平均値・最小値・最大値の求め方
Excelの関数は、セル範囲に対して数学的な計算を実行するための便利な機能です。特によく使われる関数には、SUM(合計)、AVERAGE(平均)、COUNT(個数)、MIN(最小値)、MAX(最大値)などがあります。データの平均値・最小値・最大値を調べたいときは、AVERAGE、MIN、MAX関数を使えば簡単に求められます。この記事では、Excelでこれらの値を計算する具体的な手順をわかりやすく解説します。 ExcelのAVERAGE・MIN・MAX関数とは AVERAGE関数:指定したセル範囲内の数値の平均値(相加平均)を返します。数値のほか、名前、配列、数値を含むセル参照なども引数として
-
Pythonで二分木の各ノードを左右の部分木の合計値で更新するプログラム
問題の概要 二分木が与えられたとき、各ノードの値を「自分自身の値 + 左右の部分木の合計」に置き換えた木を求めることを考えます。つまり、木を葉から根へ(ポストオーダー)たどりながら、すべてのノードを部分木の総和で更新していく処理です。 例えば、次のような二分木が入力として与えられたとします。 この場合、出力は次のようになります。 アルゴリズム この問題は再帰を使ったポストオーダー走査でシンプルに解けます。手順は以下の通りです。 関数 tree_sum() を定義します。引数として木のルートを受け取ります。 ルートが None(空)の場合は 0 を返します。 そうでなければ、ルートの値を