【发布时间】:2015-09-02 16:19:03
【问题描述】:
我刚刚遇到了一个简单的布尔问题
如果我有一个像这样的 if 语句:!(!A && !B) && B,它到底是怎么回事?
我认为它与A && B 相同(反转括号内的条件),但显然不是......这让我很烦恼
那么,是否有人想详细说明它的实际情况,因为我认为我在这里遗漏了一些东西?
【问题讨论】:
标签: if-statement boolean
我刚刚遇到了一个简单的布尔问题
如果我有一个像这样的 if 语句:!(!A && !B) && B,它到底是怎么回事?
我认为它与A && B 相同(反转括号内的条件),但显然不是......这让我很烦恼
那么,是否有人想详细说明它的实际情况,因为我认为我在这里遗漏了一些东西?
【问题讨论】:
标签: if-statement boolean
!(!A && !B) && B 是 (A || B) && B 你忘记将 and 反转为 or 的 sams。顺便说一句,这只是 B。
【讨论】:
!(!A && !B) = (A || B)
所以
!(!A && !B) && B = (A || B) && B = A && B || B = B
最后的结果简直就是B
【讨论】:
不幸的是,在一般情况下,您不能像在离散数学课上那样在编程中使用逻辑恒等式。
正如 HashPsi 和 Bas van Stein 所提到的,从逻辑的角度来看,您的表达式等同于 B。在现实世界中,您可以拥有以下代码:
def A():
throw StupidException()
def B():
return True
!(!A() && !B()) && B() # throws exception
B() # returns True
所以从技术上讲,您的表达式与 B 有很大不同。您可以说这是一个非常具体的示例,但实际上您的大多数函数都有一些副作用,因此通常您永远不能假设数学逻辑适用于布尔表达式。
作为一个布尔表达式排序很重要的实际示例,您可以考虑以下惯用的 C++ 代码:
if (foo && foo->bar()) {do something}
上面的代码会在调用 bar 方法之前检查 foo 不为空。如果你只是重新排列那个表达,你会迷恋:
if (foo->bar() && foo) {do something}
如果 foo==nullptr,foo->bar 将导致程序终止,因为 foo->bar() 会在检查 foo 值之前尝试被调用。
【讨论】: