这里有逻辑漏洞吗?

时间:2016-01-11 17:36:33

标签: logic computer-science boolean-logic

我需要执行一段像这样的代码

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
   }
 }

这两者的结果在任何情况下都有所不同吗?有没有系统的证据呢?

2 个答案:

答案 0 :(得分:4)

第二个片段几乎等同于第一个片段 - 如果您可以假设variable初始化为false,除非另有设置,这可能适用于某些编程语言,但可能很糟糕想法,最好在调用此代码段之前将其初始化为false

顺便说一句,请注意,使用逻辑运算符可以大大缩短整个表达式:

variable = !(condition1) && !(condition2);

或者说更优雅:

variable = !(condition1 || condition2);

答案 1 :(得分:0)

你的问题

  

这两者的结果在任何情况下都有所不同吗?

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

variable = false

如果没有上面的初始化步骤,许多编程语言会创建variable而不会自动初始化它,这意味着它的值是不确定的。

在介绍这四个案例之后,我将在最后展示一个证据,证明两个片段中的逻辑是相同的。

案例1:评估条件时的副作用

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

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

考虑以下示例。如果我们在两个片段中初始化variablefalse,则让条件1为((variable = !variable) == true),条件2为((variable = !variable) == false)(其副作用是更改{{1}的值1}}),然后在下面的C代码中:

variable

结果将是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 == false,这表明结果不同的情况。

案例2:重载赋值运算符

在C ++语言中,赋值运算符(variable2 == true)可以重载,这意味着它的整个含义可以更改为与其显示的不同。因此可以定义一个赋值运算符

=

有时会为variable = false; 分配值variable,但在某些情况下会导致false实际分配值variable。这是一个奇怪的例子,但你的问题是

  

这两者的结果在任何情况下都有所不同吗?

所以在这里我假设“任何情况”允许基本假设(例如true真正意味着variable = false)可以被搁置。不难想象可以设计赋值运算符以使两个案例产生不同结果的场景。有人可能会说,在这里,我的思路太远了,但在现实世界中,我们使用C ++这样的语言,有时候的行为确实与人们预期的不同。

案例3:条件是时间敏感的

给定的优化编译器可能会认为您的两个片段都是等效的,并且可能实际上将它们编译为相同的机器代码。大多数编译器可能更有可能为这两个片段生成不同的机器代码。如果机器代码不同,则两个片段之间的执行时间可能不同。如果条件2测试计时器的值,则计时器在第一个片段中的测试时可能具有与第二个片段中不同的值,这可能会产生不同的决定,从而产生不同的结果variable = false

案例4:多个线程

在采用抢先式多任务处理的程序中,有时程序员会忘记他们不再在封闭系统中工作。如果一个任务是一个线程,并且variable和/或构成条件1或条件2的元素在两个异步线程中是可写的,那么任何一个片段都可能被另一个线程中断,更改正在评估或设置的变量的状态,从而导致不可预测的结果。

案例5:没有技巧

如果我们假设我们正在谈论一个没有上述意外的封闭静态系统,并且你真正想要的只是一个简单的证据,证明两个片段在逻辑上是等价的,那么考虑所有可能性创建一个真值表:

variable

如果您通过两个代码段运行这些输入,我相信您会发现两个代码段都会产生上表中“输出”列中显示的相同结果。这可以作为两者相同的系统证据。

此表和您的两个代码段恰好代表 Inputs Output Condition 1 Condition 2 "variable" ----------- ----------- ---------- False False True False True False True False False True True False 函数的行为。