私はいくつかの初心者の間違いを考えていました、そして私はif
声明にあるもので終わりました。私はコードをこれに少し拡張しました:
int i = 0;
if (i = 1 && i == 0) {
std::cout << i;
}
私はそれが見てきたif
文はtrueを返し、それはcout
「S i
のように1
。場合はi
割り当てられている1
if文で、なぜやりましたi == 0
戻りますかtrue
?
1 && i == 0
ますか?
私はいくつかの初心者の間違いを考えていました、そして私はif
声明にあるもので終わりました。私はコードをこれに少し拡張しました:
int i = 0;
if (i = 1 && i == 0) {
std::cout << i;
}
私はそれが見てきたif
文はtrueを返し、それはcout
「S i
のように1
。場合はi
割り当てられている1
if文で、なぜやりましたi == 0
戻りますかtrue
?
1 && i == 0
ますか?
回答:
これは、演算子の優先順位に関係しています。
if (i = 1 && i == 0)
ではありません
if ((i = 1) && (i == 0))
両方&&
と==
優先順位がよりも高いです=
。それが本当にうまくいくのは
if (i = (1 && (i == 0)))
その結果割り当て1 && (i == 0)
にしますi
。あれば、i
から始まり0
、その後はi == 0
あるtrue
、そう1 && true
であるtrue
(または1
)、その後i
に設定されます1
。次に、1
trueなので、ifブロックを入力して、割り当てた値を出力しますi
。
i = !i; if (i)
適切に書かれています
コードが実際に次のようになっていると仮定します。
#include <iostream>
using namespace std;
int main() {
int i = 0;
if (i = 1 && i == 0) {
cout << i;
}
}
次にこれ:
if (i = 1 && i == 0) {
として評価
if (i = (1 && i == 0)) {
にi
設定されてい1
ます。
using namespace std
!
=
前に来たと思った人は誰でも&&
問題を見ることができます。また、そうです、拡張は無関係ですが、それほど重要ではないと思います。私はそのような小さな違いが人々に151から-4を投票させるとは信じられません。
これは、右から左へのルールの解析に関係しています。たとえば、y = x + 5。
すべての部分式は重要度に重み付けされています。重要度が等しい2つの式は、右から左に評価されます。&&式の側が最初に行われ、次にLHSが続きます。
私には理にかなっています。
実際の答えは:
証明として、入力したコードのコンパイラのasm出力を確認してください(すべてのコメントは自分のものです)。
mov dword ptr [rbp - 8], 0 ; i = 0;
cmp dword ptr [rbp - 8], 0 ; i == 0?
sete al ; TRUE (=1)
mov cl, al
and cl, 1 ; = operator always TRUE
movzx edx, cl
mov dword ptr [rbp - 8], edx ; set i=TRUE;
test al, 1 ; al never changed,
; so final ans is TRUE
上記のasm出力はCLANGからのものでしたが、私が調べた他のすべてのコンパイラーも同様の出力を出しました。これは、サイトのすべてのコンパイラーに当てはまります。それらが純粋なCコンパイラーであるか、C ++コンパイラーであるかに関係なく、コンパイラーのモードを変更するプラグマはありません(デフォルトではC ++コンパイラーのC ++です)。
コンパイラは実際にはi = 1ではなく、i = TRUEを設定したことに注意してください(ゼロ以外の32ビットの整数値を意味します)。これは、&&演算子はステートメントがTRUEかFALSEかを評価するだけであり、その結果に従って結果を設定するためです。証明として、i = 1をi = 2に変更してみてください。何も変更されないことが自分で確認できます。Compiler Explorerでオンラインコンパイラを使用して自分の目で確かめてください
i = 1
代入演算子[同等ではない]です。2b)if (i = 0)
CとC ++の両方でfalse条件に評価されることを保証できます。したがって、「決して失敗しない」という条件でtrueと評価されるかどうかは、多少誤解を招きます。
and cl, 1 ; = operator always TRUE
<<私が間違っている場合は修正しますが、ここには割り当てがありません。1 &&
式の一部を表します。したがって、この答えは基本的にに評価されfalse
ます。
if ( i = 0 ) { print something }
。また、あなたの答えはそれ自体と矛盾しています。最初に、i=1
前に評価されたこと&&
が適用されると言い、最後に、それi
が&&
演算子の結果に設定されると言います。
i
がに設定されているため、ifコードにこのコードを入力した理由を知りたいと考えてい1
ます。