ページ 11

最大値を求めるのに・・・

Posted: 2011年3月21日(月) 22:31
by 欲怨
C言語の勉強をはじめて少したったので、
何も見ずに、10回入力された数字の最大値を出すプログラムを作ってみました。
しかし何故か正確な値が出たり、出なかったりとおかしいです。
どこに問題があるのでしょうか?
さらに僕が使っていたサイトに書いてあったコードも
僕のかいたものと同じように、使えたり使えなかったりします。
これは2010のバグでしょうか?コードの間違いでしょうか?

コード:

#include <stdio.h>

int main(void)
{
	int in[10], n = 0, ns, a;
	
	printf("10回数字を入力してください。最大値が出てきます。\n");
	
	while(n < 10)
	{
		printf("%02d回目:",n+1);
		scanf("%d",&in[n]);
		n++;
	}

	ns = 0;
	a = in[0];
	
	while(ns < 11)
	{
		if(in[ns+1] >= in[ns])
		{
			a = in[ns+1];
		}
		ns++;
	}
	
	printf("最大値は%dです。\n",a);
	return 0;
}

Re: 最大値を求めるのに・・・

Posted: 2011年3月21日(月) 22:57
by Ciel
一瞬しか見てませんが、毎回最大値と比較させてみてはどうでしょう。

Re: 最大値を求めるのに・・・

Posted: 2011年3月21日(月) 22:59
by しひ
添字の範囲に問題があります。
配列in[10]と宣言すると、実際に使えるのはin[0]からin[9]になります。
しかし、2回目のwhile文でin[10]という存在しない変数にアクセスしてしまっているのでおかしなことになります。
変数nsの取りうる値の範囲をよく考えてみてください。

それと、示されている例であればwhile文よりもfor文の方が適任かと思います。

Re: 最大値を求めるのに・・・

Posted: 2011年3月21日(月) 23:18
by GRAM

コード:

while(ns < 11)
    {
        if(in[ns+1] >= in[ns])
        {
            a = in[ns+1];
        }
        ns++;
    }
ここですね。ロジックを確認してみてください
ns < 11でしょうか?

ns = 0; if(in[1] >= in[0])
ns = 1; if(in[2] >= in[1])
ns = 3; if(in[3] >= in[2])
・・・
ns = 9; if(in[10] >= in[9])
ns = 10; if(in[11] >= in[10])

ns<10でないというところまではいいですが考え方が増やすのと減らすので真逆になってますね

Re: 最大値を求めるのに・・・

Posted: 2011年3月21日(月) 23:22
by 欲怨
あ~、配列の数についてよく考えてませんでした。
でもそれをそろえても何故か同じ結果になってしまうのですが・・・
後、while文よりfor文のほうがよいのはなぜなのでしょうか?

Re: 最大値を求めるのに・・・

Posted: 2011年3月21日(月) 23:44
by Dixq (管理人)
whileでもforでもやれることは同じですが、for文の方が上限が明確な時に使われる傾向にあります。
例えば

コード:

for( i=0; i<10; i++ ){
    //処理
}
というループ文があれば、上限がいくらかパッと見て明確に解りやすいでしょう。

Re: 最大値を求めるのに・・・

Posted: 2011年3月22日(火) 00:10
by maru
Cielさん以外の方は配列の添字に注目していますが、問題はそれだけではありませんね。
添字を修正しても

コード:

    while(ns < 9)
    {
        if(in[ns+1] >= in[ns])
        {
            a = in[ns+1];
        }
        ns++;
    }
これでは前後のデータを比較しているだけですよね。
それまでの最大値(a)と比べなければダメでしょう。

コード:

    a = 0;
    for (int i = 0; i < 10; ++i)
    {
        if (in[i] >= a)
        {
            a = in[i];
        }
    }

Re: 最大値を求めるのに・・・

Posted: 2011年3月22日(火) 22:27
by box
maru さんが書きました: それまでの最大値(a)と比べなければダメでしょう。
それはそうなんですけど、
maru さんが書きました:

コード:

    a = 0;
最大値の初期値が0で決めうちっていうのは、ちょっとまずいかもしれません。

私だったら、
a = in[0];
として、1~9のループを構成しますね。

Re: 最大値を求めるのに・・・

Posted: 2011年3月22日(火) 23:42
by maru
box さんが書きました:最大値の初期値が0で決めうちっていうのは、ちょっとまずいかもしれません。

私だったら、
a = in[0];
として、1~9のループを構成しますね。
ですね!
つい、データは0以上という仮定を置いてしまいました。
ループ範囲を0~9にするなら初期値は INT_MIN にすべきでした。

ループを1~9からにしていないのは配列範囲の一部を特別処理にするのが嫌だったからですが、
この程度の処理なら問題はないでしょうね。

Re: 最大値を求めるのに・・・

Posted: 2011年3月24日(木) 18:52
by GaZAsA
in[10]と宣言したとき、in[10]を使ってはいけません。
in[10]と宣言したとき確保される領域はin[0]からin[9]までなのでin[10]には別のものが入っています。
in[10]がもし、osの大事なことを管理する場所だった場合、osが壊れる可能性があります。
このままだと危険なので修正しておきました。
このパターンはありがちだけど危険なのでこれからは絶対にこのようなことをしないでください。

コード:


#include <stdio.h>
 
int main(void)
{
    int in[10], n, a;
    
    printf("10回数字を入力してください。最大値が出てきます。\n");
    
    for(n=0;n < 10; n++) {          //決まった回数ループする場合はforがいい
        printf("%02d回目:",n+1);
        scanf("%d",&in[n]);
    }
    a=in[0];
    for(n=0; n < 10; n++) {        //nの再利用(メモリ使用量削減のため)  ここも決まった回数ループするのでfor
        if(a <= in[n]) {              //最大値と比較
            a = in[n];
        }
    }
    printf("最大値は%dです。\n",a);
    return 0;
}
危険のないように修正しておいたので、かなり安全になっています。ちゃんと動きます。

Re: 最大値を求めるのに・・・

Posted: 2011年3月24日(木) 22:02
by 欲怨
たくさんの回答ありがとうございます。
皆様のおかげで問題は解決しましたが、
あまり話についていけませんでした・・・

これからしっかり勉強して、
こんな問題をすぐに解決できるようになりたいです!