16

&持ってい&&ます。|持ってい||ます。なぜないのです^^^

ショートサーキットではないことは理解していますが、セマンティクスが異なります。C では、true実際にはゼロ以外の任意の値です。ビット単位の XOR は、常に論理 XOR と同じではありません。

int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)

1真の値がorであることに常に依存できるとは限ら-1ないため、^^演算子は非常に役に立ちませんか? 私はしばしば次のような奇妙なことをしなければなりません:

if(!!a ^ !!b) // looks strange
4

7 に答える 7

54

デニス・リッチーの答え

演算子がないのには、歴史的および実際的な理由があり^^ます。

実際には、演算子はあまり役に立ちません。&&andの主なポイントは||、効率的な理由だけでなく、表現力と正確さのために、短絡評価を利用することです。
[...]
対照的に、^^演算子は常に式の両アームの評価を強制するため、効率の向上はありません。さらに、^^例を作成することはできますが、実際に必要とされる状況は非常にまれです。これらの状況は、オペレーターを積み重ねるにつれて、ますます珍しく奇妙になります--

if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...

奇数のcondx()s が true の場合、正確に後件を実行します。対照的に、&&および||アナログは依然としてかなり妥当で有用です。

于 2009-05-07T22:44:09.550 に答える
24

技術的には、すでに存在します:

a != b

これは、オペランドの真理値が異なる場合に true と評価されるためです。

編集:

ヴォルテさんのコメント:

(!a) != (!b)

上記の私の答えは型では機能しないため、正しいですint。彼が答えを追加した場合、私は私のものを削除します。

もう一度編集します。

C++ から何かを忘れているのかもしれませんが、これについて考えれば考えるほど、if (1 ^ 2)そもそもなぜあなたが書いたのか疑問に思います。の目的^は、2 つの数値の排他的論理和 (別の数値に評価される) であり、それらをブール値に変換してそれらの真値を比較することではありません。

これは、言語設計者が行うのは奇妙な仮定のようです。

于 2009-05-07T22:04:23.623 に答える
5

カーニハンとリッチーが C を発明したときの頭の中に何があったかはわかりませんが、あなたは「短絡することはない」と簡単に言及しましたが、それが理由だと思います。それを一貫して。AND と OR のように XOR を短絡することはできないため、^^ は && と || を完全に並列化できませんでした。したがって、作成者は、ある種の操作を他の操作と類似しているように見えるが、まったくそうではない操作を作成することは、まったく実行しないよりも悪いと判断した可能性があります。

個人的に && と || を使う主な理由は 非ビット単位ではなく短絡用です。実際、ビット単位の演算子を使用することはほとんどありません。

于 2009-05-07T22:28:59.210 に答える
5

boolオペランドの場合、次のa ^^ bように評価されることをお勧めします。

(a != 0) ^ (b != 0)

さて、上記のオプションがあり、他の回答にいくつかのオプションがリストされています。

演算子はオペランド^^に対して冗長です。論理演算オペランドについてのみ話しますが、議論のために、それがビット単位のみであり、論理 XOR として存在していたとしboolましょう。次に、次の選択肢があります。^^^

  • & - ビットごとの AND -- 常に両方のオペランドを評価します
  • &&- 論理 AND -- 常に両方のオペランドを評価するとは限りません
  • | - ビットごとの OR -- 常に両方のオペランドを評価します
  • ||- 論理 OR -- 常に両方のオペランドを評価するとは限りません
  • ^ - ビット単位の XOR -- 常に両方のオペランドを評価する必要があります
  • ^^- 論理 XOR -- 常に両方のオペランドを評価する必要があります

^^数値を本質的に に変換しboolて として機能するように作成しなかったのはなぜ^ですか? それは良い質問です。&&おそらく、 andよりも混乱する可能性が高いため、おそらく、同等のを他の演算子||で簡単に作成できるためです。^^

于 2009-05-07T22:04:01.813 に答える
1

Java では、^演算子は 2 つのブール オペランドで使用された場合、実際に論理 XOR を実行します ( Java では、ブール値に適用された場合に、短絡しない論理 AND および OR をそれぞれ実行するの&と同じように)。|C / C++ との主な違いは、Java ではできないのに対し、C / C++ では整数とブール値を混在させることができることです。

しかし、とにかく整数をブール値として使用するのは悪い習慣だと思います。bool論理演算を実行する場合は、0 または 1 のいずれかの値または整数に固執する必要があります。その後^、論理 XOR として正常に機能します。

同様の質問は、C / C++ で非短絡論理 AND および OR をどのように行うかを尋ねることです。通常の答えは、演算子&|演算子をそれぞれ使用することです。ただし、これは値がbool0 か 1 かによって異なります。整数値を許可すると、これも機能しません。

于 2009-05-08T07:40:05.330 に答える
1

上記の別の回避策 (コードに別のブランチが必要な場合でも) は、次のようになります。

if ( (a? !b : b ) )

これは xor と同等です。

于 2009-05-08T05:59:30.500 に答える
0

^^演算子としての賛成または反対の場合に関係なく、あなたはstrcmp()吸うことで例を示します。真理値(trueまたはfalse)を返すのではなく、整数としてエンコードされた入力間の関係を返します。

確かに、任意の整数はCの真理値として解釈できます。この場合、0は「偽」であり、他のすべての値は「真」ですが、それはstrcmp()返されるものの反対です。

あなたの例は始まるべきです:

int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"

戻り値を0と比較して、文字列が等しいかどうかを示す適切なブール値に変換する必要があります。

正規に0または1として表される「適切な」ブール値を使用すると、ビット^演算子もはるかにうまく機能します...

于 2009-05-08T07:51:50.263 に答える