int
があり、それを0
と1
の間でブール式に切り替えたいとします。私は次の可能性を考えました:
int value = 0; // May as well be 1
value = value == 0 ? 1 : 0;
value = (value + 1) % 2;
value = !value; // I was curious if that would do...
!0
が1
であると誰が決めるのですか?_Bool
(またはstdbool.hのbool
)と同じですか?そうでない場合、違いは何ですか?編集:たくさんの貴重な情報を含む多くの素晴らしい答え、ありがとう!残念ながら、私は1つしか受け入れることができません。
value = !value;
は、直接実行したいことを表し、定義により、実行したいことを正確に実行します。
その表現を使用します。
C99 6.5.3.3/5「単項算術演算子」から:
論理否定演算子の結果です!オペランドの値が0と等しくない場合は0、オペランドの値が0と等しい場合は1。結果の型はintです。式!Eは(0 == E)と同等です。
3つ目は動作するようです。どうして? !0が1だと誰が決めるのですか?
C標準では、!0
が1
であることを保証しています。
他の可能性はありますか?例えばビット演算子?
はい、排他的なOR演算子を使用できます:
value ^= 1;
ところで、私はこれをvalue = !value;
よりも好んでいます。なぜなら、関係演算子と等価演算子は分岐につながる可能性があり、ビットごとの演算子は通常そうではないためです。
value = (value ^ 1) & 1;
_Bool
も同じ結果になります。 _Boolとの唯一の違いは、値が1または0に強制的に変換されることです。つまり、bool x = 55;
の値はx == 1
編集:私の頭痛のために3の式を修正しました。コメントを書いてもらい、私のブーパーを見てもらいました。
value = !value
が最も妥当な方法のようですが、value = 1 - value
またはvalue ^= 1
を使用することもできます。ただし、value
が0
または1
でない場合、最後の2つは両方とも壊れます。最初のものはまだ機能します。
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
アーキテクチャによっては、代替案で顕著なパフォーマンスの問題が発生する可能性があります。
しかし、とにかく最適化の最初のルールは、機能していないコードを最適化しないことです。 !aをa ^ 1に置き換えるには、常に期待値を生成することを100%確実にする必要があります。
式_value = value == 0 ? 1 : 0;
_は、_value = !value;
_とまったく同じように機能します。 2つのうちいずれかを使用できます。
_!0
_は常に_1
_であり、!(any non zero value)
は_0
_でもあります
C#では、Math.Abs(value -1)
を使用して、整数として0と1を切り替えることができます。