回答編集履歴
3
気づいた点を追加
    
        answer	
    CHANGED
    
    | @@ -79,7 +79,7 @@ | |
| 79 79 | 
             
                    ans = calc(num1, num2, op);
         | 
| 80 80 |  | 
| 81 81 | 
             
            ```
         | 
| 82 | 
            -
            演算子直前の空白はどうすべきか、エラーチェックなどまだまだ不完全・・・ですが、流れがシンプルで見通しがよくなったと思います。
         | 
| 82 | 
            +
            演算子直前の空白はどうすべきか、エラーチェックなどまだまだ不完全・・・ですが、流れがシンプルで見通しがよくなったと思います。この線で私なりの完成形を作ることができました。
         | 
| 83 83 |  | 
| 84 84 | 
             
            > その他何か、お気づきの点があれば
         | 
| 85 85 |  | 
| @@ -99,4 +99,6 @@ | |
| 99 99 | 
             
            2. 繰り返すことを見越してループの最後で num1 〜 countnum に0を代入していますが、**初期値の代入はループに入った先頭で行うべき**です。
         | 
| 100 100 | 
             
            さらに、main() の先頭は ``` int num1; ``` と変数定義だけにして、初期化は不要です。不要なことは書かない。一箇所でできることは一箇所で行ったほうがよい。
         | 
| 101 101 |  | 
| 102 | 
            -
            - STRLEG は string length を短縮したのだと思いますが、LEG だと長さではなく「脚」になって良くない(脚にも長さあるがw)。重箱の隅のようだけど、格好悪いし、名前は案外大事だということで。6文字ならSTRLENかな。
         | 
| 102 | 
            +
            - STRLEG は string length を短縮したのだと思いますが、LEG だと長さではなく「脚」になって良くない(脚にも長さあるがw)。重箱の隅のようだけど、格好悪いし、名前は案外大事だということで。6文字ならSTRLENかな。
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            - ```#define STRLEG  16``` ですが、int 型が 32bit なら10進数で10桁まで扱えるので、16文字では少ないと言えます。fgets()で入力するなら \n と \0 の2文字分を含めて、最低でも 10 + 1 + 10 + 2 = 23 文字、さらに空白文字の分もあったほうが良いでしょうね。
         | 
2
説明を一文追加
    
        answer	
    CHANGED
    
    | @@ -14,7 +14,7 @@ | |
| 14 14 |  | 
| 15 15 | 
             
            と、**今見ているものをif文で区別しながら処理する必要があるので、それだけでもインデントは1〜2段深くなる**のです。私には諸悪の根源に思えてきました(笑)。
         | 
| 16 16 |  | 
| 17 | 
            -
            そこで、こんなふうに組み直したらどうか(まずは、空白は無い、エラーチェックも要らないと仮定し、正常な処理の本筋だけを考えてみる)。
         | 
| 17 | 
            +
            要は、入力した文字列から2つの数字と演算子を切り出すことです。そこで、こんなふうに組み直したらどうか(まずは、空白は無い、エラーチェックも要らないと仮定し、正常な処理の本筋だけを考えてみる)。
         | 
| 18 18 |  | 
| 19 19 | 
             
            ```C
         | 
| 20 20 | 
             
                p = str;         // 入力した行の先頭から見ていく
         | 
1
str2num() を conv2num() に。他、少し表現を修正。
    
        answer	
    CHANGED
    
    | @@ -4,9 +4,9 @@ | |
| 4 4 |  | 
| 5 5 | 
             
            > 帳尻合わせのデクリメントを対処する方法
         | 
| 6 6 |  | 
| 7 | 
            -
            p--; が必要になる理由は、``` for (p = str; *p != '\n'; p++)``` というループの中で数字やら演算子やらを切り出しているからです。ですから Chironian さんが | 
| 7 | 
            +
            p--; が必要になる理由は、``` for (p = str; *p != '\n'; p++)``` というループの中で数字やら演算子やらを切り出しているからです。ですから Chironian さんがおっしゃるように、``` for (p = str; *p != '\n'; ) ``` とする手もあるでしょうが、、、
         | 
| 8 8 |  | 
| 9 | 
            -
            もうひとつ、Chironianさん | 
| 9 | 
            +
            もうひとつ、Chironianさんご指摘の、インデントが深いことも考慮する必要があります。インデントが深いほど理解しにくく、メンテナンスしにくくなるのだから。
         | 
| 10 10 | 
             
            インデントが深くなる原因は、関数化していないことに加えて、``` for (p = str; ...)``` という大きなループの中で処理していることです。このforループの中で
         | 
| 11 11 | 
             
            - ひとつめの数字
         | 
| 12 12 | 
             
            - 演算子
         | 
| @@ -42,7 +42,7 @@ | |
| 42 42 | 
             
                return ptr;               // 次の文字位置を返す
         | 
| 43 43 | 
             
            }
         | 
| 44 44 |  | 
| 45 | 
            -
            char * | 
| 45 | 
            +
            char *conv2num(char *ptr, int *num)     // 数字に変換する
         | 
| 46 46 | 
             
            {
         | 
| 47 47 | 
             
                int result = 0;
         | 
| 48 48 |  | 
| @@ -68,9 +68,9 @@ | |
| 68 68 | 
             
                        break;
         | 
| 69 69 |  | 
| 70 70 | 
             
                    p = str;                       // 入力行の先頭から
         | 
| 71 | 
            -
                    p =  | 
| 71 | 
            +
                    p = conv2num(p, &num1);        // 数字ひとつめ
         | 
| 72 72 | 
             
                    op = *p++;                     // 演算子
         | 
| 73 | 
            -
                    p =  | 
| 73 | 
            +
                    p = conv2num(p, &num2);        // 数字ふたつめ
         | 
| 74 74 |  | 
| 75 75 | 
             
                    if (op == '/' && num2 == 0) {  // 0除算しない
         | 
| 76 76 | 
             
                        // 0除算エラー
         | 
| @@ -79,7 +79,7 @@ | |
| 79 79 | 
             
                    ans = calc(num1, num2, op);
         | 
| 80 80 |  | 
| 81 81 | 
             
            ```
         | 
| 82 | 
            -
            エラーチェックなどまだまだ不完全 | 
| 82 | 
            +
            演算子直前の空白はどうすべきか、エラーチェックなどまだまだ不完全・・・ですが、流れがシンプルで見通しがよくなったと思います。
         | 
| 83 83 |  | 
| 84 84 | 
             
            > その他何か、お気づきの点があれば
         | 
| 85 85 |  | 
| @@ -99,4 +99,4 @@ | |
| 99 99 | 
             
            2. 繰り返すことを見越してループの最後で num1 〜 countnum に0を代入していますが、**初期値の代入はループに入った先頭で行うべき**です。
         | 
| 100 100 | 
             
            さらに、main() の先頭は ``` int num1; ``` と変数定義だけにして、初期化は不要です。不要なことは書かない。一箇所でできることは一箇所で行ったほうがよい。
         | 
| 101 101 |  | 
| 102 | 
            -
            - STRLEG は string length を短縮したのだと思いますが、LEG だと長さではなく「脚」 | 
| 102 | 
            +
            - STRLEG は string length を短縮したのだと思いますが、LEG だと長さではなく「脚」になって良くない(脚にも長さあるがw)。重箱の隅のようだけど、格好悪いし、名前は案外大事だということで。6文字ならSTRLENかな。
         | 
