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

时间:2009-05-07 22:00:53

标签: c++ c operators language-design 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)

由于您不能始终依赖1-1的真值,^^运算符不会非常有用吗?我经常要做这样奇怪的事情:

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

7 个答案:

答案 0 :(得分:54)

Dennis Ritchie answers

  

为什么没有^^运算符,有历史和实际原因。

     

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

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

确切地说明奇数个condx() s是否为真。相比之下,&&||类似物仍然相当合理且有用。

答案 1 :(得分:24)

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

a != b

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

编辑:

Volte的评论:

(!a) != (!b)

是正确的,因为上面的答案对int类型不起作用。如果他补充答案,我会删除我的。

再次编辑:

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

对于语言设计师而言,这似乎是一个奇怪的假设。

答案 2 :(得分:5)

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

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

嗯,您有以上选项,其他答案中列出了一些选项。

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

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

为什么他们没有创建^^来基本上将数值转换为bool s然后充当^?这是个好问题。也许是因为它比&&||更容易混淆,可能是因为您可以轻松地与其他运算符构造等效的^^

答案 3 :(得分:5)

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

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

答案 4 :(得分:1)

上面发布的解决方法(即使它需要代码中的另一个分支)将是:

if ( (a? !b : b ) )

相当于xor。

答案 5 :(得分:1)

在Java中,^运算符确实在两个布尔操作数上使用逻辑XOR(就像&和Java中的|做非短路逻辑AND和OR,分别适用于布尔人)。与C / C ++的主要区别在于,C / C ++允许您混合整数和布尔值,而Java则不允许。

但我认为无论如何使用整数作为布尔值是不好的做法。如果要进行逻辑运算,则应该坚持使用bool值或0或1的整数。然后^可以正常运行逻辑XOR。

类似的问题是,如何在C / C ++中进行非短路逻辑AND和OR?通常的答案是分别使用&|运算符。但同样,这取决于值为bool或0或1.如果允许任何整数值,则这也不起作用。

答案 6 :(得分: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,按位^运算符也可以更好地运行...