我们将根据需要使用 deMorgan 进行转换:
结构化 if-then-else 语句中的复合条件:
...
if ( i == x && j == y ) {
<then-part>
}
else {
<else-part>
}
...
在 if-goto-label 形式中,条件被否定,同时分支也指向 else 部分,因此将这两个更改放在一起,它仍然运行相同(它实际上是双重否定,因此相同的逻辑):
...
if ( ! (i == x && j == y) ) goto else1Part;
then1Part:
<then-part>
goto endIf1;
else1Part:
<else-part>
endIf1:
...
否定可以通过对操作数取反来分布在合取上&&
并更改为||
.
德摩根在否定条件上的应用:
if ( ! (i == x) || ! (j == y) ) goto else1Part;
然后优化关系的否定:
if ( i != x || j != y ) goto else1Part;
这可以分为两个 if 语句:
if ( i != x ) goto else1Part;
if ( j != y ) goto else1Part;
// will come here when the original if condition is true
这两条线很容易组装。
我们可以转换&&
to &
作为另一种方法,我们可以评估两个操作数,然后简单地实现,而不是实现短路运算符and
将结果放在一起并使用单分支指令进行测试。德摩根也可以应用;尽管||
可以替换为|
.
仅当代码允许时,将短路运算符转换为非短路运算符才有效,这意味着程序必须始终执行/执行/评估第二个操作数。如果函数调用或数组引用受到第一个条件的保护,则不一定可以执行。这是一个不能转换短路运算符的示例:
if ( i < N && a[i] == 0 ) ...
数组引用受到使用短路运算符的范围检查的保护/保护,因此有时会导致数组引用超出范围以评估两侧&&
如果它被转换为&
.
对于此转换,第二个操作数中的函数调用也可能会出现问题。