涼の成長記録

自らの人生に主導権を持つべく、独立を目指して2014年3月31日を持ってITエンジニアを退職。そんな23歳♂の成長記録。

論理演算子の短絡評価

読み飛ばしても良い話

ミニッツメイド の健康果実100%のピンクグレープフルーツ・ブレンドがブームです。でも僕はワルだから飲んでます。勿論午後の紅茶も午前に飲みます。そして、私、はてなブログで見出しを使う高等テクニックを習得しました。
http://banguard.hatenablog.com/entry/2012/01/11/010213


思い立ってみれば、私は素人であったことを思い出した話

さて、プログラミングの記事をようやく書きます。何を書こうか考えたのですが、ブログに偉そうに載せられるようなスキルは、当方持ち合わせておりませんでした。人の役に立つかは別として、毎日何か書き続けることに意義があるのだと、自分に言い聞かせながら、さて、書きます。論理演算子の短絡評価のお話。


本題

C, C++ C#, Java, JavaSctipt, Perl, Pythonと、様々なプログラミング言語に言えることですが、論理演算には短絡評価という仕様があり、左辺のオペランドを評価した時点で結果が得られた場合は、右辺のオペランドは評価されない、という特徴があります。わりと知らない方が多いのですよ。


具体的にどういうことかというと、例えば(false and true)であると、左オペランドがfalseなので、解析した時点で、右オペランドがtrueであろうとfalseであろうと、論理演算の結果はfalseになりますよね。論理演算子くんが、「もう答え分かっちゃった☆」と投げちゃうわけです。


論理和の場合でも同様です。左オペランドが真であれば、右オペランドが真であろうと偽であろうと、結果は真です。論理演算子くんが、「もう答え分かっちゃった☆」と投げちゃうわけです。


私たちだって、

2 × 4 × 0 × 9 × 4 × 6 × 8

なんていう計算をする時、3つ目が0なので、どれだけ掛け算しても答えは0になると気付けば、「0 × 9 が 0でー、0 × 4 が 4でー・・・」と最後まで計算したりはしませんよね。論理演算子くんもそんな感じです。


さて、この結果について、通常は意識することは無いのですが、副次効果を持つ条件文なんかでは、注意の必要が出てきます。例えば、以下のCプログラムの出力結果を予想してみましょう。

#include <stdio.h>
int main(void) {
    int x = 0, y = 0;

    if (y && x++) {
        // 処理
    }

    printf("x = %d\n", x);

    return 0;
}

短絡評価を知らない方が見ると、if文の中でxがインクリメントされておりますので、出力結果は"x = 1"だと思ってしまうかもしれません。しかし、そのif文では左オペランドのyが宣言時に0で初期化されているため、論理積演算子の結果は右オペランドに関わらず、falseです。よってifブロック内の処理は実行されませんね。


ここで重要なのは、右オペランドが評価されないということは、xに対するインクリメント演算子は適用されないということです。つまり、出力は"x = 0"になります。副次効果のある条件判定文には注意ということですね。


このことに関わらず、私は副次効果のあるステートメントが、あまり好きではありませんけどね。
ではでは。