web-dev-qa-db-ja.com

論理ステートメントでは、必要がない場合でも括弧を使用する必要がありますか?

ブール条件があるとしましょうa AND b OR c AND dと私はANDORよりも操作の優先順位が高い言語を使用しています。私はこのコード行を書くことができました:

If (a AND b) OR (c AND d) Then ...

しかし、実際には、これは次と同等です。

If a AND b OR c AND d Then ...

余分な括弧を含めることについて賛成または反対の議論はありますか?実際の経験では、読みやすくするためにそれらを含める価値があると示唆していますか?それとも、開発者が実際に座って言語の基本に自信を持つ必要があるという兆候ですか?

104
Jeff B

優れた開発者は、clearおよびcorrectであるコードを書くように努めます。条件文の括弧は、厳密に必須ではない場合でも、両方に役立ちます。

clarityについては、コード内のコメントのようにかっこを考えてください。これらは厳密には必要ではありません。理論的には、有能な開発者はそれらなしでコードを理解できるはずです。それでも、これらの手がかりは非常に役に立ちます。

  • コードを理解するために必要な作業が軽減されます。
  • 彼らは開発者の意図の確認を提供します。

さらに、インデント、空白、その他のスタイル標準と同様に、余分な括弧は、コードを論理的に視覚的に整理するのに役立ちます。

正確さについては、括弧のない条件は愚かな間違いのレシピです。それらが発生した場合、それらは見つけるのが難しいバグである可能性があります-多くの場合、誤った条件は正しく動作し、たまに失敗するだけだからです。

そして、それを正しく理解したとしても、コードに取り組む次の人は、式にエラーを追加したり、ロジックを誤解したりして、他の場所にエラーを追加するかもしれません(LarsHが正しく指摘しているように)。

andorを組み合わせた式(および同様の優先順位の問題のある算術演算)には、常に括弧を使用します。

121
user82096

あなたが言語の理解に自信があるかどうかは問題ではありません。さらに重要なのは、あなたに続くn00bの言語の理解です。

可能な限り最も明確で明確な方法でコードを記述します。余分な括弧が役立つ場合があります(常にではありません)。多くの場合、1行に1つのステートメントだけを置くと役立ちます。多くの場合、コーディングスタイルの一貫性が役立ちます。

かっこが多すぎることもありますが、助言が不要な状況の1つです。見ればわかります。その時点で、コードをリファクタリングして、括弧を削除するのではなく、ステートメントの複雑さを減らします。

94
Dan Pichelman

はい

常に括弧を使用する必要があります...優先順位は制御しません...コンパイラの開発者が行います。かっこを使わないという話をしてみました。これは、2週間にわたって何百人もの人々に影響を与えました。

現実の理由

メインフレームアプリケーションを継承しました。ある日、真っ青な状態から、それは機能しなくなりました。それだけです...止まっただけです。

私の仕事はそれをできるだけ速く動かすことでした。ソースコードは2年間変更されていませんでしたが、突然停止しました。コードをコンパイルしようとしたところ、XX行で壊れました。行XXを見たところ、行XXが壊れる原因がわかりませんでした。このアプリケーションの詳細な仕様を尋ねたところ、何もありませんでした。行XXは原因ではありませんでした。

コードを印刷して、上から下にレビューを始めました。何が起こっているかのフローチャートを作成し始めました。コードが複雑すぎて、意味がわかりません。私はそれをフローチャートにしようとするのをあきらめました。特にアプリケーションの動作や依存関係チェーンのどこにあるのか詳細がわからなかったため、その変更が残りのプロセスにどのように影響するかを知らずに変更を加えることを恐れました。

そこで、ソースコードの先頭から始めて、コードを読みやすくするためにwhitespceとlineブレーキを追加することにしました。場合によっては、ANDORを組み合わせた条件があり、ANDedであるデータとORedであるデータを明確に区別できない場合がありました。そこで、ANDORの条件を括弧で囲んで読みやすくしました。

