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