「C言語練習」 2-1.c   ・前へ   ・次へ
/* 関数   2-1.c */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* 「一連の同じ計算」をprogram中で何度も行う場合や「複雑な処理」を行う場合には、それら
の操作を一つの纏まりとして本体のprogramから切り離して処理すれば、programがすっきりと
した形になる。こういう目的の為に、C言語では関数を自分で作る事が出来る。作った関数は、
当然main()の外に置くが、main()の前に置く事も後に置く事も出来る。前に置く場合は、関数を
そのまま記述すれば良い。後に置くと、main()でその関数を呼び出した時に未定義(見た事が
ない!)となるので、関数の型だけを前以ってmain()の前に書いておく。こうして置けばエラー
は出ない。これを関数のprototype宣言(proto=初めの, type=型)という。小さな関数の場合を
除き、prototype宣言してある方が分かり易い。ここでは、関数をprototype宣言しておく事に
する。 
 関数は、関数名(引数1,引数2,,,) { }の形で書く。main()が関数に渡す変数(=引数)は、
必要数だけカンマ ,で区切って( )内に書き、{ }の中に処理内容を記述する。関数は、ある値を
得る為に(そうでない関数もあるが)一連の演算を行い、得られた値をreturnでmain()に返す。
返せる値は一つだけである。

 関数で用いる変数(引数以外)は中で宣言する。変数は関数毎に独立しており、main()で使う
変数と同名の変数を宣言し、その値を変えてもmain()の変数値には影響しない。引数名も同様
に自由であり、その型だけ分かっていれば良い。
 従って、関数は引数の型を明示すると共に、関数名にも型名を付けて(関数の返す値が何型か
を示す為)書く事になる。

 下が、関数のprototype宣言。関数の返す値がfloatなので関数名にfloatを付けている。
引数の前にも型が必要。また、宣言時には関数名の最後に;が要る。
*/

float f_mean(int n,float sum);
float f_sd(int n,float sum,float s2);

main()
{
	int n;
	float sum,s2,d;
	float mean,sd;
	char fname[50];

	FILE *fin;

	printf("* File data の平均と標準偏差 [関数使用]\nFile名を入力:");
		gets(fname);
	putchar('\n');

		fin=fopen(fname,"r");	// fileを開ける
		if (fin==NULL) {printf("File がありません!\n\nEnd\n"); exit(1);}

		sum=0;s2=0;n=0;
	while (! feof(fin)) {
		fscanf(fin,"%f",&d);
		sum+=d; s2+=d*d;
		n++;
		printf("%3d:%.2f ",n,d); if (n%5==0) putchar('\n');
	}
		fclose(fin);	// fileを閉じる。

	mean=f_mean(n,sum); sd=f_sd(n,sum,s2);	// 平均と偏差を関数で求める

/*  関数を使う時はこう書く。文末に;が必要。先ず、f_mean()という関数にdata数 nと
総和 sumを渡して計算を頼み、その結果をmeanという変数に代入している。次に、nと sumと
平方和 s2をf_sd()という関数に渡して、その結果をsdに代入している。引数の型は予め宣言
してあるので、nをint、sum,s2をfloatと判断する。関数本体は、main()の後に書いてある。
*/
	printf("\n(n=%d) sum=%d  mean=%.2f  sd=%.2f",n,sum,mean,sd);

printf("\nEnd\n");
return 0;
}


/*  ここからが関数。f_mean()では、計算式自体をreturnで返している。非常に簡単だが、
  先ずは練習 */

float f_mean(int n,float sum)
{
	return (sum/n);
}

float f_sd(int n,float sum,float s2)
{
	s2=s2-sum*sum/n; s2=s2/(n-1); s2=sqrt(s2);
	return s2;
}



(前に戻る)   ・次へ