みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語の配列を使ったプログラミングについてです。

5人の数学と英語の点数の合計が入る二次元配列を用意し、5人の数学 (scores [i] [0]) と英語 (scores [i] [1]) の点数の入力する.5人の数学と英語の合計点を計算し配列に入れる (scores [i] [2]).数学と英語と合計の一覧を表示したあと,合計点の最高点と最低点を表示するプログラムを作れ.という問題で
#include<stdio.h>

int main()

{
char score[5][3];
int i, min=0,max=0;

for(i=0; i<5; i++){
printf("%d: M E?",i+1);
scanf("%d %d", &score[i][0], &score[i][1]);
score[i][2]= score[i][0]+score[i][1];
if(score[max]<score[i][2])
max=i;
if(score[min]>score[i][2])
min=i;
}
printf("id Math Eng Total\n");
for(i=0; i<5; i++){
printf("%d %d %d %d\n", i+1, score[i][0], score[i][1], score[i][2]);
}
printf("min: %d max: %d",score[min], score[max]);
}

というプログラムを作ったのですが、scanfで改行を入れていないのに、1つ目の数字を入れると2つ目の数字はなぜか改行してしまい、さらに最低点と最高点が正しく出力されませんでした。なぜでしょうか。回答よろしくお願いします。

投稿日時 - 2016-10-12 14:45:46

QNo.9241688

困ってます

質問者が選んだベストアンサー

>ヒントには、
>char scores[5][3];
>scanf("%d %d", &scores[i][0], &scores[i][1]);
>と書かれているのでcharは間違っていないと思います。

ヒント通りに作成すると「scanfを行なった時点で、メモリを破壊する」ので「ヒントそのものが間違っている」のが明白です。

世の中には「出題者そのものがバグに気付いていない」という課題が多く存在します。

出題者がバグに気付かない原因は「メモリを壊していても、この程度の例題なら、問題が表面化しない」からです。

#include<stdio.h>

int main()
{
int score[5][3];
int i, min=0,max=0;

for(i=0; i<5; i++){
printf("%d: M E?",i+1);
scanf("%d %d", &score[i][0],&score[i][1]);
score[i][2]= score[i][0]+score[i][1];
if(score[max][2]<score[i][2])
max=i;
if(score[min][2]>score[i][2])
min=i;
}
printf("id Math Eng Total\n");
for(i=0; i<5; i++){
printf("%d %d %d %d\n", i+1, score[i][0], score[i][1], score[i][2]);
}
printf("min: %d max: %d",score[min][2], score[max][2]);
return 0;
}

因みに「score配列がcharの配列」だった場合、数学と英語の合計点が128点以上になると、charの値が「マイナス」になるので、確実に誤動作します。

つまり「score配列は、128以上の整数を記録出来なければならない」ので「charで定義するのは明白な誤り」です。ヒントが確実に間違っています。

因みに、以下は「charの配列のまま」で実行した結果です。

1: M E?50 50
2: M E?10 50
3: M E?100 100
4: M E?10 0
5: M E?0 10
id Math Eng Total
1 50 50 100
2 10 50 60
3 100 100 -56
4 10 0 10
5 0 10 10
min: -56 max: 100

3人目の合計が「200点」でなければならないのに「-56点」になっています。

この点からも「scoreがcharの配列であるのは明白なバグ」であり、出題者の頭がおかしいとしか思えません。

投稿日時 - 2016-10-12 17:29:33

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.6

#5補足です。

max,minには最高点や最低点の人が「何番目の人か」の番号(0~4)が入ります。点数そのものが入るわけではありませんのでご留意ください。
最後のprintfの中もscore[max][2]などとなります。

scanfの件は他の回答者様のおっしゃる通りです。%dを使うのであればint型の変数を使用します。int score[5][3]と宣言してください。charではダメだと思います(ヒントが間違っている?)。

投稿日時 - 2016-10-12 17:19:17

