ページ 11

論理エラー

Posted: 2011年6月04日(土) 19:01
by アレス
コンパイルは出来るのですが論理エラーを起こしているようなのですがどこがおかしいのか教えてください。
ちなみに9999を読み込むまで次々に整数を読み込んでいき(最大1000個)、合計値および平均値を表示するプログラムです。

コード:

 
#include <stdio.h>
#define MAX 1000

int main(void)
{
	int i=0,	;
	int	sum = 0;
	int	any[MAX]={0};

	puts("整数を入力してください。");

	while(i < MAX){
		printf("No.%d:", i + 1);
			scanf("%d",	&any[i]);
		if(any[i] == 9999){
			i++;
			break;
		}
		sum += any[i++];
	}
	
	if(i>1)
		printf("合計は%dで平均は%.2fです。\n", sum, (double)sum / (i - 1));


	return (0);
}

Re: 論理エラー

Posted: 2011年6月04日(土) 19:25
by みけCAT
Ideoneでコンパイルしたらコンパイルエラーでした。
prog.cpp: In function ‘int main()’:
prog.cpp:6: error: expected unqualified-id before ‘;’ token
prog.cpp:14: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result
http://ideone.com/w4U2o

少し編集したらコンパイルできました。
さて、どこが論理エラーなのでしょうか?
http://ideone.com/hJOvT
私には正しく動作しているように見えます。
テストに使用した入力とそれに対する出力、そして意図する出力を提示してください。

Re: 論理エラー

Posted: 2011年6月04日(土) 20:48
by box
アレス さんが書きました: コンパイルは出来る

コード:

	int i=0,	;
引用した部分のコード内容なのにコンパイルできる、というのは矛盾しています。
コンパイルができているコードを載せてください。

Re: 論理エラー

Posted: 2011年6月04日(土) 21:13
by アレス
>みけCAT さん
学校の課題なんですけど、自分も問題ないと思い先生に提出したら論理エラーがあるから直してこいと言われて何が論理エラーなのかわからない状況です。
>boxさん
すみません。これがコンパイルしたコードです。

コード:

#include <stdio.h>
#define MAX 1000

int main(void)
{
	int i=0;
	int	sum = 0;
	int	any[MAX]={0};

	puts("整数を入力してください。");

	while(i < MAX){
		printf("No.%d:", i + 1);
			scanf("%d",	&any[i]);
		if(any[i] == 9999){
			i++;
			break;
		}
		sum += any[i++];
	}
	
	if(i > 1)
		printf("合計は%dで平均は%.2fです。\n", sum, (double) sum / (i - 1));

	return (0);
}

Re: 論理エラー

Posted: 2011年6月04日(土) 21:23
by bitter_fox
アレス さんが書きました: 学校の課題なんですけど、自分も問題ないと思い先生に提出したら論理エラーがあるから直してこいと言われて何が論理エラーなのかわからない状況です。

コード:

    while(i < MAX){
		if(any[i] == 9999){
			i++;
			break;
		}
		sum += any[i++];
	}
	
	if(i > 1)
		printf("合計は%dで平均は%.2fです。\n", sum, (double) sum / (i - 1));
sum / (i - 1)のあたりが臭そうですね。

MAX回代入した場合はどうなりますか?

Re: 論理エラー

Posted: 2011年6月04日(土) 21:33
by みけCAT
ちなみにMAX縛りが必須ならともかく、このコードならわざわざ配列に入れる必要は無いと思います。

コード:

#include <stdio.h>
 
int main(void)
{
    int i=0;
    int sum = 0;
    int any;
 
    puts("整数を入力してください。");
 
    while(1){
        printf("No.%d:", i + 1);
        scanf("%d", &any);
        i++;
        if(any == 9999)break;
        sum += any;
    }
    
    if(i > 1)
        printf("合計は%dで平均は%.2fです。\n", sum, (double) sum / (i - 1));
 
    return (0);
}
http://ideone.com/8jiFA

Re: 論理エラー

Posted: 2011年6月04日(土) 21:42
by box
アレス さんが書きました:論理エラーを起こしているようなのですがどこがおかしいのか教えてください。
MAX をうんと小さい値にして、MAX個の整数を入力するシチュエーションで試してみてください。
1000個も入力するのは大変ですからね。

Re: 論理エラー

Posted: 2011年6月04日(土) 22:13
by アレス
>bitter_foxさん みけCATさん boxさん
#define MAX 10 にして1~10を代入してみたら「合計は55で平均は6.11です。」と表示されたので多分sum / (i - 1)の(i - 1)がおかしかったみたいです。いろいろありがとうございました。

