有这样的事吗?这是我第一次遇到它的实际需要,但我没有看到列出的in Stroustrup . 我打算写:
// Detect when exactly one of A,B is equal to five.
return (A==5) ^^ (B==5);
但是没有 ^^
运营商 . 我可以在这里使用按位 ^
并得到正确的答案(无论机器表示真和假)?我从不混淆 &
和 &&
,或 |
和 ||
,所以我对 ^
和 ^^
犹豫不决 .
我会更自在地编写自己的 bool XOR(bool,bool)
函数 .
11 回答
XOR运算符不能短路;即,仅通过评估其左手操作数,您无法预测XOR表达式的结果 . 因此,没有理由提供
^^
版本 .还有另一种方法可以做XOR:
显然可以证明通过以下方式工作:
!=
运算符用于bool
值 .以下是我认为您在C中编写XOR比较的方式:
证明
证据是对输入和输出的详尽研究表明,在两个表中,对于每个输入集,结果在两个表中始终是相同的 .
因此,原来的问题是如何写:
答案是
或者,如果你愿意,写信
对于真正的逻辑XOR操作,这将起作用:
我们否定
A
和B
的原因是将它们转换为布尔值 . 否定不是意图 . 将整数转换为布尔值的常见技巧是使用!!
. 这会将变量的值转换为0
,否则变量为0
和1
. 我们本可以使用!!A != !!B
代替 . 另一种方法是使用(_Bool)A != (_Bool)B
.适当的手动逻辑XOR实现取决于您希望模拟其他逻辑运算符(
||
和&&
)与XOR的一般行为的接近程度 . 关于这些运算符有两个重要的事项:1)它们保证短路评估,2)它们引入序列点,3)它们仅评估它们的操作数一次 .如您所知,XOR评估不能被短路,因为结果总是取决于两个操作数 . 所以1是不可能的 . 但是2呢?如果你不关心2,那么使用标准化(即
bool
)值,运算符!=
在结果方面完成XOR的工作 . 如果需要,可以使用一元!
轻松地对操作数进行标准化 . 因此!A != !B
在这方面实现了正确的XOR .但是如果你关心额外的序列点,那么
!=
和bitwise^
都不是实现XOR的正确方法 . 正确执行XOR(a,b)的一种可能方法可能如下所示这实际上就像你可以制作一个自制的XOR "similar"到
||
和&&
. 当然,只有将XOR实现为宏时,这才有效 . 一个函数赢得了't do, since the sequencing will not apply to function'的参数 .有人可能会说,在每个
&&
和||
都有一个序列点的唯一原因是支持短路评估,因此XOR不需要一个 . 实际上,这是有道理的 . 然而,值得考虑在中间具有序列点的XOR . 例如,以下表达式已经在C / C中定义了行为和特定结果(至少在排序方面) . 因此,人们可能合理地期望用户定义的逻辑XOR相同,如同
而基于
!=
的XOR没有此属性 .(A || B) && !(A && B)
第一部分是A OR B,即包含OR;第二部分是,不是A和B.一起得到A或B,但不是A和B.
这将提供下面真值表中证明的XOR .
它按照定义工作 . 条件是检测你是否正在使用Objective-C,这要求BOOL而不是bool(长度不同!)
我使用"xor"(它似乎是一个关键字;在Code::Blocks中至少它变为粗体)就像你可以使用"and"而不是
&&
而"or"而不是||
.是的,这是有点的 . 抱歉 .
发布了一些好的代码,比#!=!b更好地解决了问题
请注意,我必须添加BOOL_DETAIL_OPEN / CLOSE,以便它可以在MSVC 2010上运行
使用简单: