C言語 if文の「=」忘れは致命的になる

  • このエントリーをはてなブックマークに追加
Pocket

C言語に限らず、プログラミングをしていくうえで、条件文はかかせないでしょう。

特に、C言語における条件文ifで、はまると大変な状況になるので、注意しましょう。

では、どう大変なのか見ていきます。


C言語のif文で等しい判定は「=」ではなく「==」である

C言語において、if文で何かと等しいとき、if文内の処理を実行するというのは、普通にあるでしょう。

例えば、このようなプログラムがあったとします。

    short a, b, c;

    a = 1;
    b = 2;

    if (a == b) {
        c = 1;
    } else {
        c = 0;
    }

「aとbが同じだったら、cに1を代入し、違っていたら、cに0を代入する」というだけです。
このプログラムではaとbにすでに値が決まって設定されているため、このif文は必ずelse側を実行し、cに0が代入されることになります。

しかし、これをこう書いてしまったら、どうなると思いますか?

    short a, b, c;

    a = 1;
    b = 2;

    if (a = b) {
        c = 1;
    } else {
        c = 0;
    }

if文の条件のところの「=」を一つ削除しました。

これでも、文法に間違いがないため、コンパイルエラーになりません。
しかし、実行結果はcに1が代入されてしまいます。

なぜなら、「a = b」は「aにbの値を代入する」ということなので、aは2になり、if文の評価は 0以外で真となるため、「c = 1;」が必ず実行されてしまうのです。

たった「=」を一つ忘れただけで、全く違った結果になるのです。
プログラムの世界は恐ろしいですね。

C言語のif文で等しい判定しなくて済む書き方にする

先ほどの例文では「aとbが等しい」ということを判定して、次の処理を行うようにプログラムを書いていました。

しかし、「=」を1つ忘れると意図した結果が得られないこともお話ししました。

このようなことを減らしていくには、どうしたらいいかを考えていきます。

先ほどの例文を思い出してください。

    short a, b, c;

    a = 1;
    b = 2;

    if (a == b) {
        c = 1;
    } else {
        c = 0;
    }

「aとbが等しい」ことを判定しています。この文にはelse文もついていますね。

したがって、「aとbが異なっていたら、cに0を代入し、同じだったら、cに1を代入する」とすることも可能です。
これを書き換えると、以下のようになります。

    short a, b, c;

    a = 1;
    b = 2;

    if (a != b) {
        c = 0;
    } else {
        c = 1;
    }

どうでしょうか?

先ほどのように「=」を2つ並べて書く記述がありませんね。読みにくいかもしれませんが、否定側からプログラミングしているので、意識の中に「=」が一つ欠如したらまずいということがなくなります。

この文で「=」を忘れたら、コンパイルエラーになりますから、気づくことができます。

C言語のif文で等しい判定で「=」1つしかない状態は気付けない

if文の等しい判定で「==」を「=」にしてしまっている状態は、なかなか気付くことができません。

通常、等しいときの処理を実行するのであれば、なおさらです。

しかし、これは致命的になってしまうこともあります。

通常時はそれでいいのですが、異常状態のときに、異常時の処理が実行されないのは、場合によっては危険な状態になります。

さらに、比較される側の変数を他の箇所でも参照しているのなら、常に同じ値になってしまっている状態なので、他の箇所でも必ず同じ結果になってしまいます。

では、どうやって見つけるのかということですが、異常状態を作って、そのif文がきちんと動作することを確認するしかありません。

要は、条件文を満たすときと満たさないときの両方をテストするということですね。

テスト方法を考えているときに、プログラムを眺めていて気づくこともあるでしょうが、正しいと思い込んでいるので、気づかないことのほうが多いです。

両方のケースのテストを実施し、自分が作ったプログラムが思っていた通りに実行されれば、テストはOKです。しかし、「=」が一つの場合は、テスト結果はNGとなるはずです。

そこで、なぜなのかを、プログラムをじっくり見ていくことで、ようやく気付くことができるのです。

もう一つの方法は、他の人にも作成したプログラムを見てもらうことです。 この方法だと、別の目で見てもらえるので、間違いややり方を指摘してもらうことができます。

他の人が気づいてくれたなら、テストする前にプログラムを修正することが可能です。 もちろん、修正した後のプログラムで確認テストをすることは当然のことです。

ここをおろそかにして、「まぁいいか」で過ごすと、肝心なところで失敗することになります。 だいたいがテストしていなかった箇所が、不具合発生になってしまうことが多いのです。

初心者の方は、面倒くさくても、必ずすべてのケースについてテストするということを心がけてください。

テストはうまくいくことを見るのではなく、間違いを見つけるためのものだということを覚えておいてください。

C言語のif文で等しい判定で「=」忘れを防ぐには?

結論からいうと、必ず忘れないようにできるということはありません。

リスクを減らすためには否定文で作成する、他の人にもチェックしてもらう、漏れのない動作テストをするということしかありません。

漏れのない動作テストを実施すれば、ほぼ確実に「=」忘れは修正できるでしょう。

それは、「=」を忘れていれば、思うような動作にならないからです。

気を付けてほしいのは、ただ動作テストをするだけでなく、漏れのない動作テストをすることです。

先ほども述べたように、異常発生していない動作、または、異常発生したときの動作だけを確認しただけでは逆側の条件のときに、うまく動作しないことがわからないのです。

したがって、あなたが今後、プログラミングをしていくうえで、文法エラーがないのはもちろんのこと、実行エラーが発生していないかの確認を日ごろから心がけてほしいと思います。

そうすることで、プログラミングレベルも向上しますし、テストケースを考えるスキルも身に付きます。

繰り返しになりますが、動作確認は、うまくいくことを見るのではなく、間違いを見つけるものです。

これはif文だけでなく、すべての文について言えることなので、絶対に忘れないでください。

よければ、こちらの記事もお読みください。

C言語 while文の「=」忘れはif文の「=」忘れより致命的になる


  • このエントリーをはてなブックマークに追加

コメントを残す

*