Re: 論理エラー

Posted: 2011年6月04日(土) 22:17
by box
アレス さんが書きました:多分sum / (i - 1)の(i - 1)がおかしかったみたいです。
本当にそれでよいですか?
MAX個を入力せずに途中で9999を入力したときは?

Re: 論理エラー

Posted: 2011年6月04日(土) 23:29
by アレス
No.1~3にそれぞれ6,3,9を代入し、No.4で9999を入れたら「合計は18で平均は6.00です。」となったのでi=MAXとなった場合だけ論理エラーが起きるようです。なのでこんなかんじにしてみました。

コード:

#include <stdio.h>
#define MAX 10

int main(void)
{
	int i=0;
	int	sum = 0;
	int	any[MAX]={0};

	puts("整数を入力してください。");

	
	while(i < MAX){
		printf("No.%d:", i + 1);
			scanf("%d",	&any[i]);
		if(any[i] == 9999){
			i++;
			break;
		}
		sum += any[i++];
	}
	if(i = MAX)
		i++;
	if(i > 1)
		printf("合計は%dで平均は%.2fです。\n", sum, (double) sum / (i - 1));

	return (0);
}

Re: 論理エラー

Posted: 2011年6月04日(土) 23:31
by h2so5
アレス さんが書きました:

コード:

	if(i = MAX)
		i++;
この条件式は間違っていますよ。常に真になってしまいます。

Re: 論理エラー

Posted: 2011年6月05日(日) 05:55
by dic
答えを書くのは考える力が養われないので

ある場合のとき、ある現象が起きます
おそらく、このある場合のとき を論理エラー
もしくは、意図していないコード と読んで指摘しているのではないでしょうか

と書いている途中で もうひとつみつけました

私が気づいたのは2点あります


想定外といったほうがいいでしょうか
http://www.sophia-it.com/content/%E8%AB ... 9%E3%83%BC
論理エラー
読み方:ろんりエラー
【英】logic error

論理エラーとは、プログラムの実行結果が意図した通りにならないエラーのことである。

論理エラーは、コンパイルが正常に行われ、プログラムの実行途中で異常終了することなく動作するものの、アルゴリズムが論理的に正しくない場合のことを意味する。プログラムの文法や構文などが正しいため、コンパイルラによって発見されることはない。そのため、自力でデバッグを行う必要がある。

論理エラーは、仕様をよく理解した上でプログラムの設計を行えば、ある程度防ぐことができるとされている。また、紛れ込んだ論理エラーの発見効率を高めるには、アルゴリズムの正しさを検証するだけでなく、読みやすいソースコードを記述することも必要であるとされている。

Re: 論理エラー

Posted: 2011年6月05日(日) 13:11
by アレス
>h2so5 さん
これなら大丈夫ですか?

コード:

#include <stdio.h>
#define MAX 10

int main(void)
{
	int i=0;
	int	sum = 0;
	int	any[MAX]={0};

	puts("整数を入力してください。");

	
	while(i < MAX){
		printf("No.%d:", i + 1);
			scanf("%d",	&any[i]);
		if(any[i] == 9999){
			i++;
			break;
		}
		sum += any[i++];
	}
	if(i == MAX)
		i++;
	if(i > 1)
		printf("合計は%dで平均は%.2fです。\n", sum, (double) sum / (i - 1));

	return (0);
}
>dicさん
最後i == MAX以外にも論理エラーが発生するということですか?

Re: 論理エラー

Posted: 2011年6月05日(日) 14:16
by dic
>>アレスさん
はい
結構いじわるに受け取られるようなものがあります

Re: 論理エラー

Posted: 2011年6月05日(日) 15:16
by アレス
>dicさん
いじわるってことは9999が使えないとかですか?

Re: 論理エラー

Posted: 2011年6月05日(日) 15:45
by フリオ
 
 一度、9999で入力を打ち切った場合と、MAXまで入力した場合で、
入力したデータが配列にどのように格納されているか、紙にでも書いて
確認してみては如何でしょうか。

そうすれば、もっと素直な処理ができると思います。
 

Re: 論理エラー

Posted: 2011年6月05日(日) 17:05
by dic
>>アレスさん
送付画像のようにある条件を満たすとバグります

Re: 論理エラー

Posted: 2011年6月05日(日) 19:52
by アレス
>dicさん
自分でいろいろ試してみたんですが9999999999999999999999999999999999999999999999999999999999999999などの数字を入力したときおかしくなったのですがこれですか?

Re: 論理エラー

Posted: 2011年6月06日(月) 10:25
by dic
>>アレスさん
ほとんど正解です