ゆっくりと掃除しながら片付けながら、定期的に作業を保存していました。ある時点でコードをコンパイルしようとしたところ、奇妙なことが起こりました。エラーはジャンプして元のコード行を通過し、さらに下にありました。だから私は続けて、ANDORの条件を括弧で分離しました。私がそれをきれいにしたとき、それはうまくいった。図に移動します。

次に、オペレーションショップに行って、メインフレームに新しいコンポーネントを最近インストールしたかどうかを尋ねることにしました。はい、私たちは最近コンパイラをアップグレードしました。うーん。

古いコンパイラは式に関係なく左から右に式を評価したことがわかります。新しいバージョンのコンパイラーも式を左から右に評価しましたが、あいまいなコードです。つまり、ANDORの明確な組み合わせを解決できませんでした。

これから学んだ教訓...常に、常に、常に、括弧を使用して、AND条件とOR条件を互いに組み合わせて使用​​する場合、それらを分離します。

簡略化された例

_IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ..._(これらのいくつかが散らばったコード)

これは私が遭遇したものの簡略版です。他にも複合ブール論理ステートメントを持つ条件がありました。

私はそれを次のように変えたことを覚えています:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...



仕様がなかったため、書き直すことができませんでした。原作者は長い間いなくなっていました。強いプレッシャーを覚えています。貨物船全体が港に取り残されており、この小さなプログラムが機能しなかったため、降ろすことができませんでした。警告なし。ソースコードに変更はありません。かっこを追加するとエラーがシフトすることに気付いた後、ネットワークオペレーションに何か変更があるかどうかを尋ねるのは、私に夜明け前のことでした。

はい、「and」と「or」が混在している場合。

論理的に1つのチェックとは何かを()することもお勧めします。

最善の方法は、適切な名前の述語関数を使用し、ほとんどのチェックと条件を削除して、単純で読みやすいものにすることです。

18
Balog Pal

括弧は意味的に冗長であるため、コンパイラは気にしませんが、それは赤いニシンです。本当の懸念は、プログラマの読みやすさと理解力です。

ここでは、過激な位置を取り、a AND b OR c AND dの括弧に心からの「いいえ」を与えます。すべてのプログラマーは、ブール式の優先順位がNOT> AND> ORのようになることを覚えておく必要があります申し訳ありません、私の親愛なる叔母サリー代数的式。冗長な句読点は、コードのほとんどの時間に視覚的な混乱を追加するだけで、プログラマーの可読性に利点はありません。

また、論理式と代数式で括弧を常に使用する場合は、「ここでトリッキーなことが起こっている-気をつけて!」のマーカーとしてそれらを使用する機能を放棄します。つまり、デフォルトの優先順位をoverrideオーバーライドして、乗算の前に加算を評価する場合、またはOR ANDの前に)を指定する場合、括弧はナイスです。次のプログラマーへの赤旗必要のないときに使いすぎると、オオカミを叫んだ少年になります。

Cのポインター式など、代数の領域外(ブールかそうでないか)を例外とします。*p++p = p->nextなどの標準のイディオムよりも複雑なものは、おそらく括弧で囲む必要があります。間接参照と演算をまっすぐにします。そしてもちろん、これはLISP、Forth、Smalltalkなどの式にポーランド語表記を使用する言語には当てはまりません。しかし、主流の言語の大部分では、論理的および算術的な優先順位は完全に標準化されています。

14

私の考えでは:

