/* 偏差計算、配列、並べ替え 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; }