関数について

といったあたりをプログラム例を使って説明する.

以下のプログラムは, 1から10までの整数の和を求めるのに, 三種類の関数を定義して使っている. 実行すれば当然同じ結果(55)が得られる.

最初の関数 sum_upto_1 は, 関数の中でループを行って, 結果を求めている. 関数の引数 n やローカル変数 i, j は, この関数の呼び出しのときに作られて, 関数からリターンすると消滅する. また, 呼出し側(このプログラムでは main)の 同じ名前の変数(i, n)とはまったく別の変数であって, おたがいに影響を及ぼさない. (たとえば, 変数 i はこの関数の中で 1 から 55 まで値を変えるが, main の i はずっと 10 のままである.)

二番目の関数 sum_upto_2 は, 等差数列の和の公式を使って 結果を一気に計算している. 実行時間も最初の関数よりも早いはずである. return 文には, 変数だけでなくて一般の式が書けるので, ここではそれを利用してプログラムを簡潔にしている. ここで大切なことは, 最初の関数を使おうと二番目の関数を使おうと, 計算結果はまったくおなじであり, (実行時間を除いて)呼出し側には 何も違いはないという点である.

三番目の関数は, 次のような漸化式を そのまま関数にしたものである.

sum_upto_3(n) = 1 (if n=1) n + sum_upto_3(n-1) (else)
数式として考えれば, この漸化式はべつに難しいものではない ことがわかってもらえると思う. (「n までの和というのは, (n-1)までの和に n を足したものである.」) ところが, これをプログラムにすると, 「関数定義の中に, 自分自身への呼び出しが含まれる」 ということになって, 再帰呼び出し(recursive call)などと 立派な名前がつく. まあこれは漸化式のことだ, と理解しておいて大きな間違いはない.
#include <stdio.h> int sum_upto_1(int n){ int i; int j; i = 0; for(j = 1; j <= n; j++){ i = i + j; } return i; } int sum_upto_2(int n){ return (n + 1) * n / 2; } int sum_upto_3(int n){ int result; if(n == 1){ result = 1; } else { result = n + sum_upto_3(n-1); } return result; } int main(){ int i; int n; i = 10; n = sum_upto_1(i); printf("%d\n", n); n = sum_upto_2(i); printf("%d\n", n); n = sum_upto_3(i); printf("%d\n", n); }

[page 9] prev index next