平均値と平均値以下の人の出力

01	/********************************/
02	/* 平均値の計算と平均値以下の人 */
03	/*      coded by Y.Suganuma     */
04	/********************************/
05	#include <stdio.h>
06	
07	int main()
08	{
09	/*
10	         データの数の読み込み
11	*/
12		int n;
13		printf("人数は? ");
14		scanf("%d", &n);
15	
16		if (n <= 0 || n > 50)
17			printf("人数が不適当です\n");
18	/*
19	         データの読み込み
20	*/
21		else {
22			double mean = 0.0, x[50];
23			int i1;
24			for (i1 = 0; i1 < n; i1++) {
25				printf("%d 番目の人の点は? ", i1+1);
26				scanf("%lf", &(x[i1]));
27				mean += x[i1];
28			}
29	/*
30	         平均値の計算と出力
31	*/
32			mean /= n;
33			printf("   平均値は=%f\n", mean);
34	/*
35	         平均値以下の人を調べ,出力
36	*/
37			for (i1 = 0; i1 < n; i1++) {
38				if (x[i1] <= mean)
39					printf("      %d番 %f点\n", i1+1, x[i1]);
40			}
41		}
42	
43		return 0;
44	}
		
16,17 行目

  このプログラムは,22 行目で宣言しているように,配列変数 x には 50 個のデータしか記憶できません.従って,入力された人数が 50 人より多いとき,エラーメッセージを出し何も行わないようにするため,これらの行があります.同時に,0 以下の値も避けています.もし,プログラム内に
	printf("%f\n", x[51]);
	x[55] = 3.6;			
のような記述をしても,コンパイルやリンク時に何のエラーメッセージも出力されず,実行可能となってしまいます( Java の場合は,実行時にエラーメッセージが出力され,実行停止になる).しかし,このような文を実行すると,出力の場合は予期せぬ値が出力されるだけで済みますが,代入の場合は,配列変数 x に用意された記憶領域の外にデータを書き込むことになり,場合によってはプログラム自身を破壊してしまいます.従って,最初に用意された領域外のデータが参照されることを避けるために 16 行目の if 文が必要になります.なお,下に述べるプログラム例のように,new 演算子を使用すれば n が 50 より大きいことに対するチェックは必要ありません.

26 行目

  (i1 + 1)番目の人の点数が,配列変数 x[i1] に読み込まれます.

37 ~ 40 行目

  平均点以下の人を調べるための for ループです.全員に対しチェックする必要があるので,再度,for 文を使う必要があります.

  以下に示すのは,上と同じプログラムを new 演算子を使用して書いた例です.人数が入力された後,動的に領域を確保していますので,「 n > 50 」の判定は必要ありません.

/********************************/
/* 平均値の計算と平均値以下の人 */
/*      coded by Y.Suganuma     */
/********************************/
#include <stdio.h>

int main()
{
/*
         データの数の読み込み
*/
	int n;
	printf("人数は? ");
	scanf("%d", &n);

	if (n <= 0)
		printf("人数が不適当です\n");
/*
         データの読み込み
*/
	else {
		double mean = 0.0;
		double *x = new double [n];
		for (int i1 = 0; i1 < n; i1++) {
			printf("%d 番目の人の点は? ", i1+1);
			scanf("%lf", &(x[i1]));
			mean += x[i1];
		}
/*
         平均値の計算と出力
*/
		mean /= n;
		printf("   平均値は=%f\n", mean);
/*
         平均値以下の人を調べ,出力
*/
		for (int i1 = 0; i1 < n; i1++) {
			if (x[i1] <= mean)
				printf("      %d番 %f点\n", i1+1, x[i1]);
		}
	}

	return 0;
}
		
  C++ には,範囲 for 文が存在します.範囲 for 文は,配列やコンテナ(複数のデータを保存するための入れ物)を簡潔に扱うための for 文の別表現です.その一般的仕様は以下に示すとおりです.
for (変数宣言 : 範囲) {
    文(複数の文も可)
}		
変数宣言において宣言した変数に,範囲内の要素が先頭から終端まで順番に代入されます.範囲 for 文では,配列の場合,その宣言された大きさだけ繰り返しが実行されてしまいますので,この例にはあまり向きませんが,一応,書き直してみます.
/********************************/
/* 平均値の計算と平均値以下の人 */
/*      coded by Y.Suganuma     */
/********************************/
#include <stdio.h>

int main()
{
/*
         データの読み込み
*/
	double mean = 0.0, x[3];
	int n = 3, i1 = 1;
	for (auto& e : x) {
		printf("%d 番目の人の点は? ", i1);
		scanf("%lf", &e);
		mean += e;
		i1++;
	}
/*
     平均値の計算と出力
*/
	mean /= n;
	printf("   平均値は=%f\n", mean);
/*
     平均値以下の人を調べ,出力
*/
	i1 = 1;
	for (auto e : x) {
		if (e <= mean)
			printf("      %d番 %f点\n", i1, e);
		i1++;
	}

	return 0;
}