ANo.5

>if(score[max]<score[i][2])
>max=i;
>if(score[min]>score[i][2])
>min=i;

二次元配列score[][]の中身は
score[i][0] :i番目の人の数学の点数(i = 0~4)
score[i][1] :i番目の人の英語の点数
score[i][2] :i番目の人の合計点
となっています。
また、scoreは2次元配列なので添え字は2個必要です。
ですからscore[max]のような添え字が1個だけ、というのは明らかに変です。
合計点の最大/最小を調べているので、if文で比較するのは、score[max][2]、score[min][2]とするのが正しいと思います。

投稿日時 - 2016-10-12 16:56:59

ANo.4

たぶんヒントが間違ってます。なぜなら、
>合計点の最高点と最低点を表示する
という仕様のプログラムを書いていて、

>if(score[max]<score[i][2])
>max=i;
>if(score[min]>score[i][2])
>min=i;

こう書いたとき、変数iは「何人目であるか」という0~4の範囲の情報を
持っています。それに対し、
maxやminは「点数の」最高点や最低点を入れることになっています。
iとman/minは、保持する情報の属性が全く異なります。
代入するとおかしなことになります。

繰り返します。
iは「何人目」か、という情報、
man / minは「何点か」という情報をそれぞれ保持します。

投稿日時 - 2016-10-12 16:06:33

ANo.3

> char score[5][3];
snip
> scanf("%d %d", &score[i][0], &score[i][1]);
snip
> と書かれているのでcharは間違っていないと思います。

そのヒントとやらがおかしい。%d は int の領域が必要です。どうしても char で受けるなら %hhd とするべきでしょう。

コンパイラにもよるでしょうが、複数の警告が表示されているはずです。もし警告の抑制オプション付けてるなら外し、まずはその警告の原因を考えて、問題を修正する必要があります。

投稿日時 - 2016-10-12 15:41:56

ANo.2

scanfのことはいったん横へ置くとして…
>if(score[max]<score[i][2])
>max=i;
>if(score[min]>score[i][2])
>min=i;

別の回答者さんからの回答にもあるとおり、score[max]というのは意味不明です。
また、maxやminにiを代入していますが、正しいですか?
maxやminには「score」が入るのではないのですか?iという添字じゃなくって。

投稿日時 - 2016-10-12 15:17:21

補足

ヒントに
char scores[5][3];
int i,min=0,max=0;

for(i=0; i<5; i++) {
scanf("%d %d", &scores[i][0], &scores[i][1]);
// scores[i][2]の計算をする
// scores[i][2]の最低点か? 最低点ならmin=iをする
// scores[i][2]の最高点か? 最高点ならmax=iをする
}

for(i=0; i<5; i++) {
// 表示
}
と書かれているのでmin=iやmax=iは間違えていないと思います。score[max]は過去の問題を参考にしたものなので私自身よくわかっていません。すみません。

投稿日時 - 2016-10-12 15:38:15

ANo.1

char score[5][3];
となっているが,どうしてcharなのですか?点数を入れるのではないですか?
if(score[max]<score[i][2])
となっているが,どうしてscore[max]とscore[i][2]を比較するのですか?このときscore[max]には何が入っていると考えているのですか?

投稿日時 - 2016-10-12 15:00:03

補足

ヒントには、
char scores[5][3];
int i,min=0,max=0;

for(i=0; i<5; i++) {
scanf("%d %d", &scores[i][0], &scores[i][1]);
// scores[i][2]の計算をする
// scores[i][2]の最低点か? 最低点ならmin=iをする
// scores[i][2]の最高点か? 最高点ならmax=iをする
}

for(i=0; i<5; i++) {
// 表示
}
と書かれているのでcharは間違っていないと思います。score[max]は過去の問題を参考に入れたものであり私自身よく分かっていません。すみません。

投稿日時 - 2016-10-12 15:32:47

あなたにオススメの質問