「C言語練習」 1-7.c   ・前へ   ・次へ
/* 偏差計算、配列、並べ替え   1-7.c */
#include <stdio.h>
#include <math.h>	// 今回は、このinclude文も書いておく。
/* math(mathematics=数学).hは、数学の関数を色々定義してあるheader file。
平方根を求めるのに必要。*/

main()
{
/* 平均値や最大・最小値を求める場合には入力値に当てる変数は一つでも良い。しかし、個々の
値を呼び出して何らかの処理をしたい場合には、変数がdataの数だけ必要になる。その場合、個別
に異なった変数名を付けると手に負えなくなるので、同じ変数名で幾つものdataを扱えるように
する。それが配列である。
 */
	int i,j,a,n;
	int d[1000];	// [ ]の形に注意。幾つdataがあるか分からないので多めに宣言。
	float sum,s2;

/* ここで int d[1000]としたのが、整数型の配列宣言である。これは、d[0],d[1],d[2],,,,,,
という様に、[ ]中の数(=添え字)の違いで異なる変数を表す。d[10]と宣言した場合、変数d[]は
10個確保される。ただし一番初めが[0]なので、最後は[9]になる。10番目の積もりでd[10]に値を
入れるとエラーになるので注意。うっかり… が結構ある。
 先ず、配列を使わずに平均と標準偏差を求める。
*/
		printf("入力dataの平均値と標準偏差を求める。[終了=999]\n");
		sum=0;s2=0;	// 初期化。
	for (i=0;i<1000;i++) {	// data数が幾つか分からないので、回る数を多めに取っておく。
		printf("No.%2d:",i+1);	// %2dと書くと 2桁右詰め表示。
			scanf("%d",&a);	// &を忘れぬ事。
			if (a==999) break;	// 入力値 aが999だったら、loopを抜ける。
		sum+=a;	// 総和
		s2+=a*a;	// 平方和
	}

/* 標準偏差を求めるには、先ず偏差平方和(平方和から総和の平方をdata数で割ったものを引く)
を計算。それを更に(data数-1)で割って分散を求め、その平方根を取る。data数は iなので、次の
様に書ける。
 */
		s2=s2-sum*sum/i; s2=s2/(i-1); s2=sqrt(s2);

/* 整数宣言された数値同士の計算結果は整数になってしまうので、それを避ける為に予め sumも
 s2も float宣言した。sqrtが平方根を求める関数。文末には必ず;を付ける。
 */
		printf("(n=%d)  sum=%.f  mean=%.2f  sd=%.2f\n\n",i,sum,sum/i,s2);

/* 配列を使わなくても計算は出来るが、後で入力値を知りたい時にはどうしようも無い。
  今度は配列宣言したd[]にdataを読み込んで同じ計算をする。*/

		printf("入力dataの平均値と標準偏差を求める [配列変数を使う。終了=999]\n");
		sum=0;s2=0;	// 初期化
	for (i=0;i<1000;i++) {
		printf("No.%2d:",i+1);
			scanf("%d",&d[i]);
			if (d[i]==999) break;
		sum+=d[i];
		s2+=d[i]*d[i];
	}
		s2=s2-sum*sum/i; s2=s2/(i-1); s2=sqrt(s2);	// 偏差計算
	printf("(n=%d)  sum=%.f  mean=%.2f  sd=%.2f\n\n",i,sum,sum/i,s2);

	printf("\n入力dataの 3番目を表示\nNo.3=%d\n",d[2]);
/* 配列変数は[0]から始まるので、一つ前の添え字にする。*/

	printf("この様に、配列を使えば後でdataを呼び出せる。\n\n");

	printf(" ? 番目の値を表示(data No.入力):");
		scanf("%d",&a); if (a<=i) printf("No.%d=%d\n",a,d[a-1]);
	printf("もう一度やってみる\n ? 番目の値を表示(data No.入力):");
		scanf("%d",&a); if (a<=i) printf("No.%d=%d\n",a,d[a-1]);
/* if文を使ったのは、data数を超える数が添え字に入るとエラーになるから。data数が iで
最後のdataはd[i-1]、d[i]は 999になっている。*/

/* dataの並べ替えをして見る */
		n=i;	// iを使ってloopを回すので、data数を nに納めておく。
	for (i=0;i<n-1;i++) {
		for (j=i+1;j<n;j++) {
			if (d[i]>=d[j]) {a=d[i]; d[i]=d[j]; d[j]=a;}
		}
	}
/* これが良く使われる並べ替えのアルゴリズムである。iを 1から(data数-1)まで回し、i番目
の値とそれ以降の全ての値を比較。後の値が小さければ交換するので、先頭から小さい順に並ぶ
事になる。Basic言語では、この種の交換にswap(交換)命令を使うが、Cにはswap命令が無いので
上の様にしている。値を預ける変数を用意しておいて、順繰りに値をずらして代入していくと、
交換が成立する。i loopの中で j を回すことは良く行われる(nesting, 入籠)。iとjの関係に目
配り。 forも whileも ifも、( )後の一文のみを実行するので、複数の命令を実行させる場合に
は{ }で囲むのを忘れない事。条件文を( )中に書くことも[つい()抜きで書くことが…]。
 */
	printf("\n配列を使わないと出来ない処理の例\ndataを小さい順に並べ替えて表示\n\n");

	for (i=0;i<n;i++) printf("%d, ",d[i]);
	
printf("\nEnd\n");
return 0;
}


(前に戻る)   ・次へ