ページ 11

コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 10:04
by mkt
AOJの問題 http://judge.u-aizu.ac.jp/onlinejudge/d ... d=ITP1_7_A に関してなのですが、下記のコードで

Sample Input                 
40 42 -1                
20 30 -1              
0 2 -1
-1 -1 -1

を試したところ

Sample Output
A
C
F

となるはずが

自分の環境では
ACFu
CFu
Fu

となってしまいました。

コードのどこが間違っているかを教えてください。どうかよろしくお願いします。

コード:

#include <stdio.h>
 
int main(void)
{
    int m,f,r,i=0,j;
    char grade[100];
    do {
        scanf("%d %d %d",&m,&f,&r);
         
        if (m==-1&&f==-1&&r==-1)  break;
          
          else if (m==-1||f==-1||m+f<30) {
            grade[i]='F';
        } else if (r>=50)  {
        	grade[i]='C';
        } else if (m+f<50) {
            grade[i]='D';
        } else if (m+f<65) {
            grade[i]='C';
        } else if (m+f<80) {
            grade[i]='B';
        } else {
            grade[i]='A';
        }
         
        i++;
    } while (1);
     
    for(j=0;j<i;j++) {
        printf("%s\n",&grade[j]);
    }
     
    return 0;
}

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 10:18
by usao
>printf("%s\n",&grade[j]);
ここ
オフトピック
grade[]に一旦結果を格納しなくても,評価がわかった時点でそれを出力すれば良い気がする.

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 10:41
by mkt
usao様、すみません、printf("%s\n",&grade[j]);のどこを間違えているのかが分かりません。

格納しないやり方は分かるのですが、格納するやり方だとどうなるのでしょうか?よろしくお願いします。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 10:44
by みけCAT
mkt さんが書きました:格納しないやり方は分かるのですが、格納するやり方だとどうなるのでしょうか?よろしくお願いします。
テストケースの数がわからないので、線形リストを使うのがいいと思います。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 11:02
by mkt
みけCAT様、回答ありがとうございます。線形リストが分からないので勉強してみます。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 11:13
by usao
>printf("%s\n",&grade[j]);のどこを間違えているのかが分かりません

printf("%s\n",&grade[j]);
が, 【各jの値について, どのような出力をせよ と書いたことになるのか】がわからないということですか?

具体的に言えば,例えばjの値が1のとき,すなわち
printf("%s\n",&grade[1]);
とは,配列grade[]のうち どこからどこまでを出力しろ と言ったことになるのか.

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 11:35
by mkt
usao様、回答ありがとうございます。

>printf("%s\n",&grade[j]);
が, 【各jの値について, どのような出力をせよ と書いたことになるのか】がわからないということですか?

はい、おっしゃる通りです。

>具体的に言えば,例えばjの値が1のとき,すなわち
printf("%s\n",&grade[1]);
とは,配列grade[]のうち どこからどこまでを出力しろ と言ったことになるのか.

自分はgrade[]のうち、要素番号1だけを出力しろ と言ったことになると思っていましたが、テストケースを試した結果を見てみると要素番号1から最後の要素番号i-1まで出力しろ と言ったことになっている ようです。これが何故なのかが分かりません。教えて下さい。よろしくお願いします。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 11:38
by みけCAT
mkt さんが書きました:自分はgrade[]のうち、要素番号1だけを出力しろ と言ったことになると思っていましたが、テストケースを試した結果を見てみると要素番号1から最後の要素番号i-1まで出力しろ と言ったことになっている ようです。これが何故なのかが分かりません。教えて下さい。よろしくお願いします。
解説はusao様に任せるとして、この解釈は間違っています。
その証拠に、格納した様子の無い"u"が出力されていますし、出力された文字の数もあっていません。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 11:57
by mkt
みけCAT様、回答ありがとうございます。もう一度見直すと、みけCAT様のおっしゃる通り、この解釈は間違っていました。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 13:23
by usao
>解説はusao様に任せるとして…

うーん,ここまで材料が出そろっているなら
検索なりして調べた方が早いと思うんですよね…

printf()について(書式指定の仕方とか)調べる
→ %sってのは「文字列」.なので,一文字だけ表示しようとしてるのにこれを使うのは何かが違うということがわかる
 →じゃあ一文字だけ表示したい場合は何と書けばいいのか?
 →書式指定が違ってたのはそれはそれとして,現在の記述だと どこからどこまでの範囲が表示されることになるのか?
  (「どこから」については自分で指定してるんだけど,「どこまで」に対応する指定はしていない)
  すなわち,文字列の終端ってのはどう決まるのか? → 終端文字がどうの
 →ところで,なんで謎の u とかが出力されてたの? → 初期化の話とか,前回のトピックでしてたよね

…みたいに,いろいろと復習になるのでは.

Re: コードの間違いを指摘して下さい

Posted: 2014年8月20日(水) 14:03
by mkt
usao様、回答ありがとうございます。usao様のヒントで分かりそうな気がしてきました。検索なりして調べてみます。

Re: コードの間違いを指摘して下さい

Posted: 2014年8月22日(金) 08:56
by mkt
なんとか理解することができました。ありがとうございました。