プロが教えるわが家の防犯対策術!

指定された個数(100個以下)だけ整数を読み込んで,読み込んだ整数の一覧,それらのうちの最大値と二番目に大きい値とを表示するプログラムを作成。最大となる値が複数入力された場合も正しく処理する。
このプログラムで入力した数字が全部同じ時、二番目に大きい値はありません。と表示したいのですが、どのようにしたらいいのかわかりません。教えてください。あとこのプログラムで最大値と二番目に大きい値出せたのですが、念のため問題ないか確認お願いします。
#include <stdio.h>

#define NUMBER 100 /*整数の個数の上限*/

int main(void)
{
int i;
int num;
int kazu[NUMBER];
int max;
int sec;

printf("整数は何個ですか:");
scanf("%d", &num);
puts("整数を入力してください。");
for(i = 0; i<num; i++){
printf("%3d個目:",i+1);
scanf("%d", &kazu[i]);
}


printf("入力された整数は%d個で、\n",num);

for(i=0;i<num;i++)
printf("%d ",kazu[i]);
printf("です。\n");

sec = max = kazu[0];
for(i=1; i<num; i++){
if(kazu[i]>max) max=kazu[i];
}
for(i=0;i<num;i++){
if(kazu[i]>max){
sec=max;
max=kazu[i];
}else if((max>kazu[i]) && (kazu[i]>sec))
sec=kazu[i];


}


printf("最大値は%dです。 \n",max);
printf("二番目に大きい値は%dです。\n", sec);

return(0);
}

A 回答 (6件)

>二番目に大きい値はありません。

と表示したい

printf("二番目に大きい値は%dです。\n", sec);

printf("二番目に大きい値は");
printf(max!=sec?"%dです。\n":"ありません。\n", sec);
に変える。

sec = max = kazu[0];
for(i=1; i<num; i++){
if(kazu[i]>max) max=kazu[i];
}
for(i=0;i<num;i++){
if(kazu[i]>max){
sec=max;
max=kazu[i];
}else if((max>kazu[i]) && (kazu[i]>sec))
sec=kazu[i];
}
の部分は
sec = max = kazu[0];
for(i=1; i<num; i++){
if(kazu[i]>=max) max=kazu[i];
else if(kazu[i]>sec) sec=kazu[i];
}
で構わない。

あと「整数の個数」に0以下(0かマイナス)が入力された場合、未初期化のkazu[]配列を参照してしまう。

また「整数の個数」に101以上が入力された場合、kazu[]配列に数値を格納しようとしてメモリを破壊してしまう。

なので、numにマイナス、0、101以上が入力されたら、return 0;して中断する必要がある。

A.No1さんへ。

>先に配列変数を大小で全部並び変えてから、最大値 二番目 同じ値か判別したほうが簡単だと思います。

入力された数値が、

1 2 2 1 2 1 3 3 3

だった場合、ソートしても

3 3 3 2 2 2 1 1 1

となるので、最大値の「3」、二番目に大きい「2」を見付けるのは簡単ではない。

単純にソート後のkazu[0]とkazu[1]を表示しても、「3」と「3」が表示されてしまう。

A.No.2さんへ。

>・ソートしてしまう

A.No1と同じ問題が起きる。

>・そもそも「同じ値が複数存在する」のが問題なんだからそうならないようにしてしまう

題意に沿わない。「同じ数が複数存在してはいけない」と言う条件は無い。

>・最後にチェック

最終的にsecとmaxが同値であれば「二番目は無い」事になるので、それが正解であろう。

>ところで, このプログラムにおいて「最後の for における最初の if」は何のためにあるんでしょうか?

ですよね。何の為にあるのか判りませんね。
    • good
    • 0
この回答へのお礼

わかりやすい説明ありがとうございます。
助かりました。

お礼日時:2012/05/30 17:49

A.No4の訂正。



○INT_MIN
×INT_NIN
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2012/05/30 17:51

追記。



A.No4のバグ修正を施した場合は
printf(max!=sec?"%dです。\n":"ありません。\n", sec);

printf(INT_NIN!=sec?"%dです。\n":"ありません。\n", sec);
に直すのも忘れないように。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2012/05/30 17:51

あ、バグ発見。



sec = max = kazu[0];
ってやってるから、一番最初に「最大値」を入力しちゃうと、それ以降、maxとsecが同値のまま、secが変化しない。

1行目に
#include <limits.h>
を追加して、
sec = max = kazu[0];

max = kazu[0];
sec = INT_MIN;
に変更すると、バグが直る。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2012/05/30 17:51

いろいろやり方はある. たとえば


・ソートしてしまう
・そもそも「同じ値が複数存在する」のが問題なんだからそうならないようにしてしまう
・最後にチェック
くらいはできそう.

ところで, このプログラムにおいて「最後の for における最初の if」は何のためにあるんでしょうか?
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2012/05/30 17:51

先に配列変数を大小で全部並び変えてから、最大値 二番目 同じ値か判別したほうが簡単だと思います。

    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2012/05/30 17:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!