Tags:, Posted in PHP 1 Comment

論理式を評価する演算子、皆さんはどちらを使っていますか?

if ( $a and $b ) echo "it's true!\n";
if ( $a && $b ) echo "it's also true!\n";

先日、両者の違いについてチームで話題になったので、ちょっとまとめ。

Quick Questions

次の問いにサクサク答えられれば、バッチリ理解しているということで無問題かと。
回答は全て、$xが真(true)か偽(false)で。各問いをクリックすると、答えがわかります。

1. $x = (true and false);
2. $x = true and false;
3. $x = false and true;
4. $x = (true && false);
5. $x = true && false;
6. $x = false && true;
7. $x = (false or true);
8. $x = false or true;
9. $x = true or false;
10. $x = (false || true);
11. $x = false || true;
12. $x = true || false;
13. $x = (false and true or true and true);
14. $x = (false and true || true and true);

さて、正解率はどれくらいだったでしょうか?

解説

まず誤解の無いようにしておくと、論理演算子としての意味は and でも && でも変わりません。共に論理積です。
では、何故このような違いが起きるのでしょうか。
そのポイントは、演算子の優先順位にあります。

例えば「2」の問題、パッと期待してしまうのは、「true and false」という論理式の結果である「false」が$xに代入されることだと思います。

$x = true and false;

しかし、PHPにおける論理式の優先順位は “&&” > “=” > “and” の順です。
つまり、この式はまず「$x = true」が評価されて代入され、その結果とfalseの論理積を計算する(結果はどこにも代入されない)ということになってしまいます。

逆に、同じ式に見える「5」の問題では、”&&”の方が”=”よりも実行順位が高いため、論理積の結果が$xに代入されるようになります。

$x = true && false;

こうして考えると、全ての問題に納得がいくでしょうか。

念のため、最後に挙げた「13」「14」について見ておきましょう。

$x = (false and true or true and true);
$x = (false and true || true and true);

“and”と”or”が並んだ場合、優先されるのは”and”です。
そのため、「13」では次のように評価され、結果は”true”となります。

$x = ((false and true) or (true and true));

しかし、”and”と”||”では、優先順位は”||”の方が高くなっています。
そのため、「14」では次のように評価されてしまいます。

$x = ((false) and (true || true) and (true));

結果は、”false”になります。

まとめ

括弧を省略せず、明示的に書く癖をつけることが第一です。

そして、同じチーム内では”and”と記述する人と”&&”と書く人が混在しないように、コーディングルールなどにしっかりと明記すべきでしょう。
さもないと、チーム内で他人のコードを編集した際などに、最後の14問目のような思わぬ不具合を招く可能性があります。

新メンバーを向かえた際などについ、「そんなの、どっちでもいいじゃん」となってしまうこともあります。
単なるコード表記上の美学ではなく動作の安全性にかかわることなので、しっかり統一することをオススメします。

このエントリーをはてなブックマークに追加
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed
Share on StumbleUpon
Newsing it!

Related posts:

  1. [PHP] 配列やオブジェクトの値渡しと参照渡し
  2. [PHP] 高速化Tipsのオカルト(2) echoとprint
  3. [Javascript] nullとundefinedとfalseと0と空文字と

2009 年 5 月 20 日