Answers:
我会以为a
,b
并且c
是bool
。
让我们画一些真值表:
| a | !a | a==1 | a==0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 |
正如你所看到的,a
并且a==1
是等价的,!a
并且a==0
也是相等的,所以我们可以改写(a==0 && b==0)xor(c==1)
为(!a && !b) xor c
。
现在再看一些真值表:
| a | b | a xor b | a != b |
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
所以a!=b
等于a xor b
,所以我们可以重写(!a && !b) xor c
为(!a && !b)!=c
。如您所见,您的解决方案是完全等效的,只是写有不同的“符号”。
UPD:忘记提及。教授的解决方案完全以这种方式出现是有原因的。
教授的解决方案比较惯用。尽管您的解决方案在技术上是正确的,但它不是惯用的C ++代码。
第一个小问题是类型的用法。您的解决方案依赖之间的转换int
和bool
比较时,布尔值,数字或使用xor
,这是作用于“按位异或”操作int
太迟了。在现代C ++中,使用正确类型的值而不依赖于此类转换有时会更加令人赞赏,因为它们有时不那么清晰且难以推理。对于bool
这样的值分别是true
和false
而不是1
和0
。还!=
比说更合适,xor
因为从技术上来说,bool
s是作为数字存储的,但是在语义上您没有任何数字,只是逻辑值。
第二个问题也是关于成语的。它位于:a == 0
。将布尔表达式与布尔常量进行比较不是一个好习惯。如您所知,a == true
完全等于just a
,并且a == false
是just !a
或not a
(我更喜欢后者)。要了解比较不佳的原因,只需比较两个代码段并确定,这更加清楚:
if (str.empty() == false) { ... }
与
if (not str.empty()) { ... }
总而言之,您教授的解决方案更好(但严格来说,还是错的,严格来说,请进一步了解),因为它使用布尔运算符而不是按位运算符并将布尔值视为整数。c==1
表示“ c为真” 的表达式是错误的,因为如果c可以是数字(根据指定的赋值),则c的任何非零值都将被视为表示true
。
有关为什么最好不要比较布尔值与0或1的比较,请参见此问题。
不使用的一个很好的理由xor
是这是按位异或运算。它在您的示例中确实起作用,因为左侧和右侧都是布尔表达式,它们都转换为1或0(再次参见1)。
布尔异或实际上是!=
。
为了更好地理解您教授的解决方案,最简单的方法是将布尔运算符替换为等效的“替代令牌”,这将布尔运算符转换为更好的可重现(imho)和完全等效的C ++代码:对“!”使用“ not” 和'and'代表'&&'
(not a and not b) != c
不幸的是,exclusive_or
除之外没有其他逻辑运算符not_eq
,在这种情况下这没有帮助。
如果我们分解自然语言表达:
a和b都为假,或者c为真,但不是两个都为真。
首先是关于布尔命题A和B的句子:
A或B,但不能两者都选。
转换为A != B
(仅适用于布尔值,不适用于任何类型A和B)。
命题A是
a和b都是假的
可以说是
a为假b为假
转换成(not a and not b)
,最后
c是真的
简而言之就是c
。结合它们,您会再次得到(not a and not b) != c
。
为了进一步解释此表达式的工作原理,我遵循其他人在其答案中给出的真值表。
而且,如果我可以挑剔:原始赋值指出a,b和c可以是非负数,但并未明确声明如果它们是数字,则应将其限制为值0和1。true
按照惯例,如果不是0代表,那么下面的代码将给出一个令人惊讶的答案:
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
a
,b
并且c
被声明为bool
,在这种情况下c == 1
是正确的,尽管代码很糟糕。无论如何,这就是我要写的答案:OP的代码可能等同于教授的代码,但是C ++不好。
variables are non-negative numbers or boolean
。因此,我向@dhavenith +1了,因为他捕捉到了这里大多数其他人(最初包括我)错过的细节。
我将尝试用更多的词来解释:数字可以隐式转换为布尔值:
零值(用于整数,浮点数和无作用域枚举)以及null指针和null指向成员的值将变为false。所有其他值都变为true。
这得出以下结论:
a == 0
与相同!a
,因为a
转换为布尔值然后取反,等于!(a != 0)
。b也是如此。
c==1
当将成为唯一的真正c
等于 1.使用转换(bool)c
将产生true
时c != 0
不只是如果c == 1
。这样就可以了,因为通常使用值1来表示true
,但是并没有保证。
a != b
与a xor b
when a
和b
ar布尔表达式相同。是的,当一个值或另一个值是正确的,但不是两个都正确时。在这种情况下,左侧(a==0 && b==0)
为布尔值,因此右侧也c
被转换为布尔值,因此,两侧都被解释为布尔表达式,因此!=
与xor
这种情况相同。
您可以使用其他答案提供的真值表亲自检查所有这些。
正如我们从真值表中看到的:
!
(not
)并==0
给出相同的结果。!=
并xor
给出相同的结果。c==1
和刚才一样 c
所以一个在另一个下面,说明了为什么这两个表达式给出相同的结果:
(a==0 && b==0) xor (c==1)
(!a && !b) != c
真相表:
不
| | ! |
| 0 | 1 |
| 1 | 0 |
== 0
| |==0|
| 0 | 1 |
| 1 | 0 |
== 1
| |==1|
| 0 | 0 |
| 1 | 1 |
和
| a | b | && |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
不相等
| a | b | != |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
异或
| a | b |xor|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
a == b or c
代替a == b or a ==c
。问题在于口头语言不准确,实际上两种解释都可能是有效的