我写逻辑AND语句的方式是否与写逻辑OR语句将C转换为mips程序集的方式相同?
else if (i == x && j == y) printf("%c", 219);
这是我写的
bne $reg1, $t3, draw219 # i==x bne $reg2, $t4, draw219 # j==y
xghobddn1#
你不小心颠倒了你的逻辑。我假设“draw219”是一段等价于你的C代码printf("%c", 219);的代码。bne指令不应该在那里分支,因为它们只在两个寄存器不相等的情况下分支。当两个寄存器不相等时,整个if条件为假,所以你应该分支到下一个你想执行的代码块。但不要转到“draw219”。
printf("%c", 219);
bne
if
rkue9o1l2#
我们将根据需要使用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
而且这两条线很容易组装。作为另一种方法,我们可以将&&转换为&,因此,我们可以计算两个操作数,并简单地将结果一起计算and,然后使用单个分支指令进行测试,而不是实现短路运算符。而X1 M5 N1 X可以用X1 M6 N1 X代替。只有在代码允许的情况下,将短路运算符转换为非短路运算符才有效,这意味着程序必须始终执行/执行/计算第二个操作数。函数调用或数组引用不一定可以执行,因为它受到第一个条件的保护。下面是一个示例:当不能转换短路操作器时:
&
and
if ( i < N && a[i] == 0 ) ...
数组引用由使用短路运算符的范围检查保护/保护,因此如果将其转换为&,有时会导致数组引用超出边界,无法计算&&的两侧。第二个操作数中的函数调用对于此转换也可能存在问题。
2条答案
按热度按时间xghobddn1#
你不小心颠倒了你的逻辑。我假设“draw219”是一段等价于你的C代码
printf("%c", 219);
的代码。bne
指令不应该在那里分支,因为它们只在两个寄存器不相等的情况下分支。当两个寄存器不相等时,整个if
条件为假,所以你应该分支到下一个你想执行的代码块。但不要转到“draw219”。rkue9o1l2#
我们将根据需要使用deMorgan来转换:
结构化if-then-else语句中的复合条件:
在if-goto-label形式中,条件被否定,同时分支也指向else部分,所以这两个变化一起,它仍然运行相同的(它实际上是双重否定,所以逻辑相同):
通过对
&&
的操作数取反并更改为||
,可以在合取中分配取反。德·摩尔根对否定条件的应用:
然后优化否定关系:
这可以分为两个if语句:
而且这两条线很容易组装。
作为另一种方法,我们可以将
&&
转换为&
,因此,我们可以计算两个操作数,并简单地将结果一起计算and
,然后使用单个分支指令进行测试,而不是实现短路运算符。而X1 M5 N1 X可以用X1 M6 N1 X代替。只有在代码允许的情况下,将短路运算符转换为非短路运算符才有效,这意味着程序必须始终执行/执行/计算第二个操作数。函数调用或数组引用不一定可以执行,因为它受到第一个条件的保护。下面是一个示例:当不能转换短路操作器时:
数组引用由使用短路运算符的范围检查保护/保护,因此如果将其转换为
&
,有时会导致数组引用超出边界,无法计算&&
的两侧。第二个操作数中的函数调用对于此转换也可能存在问题。