这里是否存在逻辑漏洞?

3
我需要执行下面这段代码:

我需要执行下面这段代码:

if(condition 1)
{
    set variable to false
}
else if (condition 2)
{
    set variable to false
} else {
    set variable to true
}

这和这个有什么不同吗?
 if(!condition 1)
 {
   if(!condition2)
   {
     variable = true
   }
 }

这两者的结果在任何情况下都可能不同吗?这是否有系统证明?

3
变量 = !(条件1)&& !(条件2) - max taldykin
1
在第二个变量中,你从未将变量设置为false,这与从未设置变量为false不同。 - pvg
1
如果可以假定变量已经为false,那么它们是相同的。证明将涉及嵌套分支与逻辑运算符的等价性。 - RBarryYoung
2个回答

4
第二个代码片段与第一个几乎相同,但前提是你可以假设变量variable在未被设置的情况下初始化为false,这在一些编程语言中可能有效,但这可能是一个不好的想法,最好在调用此片段之前明确将其初始化为false
顺便提一下,使用逻辑运算符可以大大缩短整个表达式。
variable = !(condition1) && !(condition2);

或者可以说更加优雅的是:
variable = !(condition1 || condition2);

0

您的问题

这两个代码片段的结果在任何情况下都可能不同吗?

非常广泛,我可以想到至少四种情况,其中这两个代码片段的结果可能会有所不同。这是假设,正如其他人指出的那样,您的第二个示例是在以下初始化之前执行的:

variable = false

如果没有上述的初始化步骤,许多编程语言将创建未经自动初始化的变量,这意味着它的值是不确定的。

在介绍了四种情况之后,我将在最后展示一个证明,证明两个片段中的逻辑是相同的。

情况1:在评估条件时产生副作用

这可能会导致它们不同的第一种情况是,编程语言允许在评估条件时发生“副作用”。

例如,在C语言中,条件可能是赋值语句的结果,这可以改变正在测试的变量的状态。

考虑以下示例。如果我们在两个片段中都将变量初始化为false,并让条件1为((variable = !variable) == true),条件2为((variable = !variable) == false)(这具有更改变量值的副作用),则在以下C代码中:

bool variable1 = false;
if (((variable1 = !variable1) == true)) {
    variable1 = false;
}
else if (((variable1 = !variable1) == false)) {
    variable1 = false;
}
else {
    variable1 = true;
}

bool variable2 = false;
if (!((variable2 = !variable2) == true)) {
    if (!((variable2 = !variable2) == false)) {
        variable2 = true;
    }
}

结果将是variable1 == falsevariable2 == true,这展示了一个结果不同的情况。

情况2:重载赋值运算符

在C++语言中,赋值运算符(=)可以被重载,这意味着它的整个含义可以被改变成与它表面上不同的东西。因此,可以定义一个赋值运算符,其中

variable = false;

有时候会导致变量variable被赋值为false,但在某些条件下会导致变量variable实际上被赋值为true。这是一个奇怪的例子,但你的问题是:

这两个结果在任何情况下都可能不同吗?

所以我假设“任何情况”允许基本假设(例如variable = false实际上意味着variable = false)被搁置。很容易想象一种情况,其中赋值运算符可以被设计成导致这两种情况产生不同的结果。有人可能会认为我想得太离谱了,但在现实世界中,我们有像C++这样的语言,有时确实会表现出与人们预期不同的行为。
第三种情况:条件对时间敏感。
一个优化编译器可以将您的这两个代码片段都认为是等效的,并实际上将它们编译成相同的机器代码。大多数编译器可能会为这两个代码片段生成不同的机器代码。如果机器代码不同,则执行所需的时间在这两个代码片段之间可能会有所不同。如果条件2测试计时器的值,那么第一个片段中测试时计时器可能具有不同的值,这可能导致产生不同的决策,从而在variable中产生不同的结果。
第四种情况:多个线程
在使用抢占式多任务处理的程序中,有时程序员会忘记他们不再使用封闭系统。如果一个任务是一个线程,如果variable和/或组成条件1或条件2的元素在两个异步线程中可写访问,则可能会发生任一片段被另一个线程中断的情况,从而改变了正在评估或设置的变量的状态,导致出现不可预测的结果。
第五种情况:没有技巧
如果我们假设我们谈论的是一个静态封闭系统,没有像上面那样的意外,并且您真正想要的只是证明这两个代码片段在逻辑上是等效的,那么请创建一个考虑所有可能性的真值表:
         Inputs               Output
Condition 1  Condition 2    "variable"
-----------  -----------    ----------
   False        False          True
   False        True           False
   True         False          False
   True         True           False

如果你将这些输入通过你的两个代码片段运行,我相信你会发现两个片段都会产生上表中输出列中显示的相同结果。这将作为一个系统证明它们是相同的。

这个表格和你的两个代码片段恰好代表了一个 NOR 函数的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接