为什么C / C ++中没有^^运算符?
&
has &&
。 |
有||
。 为什么不^
^^
?
我知道它不会短路,但会有不同的语义。 在C中, true
是任何非零值。 按位异或并不总是与逻辑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
丹尼斯里奇的回答
有没有
^^
运算符的历史和实际原因都有。实际情况是:操作员没有太多用处。
&&
和||
要点 是为了利用他们的短路评估,不仅是出于效率的原因,更常见的是表达性和正确性。
[…]
相比之下,^^
运算符总是强制对表达式的两个臂进行求值,因此没有效率增益。 此外,尽管可以创建示例,但实际上要求^^
情况非常罕见。 当你堆叠操作员时,这些情况变得越来越奇怪 –if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
确切地说,当奇数个
condx()
s为真时。 相比之下,&&
和||
类比仍然相当合理和有用。
从技术上讲,一个已经存在:
a != b
因为如果操作数的真值不同,这将评估为真。
编辑:
沃尔特的评论:
(!a) != (!b)
是正确的,因为我上面的答案不适用于int
类型。 如果他补充说明,我会删除我的。
再次编辑:
也许我忘记了C ++中的一些东西,但是我想的越多,我就越想知道为什么你会在第一时间写if (1 ^ 2)
。 ^
的目的是将一个或两个数字放在一起(计算到另一个数字),而不是将它们转换为布尔值并比较它们的真值。
对于语言设计师来说,这似乎是一个奇怪的假设。
对于非bool
操作数,我想你想要的是a ^^ b
评估为:
(a != 0) ^ (b != 0)
好吧,你有上面的选项,你在其他答案中列出了一些选项。
对于bool
操作数,运算符^^
将是多余的。 仅讨论布尔操作数,为了参数,让我们假设^
只是按位而且^^
作为逻辑异或存在。 然后你有这些选择:
-
&
– 按位AND – 始终计算两个操作数 -
&&
– 逻辑AND – 并不总是评估两个操作数 -
|
– 按位OR – 始终计算两个操作数 -
||
– 逻辑OR – 并不总是评估两个操作数 -
^
– 按位异或 – 必须始终评估两个操作数 -
^^
– 逻辑异或 – 必须始终评估两个操作数
他们为什么不创建^^
基本上将数值转换为bool
s然后充当^
? 这是个好问题。 也许是因为它比&&
和||
更容易混淆 ,也许是因为你可以很容易地用其他运算符构造^^
的等价物。
我不能说出他们发明C时Kernighan和Ritchie的脑袋里有什么,但是你简单地提到“不会短路”,我猜这就是原因:它不可能实现它始终如一。 你不能像你可以和OR一样短路XOR,所以^^不能完全平行&&和||。 所以作者可能已经决定将一种类似于其他操作的操作看作是与其他操作并行但不完全比没有它更糟糕。
就个人而言,我使用&&和||的主要原因 用于短路而不是非按位。 实际上我很少使用按位运算符。
上面发布的那些解决方法(即使它需要代码中的另一个分支)将是:
if ( (a? !b : b ) )
这相当于xor。
在Java中,当在两个布尔操作数上使用时, ^
运算符确实会执行逻辑XOR(就像在和Java中的&
和|
在应用于布尔值时分别进行非短路逻辑AND和OR)。 与C / C ++的主要区别在于C / C ++允许您混合整数和布尔值,而Java则不然。
但我认为无论如何使用整数作为布尔运算是不好的做法。 如果你想进行逻辑运算,你应该坚持bool
值,或者是0或1的整数。那么^
作为逻辑XOR工作正常。
一个类似的问题是,如何在C / C ++中进行非短路逻辑AND和OR? 通常的答案是使用&
和|
运营商分别。 但同样,这取决于值是bool
还是0或1.如果允许任何整数值,那么这也不起作用。
无论是作为运算符支持还是反对^^
的情况,你使用strcmp()
例子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,按位^
运算符也可以更好地工作…