Cで論理演算子がどのように機能するかを理解しようとして問題があります。ビットレベルの演算子がどのように機能するかをすでに理解しています。また、論理演算子がゼロ以外の引数をTRUEを表し、ゼロ引数をFALSEを表すものとして扱うことも知っています。
ただし、0x65&&0x55があるとします。この操作で0x01が得られる理由と方法がわかりません。
バイナリに変換しようとしましたが、どのように機能するのかわかりません
Cで論理演算子がどのように機能するかを理解しようとして問題があります。ビットレベルの演算子がどのように機能するかをすでに理解しています。また、論理演算子がゼロ以外の引数をTRUEを表し、ゼロ引数をFALSEを表すものとして扱うことも知っています。
ただし、0x65&&0x55があるとします。この操作で0x01が得られる理由と方法がわかりません。
バイナリに変換しようとしましたが、どのように機能するのかわかりません
&&
オペレーター:
左のオペランドと右のオペランドの両方が、それが評価するものと異なる場合、0
それ1
以外の場合は、と評価され0
ます。
左のオペランドが。の場合0
、右のオペランドは評価されず、結果は。になり0
ます。
0x65 && 0x55
に評価され1
ます。
これ&&
は論理的です(ビット単位の、とはAND
対照的です)。オペランドがゼロ/非ゼロ値であることだけを気にします。ゼロはと見なされ、ゼロ以外は。として扱われます。&
AND
false
true
あなたの場合、両方のオペランドがゼロ以外であるため、それらはとして扱われtrue
、結果true
も同様になります。Cはとしてを表しtrue
、1
操作の全体的な結果を説明します。
操作をに変更する&
と、ビット単位の操作になります。0x65 & 0x55
の結果が得られます0x45
。
&&
は論理演算子であり、ビット演算子ではありません。0x65と0x55の両方が真であるため、結果は真の数値になります。0x01は真の数です。
バイナリ表現は、ビット演算でのみ機能します。式0x65 & 0x55
はに等しい0x45
。
0と評価される式はすべてfalseです。そして、ゼロ以外の式はすべて真です。したがって、0x65と0x55の両方が真です。
0x65 && 0x55
=> true && true => true
バイナリに変換してみました
それが理解の邪魔になっているかもしれません。との正確なビットパターンは、必要な結果0x65
と0x55
は完全に無関係です。重要なのは、両方がゼロ以外であるということだけです。a = (0x65 && 0x55)
次のようなものと同等であると見なすことができます。
if (0x65 != 0) goto condition_false;
if (0x55 != 0) goto condition_false;
a = 1;
goto condition_end;
condition_false:
a = 0;
condition_end:
与えられた実装は、それよりも効率的にコードを出力できる可能性があります(ただし、それぞれif ... goto
がアセンブリ内のテストとブランチであるコードが出力されるのをほとんど見ました)。より効率的なコードには、分岐を回避するためのビット演算が含まれる場合があります。さらに言えば、定数を含むこの例では、コンパイラはおそらく.を出力するだけa = 1;
です。
ただし、演算子の意味は&&
条件付き実行の観点からです。たとえば、次のように記述した場合、false値を返すと、が呼び出されないf() && g()
ことが保証されます。ビットをいじることによって同じ結果を得ることが可能である場合、それはおそらくパフォーマンスのボーナスです。f
g
CおよびC++には、論理否定()、論理and()、論理or( )の3つの論理演算子があります。論理演算子の場合、はfalseであり、ゼロ以外のものはすべてtrueです。この真理値表は、各論理演算子がどのように機能するかを示しています(に使用されます)。!
&&
||
0
1
true
p q p && q p || q
= = ====== ======
1 1 1 1
1 0 0 1
0 1 0 1
0 0 0 0
の真理値表!
は次のとおりです。
p !p
= ===
1 0
0 1
特定の場合:
0x65 && 0x55
式全体に対するオペランド0x65
と0x55
評価の両方がに評価され、したがってに拡張されるため、これはに適用されますが、リンクされたスレッドの他の回答は、以前にもどのように適用されるかを説明しています。true
true
1
c99
c99
Cは、ゼロより大きい値を「True」と定義します。0x65と0x55の両方がこの条件に一致するため、結果もTrueになります。これは、出力では1、または16進表記では0x01になります。
コードの別の記述スタイルは次のとおりです。
(0x65が真)および(0x55が真)を返します。
あなたが言ったように、論理演算子はゼロ以外の引数を表すものとして扱います
(0x65 && 0x55) is equal as (0x65 > 0) && (0x55 > 0)
0x65 > 0 get true and 0x55 > 0 get true as well
So (0x65 && 0x55) is equal true && true = 1