ビットではなくブール値を考える
要約すると、教授の解決策はビット演算子ではなくブール演算子を使用し、ブール値を整数として扱うため、より優れています(ただし、厳密には間違っています。c==1
「cはtrue」を表す式は正しくありません。cが(指定された割り当てに従って)数値である場合、cのゼロ以外の値はを表すと見なされるためtrue
です。
安全であるとしてもブール値を0または1と比較しない方がよい理由については、この質問を参照してください。
使用しない非常に良い理由の1つxor
は、これがビット単位の排他的OR演算であることです。これは、左側と右側の両方が1または0に変換されるブール式であるため、例では偶然に機能します(再度1を参照)。
ブール排他的ORは実際には!=
です。
表現を分解する
教授のソリューションをよりよく理解するには、ブール演算子を同等の「代替トークン」に置き換えるのが最も簡単です。これにより、より優れた再入力可能(imho)で完全に同等のC ++コードに変換されます。そして、あなたが得る「&&」の「そして」
(not a and not b) != c
残念ながら、以外には論理exclusive_or
演算子not_eq
はありません。この場合、これは役に立ちません。
自然言語表現を分解すると:
aとbの両方が偽であるか、cが真であるが、両方ではない。
最初にブール命題AとBについての文に:
AまたはBのいずれかです。両方は使用できません。
これは次のように変換されますA != B
(ブールAとBではなくブール型のみ)。
次に、命題Aは
aとbは両方ともfalse
これは
aはfalse、bはfalse
これはに変換され(not a and not b)
、最後に
cはtrue
これは単にに変換されc
ます。それらを組み合わせると、再び得られ(not a and not b) != c
ます。
この表現がどのように機能するかをさらに説明するために、私は他の人が答えで示した真理値表を参照します。
あなたは両方間違っています
そして、私がちょっと気になるかもしれない場合:元の割り当てでは、a、b、cは負でない数値でもかまわないと述べていましたが、数値の場合は値0と1に制限する必要があることを明確に述べていませんでした。true
通常ではないように0はを表さないため、次のコードは驚くべき答えをもたらします。
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
a == b or c
代わりにに変換することですa == b or a ==c
。問題は、話し言葉が不正確であり、実際には両方の解釈が有効である可能性があることです