为什么C/C++中没有^^运算符?

Zif*_*fre 16 c c++ language-design operators xor

&&&.|||.为什么不^^^

我知道它不会短路,但会有不同的语义.在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)
Run Code Online (Sandbox Code Playgroud)

因为你不能总是依赖于一个真正的价值是1-1,就不是一个^^运营商有很大的帮助?我经常要做这样的奇怪事情:

if(!!a ^ !!b) // looks strange
Run Code Online (Sandbox Code Playgroud)

小智 54

丹尼斯里奇的回答

没有^^运营商的原因既有历史原因,也有实际原因.

实际情况是:操作员没有太多用处.的要点&&||是利用其短路评价不仅出于效率的考虑,但更经常的表现力和正确性.
[...]
相比之下,^^操作员总是会强制评估表达式的两个臂,因此没有效率增益.此外,^^尽管可以创建示例,但真正需要的情况非常罕见.当你堆叠操作员时,这些情况变得越来越奇怪 -

if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
Run Code Online (Sandbox Code Playgroud)

确切地说,当奇数个condx()s为真时.相比之下,这些&&||类似物仍然相当合理和有用.

  • 哇,我没想到Dennis Rithchie回答我的问题:).请参阅Terry Donaghe的评论.他确实给了一些非常好的观点.+1 (3认同)

Joh*_*sch 24

从技术上讲,一个已经存在:

a != b
Run Code Online (Sandbox Code Playgroud)

因为如果操作数的真值不同,这将评估为真.

编辑:

沃尔特的评论:

(!a) != (!b)
Run Code Online (Sandbox Code Playgroud)

是正确的,因为我上面的答案不适用于int类型.如果他补充说明,我会删除我的.

再次编辑:

也许我忘记了C++中的一些东西,但是我想的越多,我就越想知道你为什么要写if (1 ^ 2)第一篇.其目的^是将一个或两个数字放在一起(计算到另一个数字),而不是将它们转换为布尔值并比较它们的真值.

对于语言设计师来说,这似乎是一个奇怪的假设.

  • '(!a)!=(!b)'具有相同的效果. (3认同)
  • 不,1!= 2是真的,当1 ^^ 2为假时.你最终不得不把它包装进去!在这种情况下,我认为!! 1 ^ !! 2会更清楚. (2认同)

Edd*_*die 5

对于非bool操作数,我猜您想要的是a ^^ b评估为:

(a != 0) ^ (b != 0)
Run Code Online (Sandbox Code Playgroud)

好吧,你有上面的选项,你在其他答案中列出了一些选项.

^^对于bool操作数,运算符将是多余的.只讨论布尔操作数,为了论证,让我们假装^只是按位而且^^存在逻辑异或.然后你有这些选择:

  • & - 按位AND - 始终计算两个操作数
  • && - 逻辑AND - 并不总是评估两个操作数
  • | - 按位OR - 始终计算两个操作数
  • || - 逻辑OR - 并不总是评估两个操作数
  • ^ - 按位异或 - 必须始终评估两个操作数
  • ^^ - 逻辑异或 - 必须始终评估两个操作数

他们为什么不创建^^基本上将数值转换为bools然后充当^?这是个好问题.也许是因为它更可能比混乱&&||,也许是因为你可以很容易地构造相当于^^与其他运营商.


Jay*_*Jay 5

我不能说出他们发明C时Kernighan和Ritchie脑袋里有什么,但是你简单地提到"不会短路",我猜这就是原因:它不可能实现一贯的.你不能像你可以和OR一样短路XOR,所以^^不能完全平行&&和||.因此,作者可能已经决定将一种类似于其他操作的操作看作是与其他操作并行但不完全比没有它更糟糕.

就个人而言,我使用&&和||的主要原因 用于短路而不是非按位.实际上我很少使用按位运算符.