階乗の計算(関数の利用)

01	/****************************/
02	/* nの階乗の計算           */
03	/*      coded by Y.Suganuma */
04	/****************************/
05	#include <stdio.h>
06	
07	double kaijo(int);
08	
09	int main()
10	{
11	/*
12	     データの入力
13	*/
14		int n;
15		printf("nの値を入力して下さい ");
16		scanf("%d", &n);
17	/*
18	     階乗の計算
19	*/
20		double kai = kaijo(n);
21	/*
22	     結果の出力
23	*/
24		printf("   %dの階乗は=%f\n", n, kai);
25	
26		return 0;
27	}
28	
29	/**************************/
30	/* mの階乗               */
31	/*      m : データ        */
32	/*      return : mの階乗 */
33	/**************************/
34	double kaijo(int m)
35	{
36		int i1;
37		double s = 1.0;
38		for (i1 = 1; i1 <= m; i1++)
39			s *= (double)i1;
40	
41		return s;
42	}
		
7 行目

  関数の宣言をしています.この例では,関数 kaijo が double 型の値を返し,また,int 型の値を 1 つ関数に引き渡すことを宣言しています.なお,29 行目以降の関数本体をこの場所に記述すれば,この行は必要なくなります.

  変数と同じように,関数における処理の結果に対しても様々な型が存在します.従って,関数毎にその関数が返す値の型を宣言してやる必要があります.もし,値を返さない場合は void と宣言する必要があります.

  基本的に,各関数は,全く別のプログラムであると考えた方が理解しやすいと思います.従って,関数を呼び出した側の情報を,呼び出された関数に伝えるには何らかの処理が必要です.例えば,階乗を計算する場合,階乗の対象となる n 自身の値が不明であれば,計算不可能です.情報を伝える 1 つの方法が引数です.この宣言では,int 型の引数( n )を 1 つ渡すことを宣言しています.もちろん,引き渡す情報を必要としなければ,引数も必要ありませんし,また,複数の引数を渡すことも可能です.

20 行目

  関数 kaijo にデータ n を渡し,関数を呼び出し,その結果を変数 kai に代入しています.この行は,24 行目と一緒にして,次のようにも書けます.
	printf("   %dの階乗は=%f\n", n, kaijo(n));			
29 ~ 33 行目

  29 から 42 行目までが,関数 kaijo の本体(関数の定義)です.これらの行は,関数の機能についての注釈です.このように,少なくとも,関数の機能,引数の意味,返す値に対する説明は必ず書いておいて下さい.

34 行目

  各関数定義の最初に記述する文です.返す値や引数の型は,必ず,7 行目の宣言や 20 行目の呼び出し時と一致していなければなりません.しかし,この例のように,引数の名前は呼び出し時と異なっても構いません(もちろん,同じでも構いません).main 関数における n の値が関数 kaijo の m にコピーされて関数が実行されます.

  しかし,その値のコピーが渡されるため,たとえ関数 kaijo で同じ変数名 n を使用していても,main の変数 n と kaijo の変数 n とは異なる変数です.従って,もし関数 kaijo 内で変数 n の値を変更しても,main の変数 n の値は変化しません.

  関数内で使用している他の変数についても同様です.ある関数と別の関数において,同じ名前の変数が定義され,使用されていても,それらは全く関係ありません.ある関数で,ある変数の値を変化させた場合,たとえそれが別の関数の変数と同じ名前であっても,その情報が何らかの方法で受け渡されない限り,別の関数ではその影響を全く受けません.

41 行目

  関数での処理を終了し,その結果を返すための文です.void 型の関数でない限り,必ずこの文が必要になります.なお,s の型は関数の型と一致している必要があります.