(true && true || false && false) は && が優先されて評価されます。
TRUE && TRUE = True
FALSE && FALSE = False
True || False = True
アップデート:
1&&1||infiniteLoop()&&infiniteLoop()
これが C++ で true を生成するのはなぜですか?
前と同じように、分解してみましょう。&& は || よりも優先順位が高い C++ ではブール ステートメントがショート サーキットします。
1 && 1 = True.
bool 値を整数値に変換すると、
false -> 0
true -> 1
式は、この (真) && (真) ステートメントを評価し、|| を短絡して、無限ループの実行を防ぎます。さらに多くのコンパイラ Juju が進行中であるため、これはこの例に適した状況の単純化されたビューです。
非短絡環境では、OR の両側が「評価」され、右側がハングするため、その式は永久にハングします。
優先順位について混乱している場合は、元の投稿で || の場合は次のように評価されます。&& より優先度が高かった:
1st.) True || False = True
2nd.) True && 1st = True
3rd.) 2nd && false = false
Expression = False;
右から左か左から右かは覚えていませんが、どちらの方法でも結果は同じです。2 番目の投稿で || 優先度が高かった:
1st.) 1||InfLoop(); Hang forever, but assuming it didn't
2nd.) 1 && 1st;
3rd.) 2nd && InfLoop(); Hang Forever
tl;dr: && が最初に評価されるのは依然として優先順位ですが、コンパイラは OR も短絡します。本質的に、コンパイラは操作の順序を次のようにグループ化します (単純なビュー、ピッチフォークを配置します:-P)
1st.) Is 1&&1 True?
2nd.) Evaluate if the Left side of the operation is true,
if so, skip the second test and return True,
Otherwise return the value of the second test(this is the OR)
3rd.) Is Inf() && Inf() True? (this would hang forever since
you have an infinite loop)
更新 #2:
「ただし、|| は 2 番目の && の前に評価されるため、この例は && に優先順位がないことを証明しています。これは、&& と || の優先順位が等しく、左から右の順序で評価されることを示しています。」
「&& が優先されると、最初の && (1) が評価され、次に 2 番目の && (無限ループ) が評価され、プログラムがハングします。これは起こらないため、&& は || の前に評価されません。」
これらについて詳しく説明しましょう。
ここでは、2 つの異なることについて話しています。操作の順序を決定する優先順位と、プロセッサ サイクルを節約するためのコンパイラ/言語のトリックであるショート サーキットです。
最初に Precedence について説明しましょう。優先順位は「操作の順序」の省略形です。本質的に、次のステートメントが与えられた場合: 1 + 2 * 3 どの順序で操作を評価のためにグループ化する必要がありますか?
数学では、演算の順序が加算よりも乗算の優先順位が高いと明確に定義されています。
1 + (2 * 3) = 1 + 2 * 3
2 * 3 is evaluated first, and then 1 is added to the result.
* has higher precedence than +, thus that operation is evaluated first.
ここで、ブール式に移行しましょう: (&& = AND, || = OR)
true AND false OR true
C++ では AND が OR よりも優先されるため、
(true AND false) OR true
true AND false is evaluated first, and then
used as the left hand for the OR statement
したがって、優先順位だけで、 (true && true || false && false) は次の順序で処理されます。
((true && true) || (false && false)) = (true && true || false && false)
1st Comparison.) true && true
2nd Comparison.) false && false
3rd Comparison.) Result of 1st comparison || Result of Second
これまで私と一緒に?では、ショート サーキットについて説明します。C++ では、ブール ステートメントは「ショート サーキット」と呼ばれるものです。これは、コンパイラが特定のステートメントを調べて、評価のために「最適なパス」を選択することを意味します。次の例を見てください。
(true && true) || (false && false)
There is no need to evaluate the (false && false) if (true && true)
equals true, since only one side of the OR statement needs to be true.
Thus, the compiler will Short Circuit the expression. Here's the compiler's
Simplified logic:
1st.) Is (true && true) True?
2nd.) Evaluate if the Left side of the operation is true,
if so, skip the second test and return True,
Otherwise return the value of the second test(this is the OR)
3rd.) Is (false && false) True? Return this value
ご覧のとおり、(true && true) が TRUE と評価された場合、(false && false) が true であるかどうかを評価するためにクロック サイクルを費やす必要はありません。
C++ 常にショート サーキットですが、他の言語では「Eager」演算子と呼ばれるもののメカニズムが提供されています。
たとえば、プログラミング言語の Ada を考えてみましょう。Ada では、"AND" と "OR" は "Eager" 演算子です..すべてを強制的に評価します。
Ada では、(true AND true) OR (false AND false) は、OR を評価する前に (true AND true) と (false AND false) の両方を評価します。Ada はまた、AND THEN および OR ELSE で短絡する機能を提供します。これにより、C++ と同じ動作が得られます。
それがあなたの質問に完全に答えることを願っています。そうでない場合は、お知らせください:-)
更新 3: 最後の更新です。引き続き問題が発生する場合は、メールでお知らせします。
「|| 演算子の短絡が発生し、2 番目の && 式の実行が短絡された場合、それは || 演算子が 2 番目の && 演算子の前に実行されたことを意味します。これは、&& および || の左から右への実行を意味します ( &&優先ではありません)」
次に、この例を見てみましょう。
(false && infLoop()) || (true && true) = true (Put a breakpoint in InfLoop and it won't get hit)
false && infLoop() || true && true = true (Put a breakpoint in InfLoop and it won't get hit)
false || (false && true && infLoop()) || true = false (infLoop doesn't get hit)
あなたの言っていることが本当なら、InfLoop は最初の 2 つでヒットするでしょう。また、3 番目の例でも InfLoop() が呼び出されていないことに気付くでしょう。
さて、これを見てみましょう:
(false || true && infLoop() || true);
Infloop が呼び出されます。OR の優先順位が && よりも高い場合、コンパイラは次のように評価します。
(false || true) && (infLoop() || true) = true;
(false || true) =true
(infLoop() || true = true (infLoop isn't called)
しかし、InfLoop が呼び出されます。これが理由です:
(false || true && infLoop() || true);
1st Comparison.) true && InfLoop() (InfLoop gets called)
2nd Comparison.) False || 1st Comp (will never get here)
3rd Comparison.) 2nd Comp || true; (will never get here)
Precendece は操作のグループ化のみを設定します。この場合、&& は || より大きいです。
true && false || true && true gets grouped as
(true && false) || (true && true);
次に、コンパイラがやって来て、サイクルを節約するための最良の機会を与えるために、評価を実行する順序を決定します。
Consider: false && infLoop() || true && true
Precedence Grouping goes like this:
(false && infLoop()) || (true && true)
The compiler then looks at it, and decides it will order the execution in this order:
(true && true) THEN || THEN (false && InfLoop())
それは一種の事実です..そして、私はこれを証明する方法を他に知りません. 優先順位は、言語の文法規則によって決定されます。コンパイラの最適化は、各コンパイラによって決定されます.いくつかは他のものよりも優れていますが、最も少ない比較で最速の実行の「最良の」チャンスを与えるために、グループ化された比較を自由に並べ替えることができます。