猿にはわからない論理演算と条件演算の話

.NETになって、論理演算子とビット演算子の違いって意識されなくなってるのかなと(^^;
if文に使われるのは、論理演算子が主流だと思っていたのですが・・・ビット演算子を使う人もいるのね。
正直なとこ、if文などにビット演算子を使う利点がみえないのですよ。
Delphiをやってた人だと、もともと区別がないようなので、なんで2つに分かれているのかとか思うのかもしれませんがw
私の場合、Delphiを後からみたので、なんで1つで区別できているのか?とか思ったりしたのですがねw
よくよく考えると、区別は明確だったりしたので、C#も同じなのかと思ったのですが・・・
同じだったら2つに分かれているわけもなくw


まぁ、区別しなくても同じような感じで動作はするし・・・
.NETのif文はbool値しか許されていないので、なにが違うのかわからない人もいるのかなと・・・
C#だとーC言語でいうビット演算子が論理AND(&)、論理OR(|)という名称ですねぇ。
でもって、論理演算子が条件AND(&&)、条件OR(||)という名称ですか・・・
わかりやすいような、誤解を生みやすいような(^^;;;;


C#での論理演算と条件演算の違いは以下のようなプログラムではっきりわかります。

namespace ortest
{
    class Program
    {
        static void Main(string[] args)
        {
            if (RetTrue() | RetFalse())
            {
                Console.WriteLine("IFの中・・・");
            }
            else
            {
                Console.WriteLine("なんとか出られたな");
            }
        }
        static bool RetTrue()
        {
            Console.WriteLine("Trueだよ");
            return true;
        }
        static bool RetFalse()
        {
            Console.WriteLine("Falseだよ");
            return false;
        }
    }
}

これは論理演算の例です。
デバッグ実行で、if文の部分をステップして追いかけてみてください。
RetTrue()を実行した後にRetFalse()を実行しているはずです。
次に、「 if (RetTrue() | RetFalse())」を 「if (RetTrue() || RetFalse())」のように条件演算に変えて同じことをしてください。
今度は、RetTrue()を実行した後にif文の中に入ってしまいRetFalse()を実行しなかったはずです。


これが2つの明確な違いです。
論理演算は足し算や引き算のような計算なので、式全てを参照しなくてはいけません。
この場合、RetTrue()の結果とRetFalse()の結果を計算する必要があるので、両方が実行されるわけです。


それに対し、条件演算は演算ではあるのですが、答えが確定した時点で処理を打ち切ります。
この場合、RetTrue()の結果で式全体の値がtrueと確定するのでRetFalse()を実行しなくてもいいわけです。


これを応用するとー

if ((i==0) | (x/i==0))

論理演算だとiが0の場合、条件を満たしているのにもかかわらず、x/iを実行して0割り算が発生してしまう。
そのため別の方法を考えなくてはいけないのですがー地味に面倒ですねw
ところが、

if ((i==0) || (x/i==0))

条件演算ではi==0で式が確定するので、x/iを実行せずに0割り算が発生しないわけです。
先のサンプルプログラムのように、無駄な処理を行ってしまうこともあるわけでー
わりと特殊な条件でもない限り条件演算を使うほうが良い・・・
というかif文で論理演算使うのは、基本的には間違ってることのほうが多いんじゃね?と思うわけですw