[〜#〜]はい[〜#〜]長所:

  • 操作の順序は明示的です。
  • 操作の順序を理解していない将来の開発者からあなたを守ります。

[〜#〜]はい[〜#〜]短所:

  • コードが乱雑で読みにくい

[〜#〜] no [〜#〜]長所:

[〜#〜] no [〜#〜]短所:

  • 操作の順序は暗黙的です
  • 操作の順序を十分に理解していない開発者は、コードを保守しにくくなります。
8
MetaFight

一般的なケース

C#では、乗算と除算は加算と減算よりも優先されます。

それでも、十分に明確ではない可能性があるコードによって導入されるバグのリスクを軽減するための追加の目標を使用してコードベース全体に共通のスタイルを適用するツールであるStyleCopには rule SA1407 があります。このルールは、次のようなコードを含む警告を生成します。

var a = 1 + 2 * 3;

結果が7ではなく9であることは明らかですが、それでもStyleCopは括弧を付けることを提案しています:

var a = 1 + (2 * 3);

あなたの特定のケース

特定のケースでは、使用する特定の言語でORと比較してANDが優先されます。

これはすべての言語が動作する方法ではありません。他の多くはANDとOR=を同等に扱います。

ほとんどC#で作業する開発者として、最初にあなたの質問を見て、前に書いたものを読まずにコードを読んだとき、私の最初の誘惑は2つの式は同じではないとコメントすることでした。うまくいけば、コメントする前に質問全体を完全に読んだことでしょう。

この特殊性と、一部の開発者がANDとORの優先順位が同じであると考える可能性があるため、リスクがあるため、括弧を追加することがさらに重要になります。

賢いことを示すことを目的としたコードを記述しないでください。言語のすべての側面に精通していない可能性がある人も含めて、可読性を目標にコードを記述してください。

3

余分な括弧を含めることについて賛成または反対の議論はありますか?実際の経験では、読みやすくするためにそれらを含める価値があると示唆していますかそれとも、開発者が実際に座って言語の基本に自信を持つ必要があるという兆候ですか?

他の誰も私のコードをもう一度見る必要がなければ、私は気にしないと思います。

しかし、私の経験から:

  • 私は時々自分のコードをもう一度見ます(時にはyears書いた後)
  • 他の人が私のコードを時々見る
    • またはそれを拡張/修正する必要さえあります!
  • 私も他の人も、私が書いたときに考えていたことを正確に覚えていません
  • 不可解な「文字数を最小限に抑える」コードを書くと読みやすさが低下する

私はほとんどいつもこれを行います。なぜなら、私はすばやく読む能力があり、括弧を使って他の何よりも多くの小さな間違いを犯さないからです。

あなたの場合、私はほぼ確実に次のようなことをします:

if (a AND b) then ab = true
if (c AND d) then cd = true
If (ab OR cd) Then ...

はい、それはより多くのコードです。はい、代わりに空想ブール演算子を実行できます。いいえ、将来1年以上コードをスキミングするとき、私は空想的なブール演算子を誤解する可能性はありません。 AND/ORの優先順位が異なる言語でコードを記述していて、これを修正するためにジャンプする必要があった場合はどうなりますか?私は行くつもりですか?「ああ!私がしたこの賢い小さなことを覚えています!昨年書いたときに括弧を含める必要はありませんでした。今覚えている良いことです!」それが起こった場合(またはさらに悪いことに、この賢さを認識していないか、「できるだけ早く」タイプの状況に投げ込まれた他の誰か)?

()で区切ると、すぐに読み飛ばして後で理解するのがはるかに簡単になります...

3
enderland

誰もが言ったように、式を読みやすくするたびに括弧を使用します。ただし、式が複雑な場合は、部分式に新しい関数を導入するをお勧めします。

1
Honza Brabec

それとも、開発者が実際に座って言語の基本に自信を持つ必要があるという兆候ですか?

厳密にlanguageを単数形で使用している場合は、たぶん。さて、あなたが知っているすべてのlanguagesを、古いものから最新のものまで、コンパイルからスクリプト、SQLに、先月発明した独自のDSLに変更してください。

見ずに、これらの各言語の正確な優先規則を覚えていますか?

0
Secure

「論理ステートメントで、必要がない場合でも括弧を使用する必要があります。」

はい、2人が役立つと思うからです。

  • 次のプログラマーは、知識、能力、またはスタイルが異なる場合があります

  • 将来このコードに戻る未来のあなた!

0
Michael Durrant