我正在查看合作伙伴的代码,我发现了这个IF声明。
if (((x == 0) && (y == 0)) || y == 0) {
do something
}
如果我错了,请纠正我,但这不是IF冗余的第一部分吗?
答案 0 :(得分:7)
使用真值表:
╔════════╦════════╦══════════════════════════════════╗ ║ x == 0 ║ y == 0 ║ ((x == 0) && (y == 0)) || y == 0 ║ ╠════════╬════════╬══════════════════════════════════╣ ║ 0 ║ 0 ║ 0 ║ ║ 0 ║ 1 ║ 1 ║ ║ 1 ║ 0 ║ 0 ║ ║ 1 ║ 1 ║ 1 ║ ╚════════╩════════╩══════════════════════════════════╝
显然,x == 0
部分无关紧要,你拥有的部分相当于
if (y == 0) {
...
}
答案 1 :(得分:3)
是的,在这种情况下它是多余的,因为没有一个条件有副作用,如果第一部分是真的,第二部分是真的。
但是,如果声明中存在副作用,那么由于短路情况并非总是如此:
if( (doX() == 0 && doY() == 0) || doY() == 0 ) { ... }
在这种情况下,如果doX()
未返回0,则&&
的右侧将不会被评估,因此doY()
将仅执行一次。当doX()
返回0且第一个doY()
未返回0时,doY()
将执行两次。
答案 2 :(得分:1)
你是对的,它等同于
if (y == 0) {
//do something
}
您可以绘制可能的作业表。我使用1表示任何不是0的整数。
x y (((x == 0) && (y == 0)) || y == 0)
- - ----------------------------------
0 0 True
0 1 False
1 0 True
1 1 False
只有当y = 0时,整个表达式才会计算为True,所以你也可以将它重构为(y == 0)
答案 3 :(得分:0)
是的,第一部分是多余的。如果||
为true
,则第二部分(y
之后)将返回0
,而不管x's
值。这种情况可以简化为
if (y == 0) {
doSomething();
}
顺便说一下,值得注意的是,任何一半不太好的IDE会警告你这种冗余,或者至少可以配置这样做。如果您没有收到此类警告,最好检查IDE的设置。
答案 4 :(得分:0)
第一部分((x == 0)&&(y == 0))只有在双方都为真时才返回true。如果 y == 0 ,则后半部分为真。此if语句仅在x == 0时排除执行,但允许y等于0,无论x是否等于0.
答案 5 :(得分:0)
我建议使用unit test
。
boolean isIt(int x, int y) {
if (((x == 0) && (y == 0)) || y == 0) {
return true;
}
return false;
}
@Test
public void test1() {
boolean result = isIt(1, 0);
assertTrue(result);
}
@Test
public void test1() {
boolean result = isIt(0, 0);
assertTrue(result);
}
然后,在您运行测试并意识到if
的第一部分没有必要之后,您可以将其删除并再次运行测试以检查您是否正确。
答案 6 :(得分:0)
我们假设
a : x == 0
b : y == 0
c : a && b
d : (a && b) || b
所以a,b,c和d的真值表如下所示。
a | b | c | d |
----------------
0 | 0 | 0 | 0
----------------
0 | 1 | 0 | 1
----------------
1 | 0 | 0 | 0
----------------
1 | 1 | 1 | 1
从表中可以轻松判断出来。我通常只是使用卡诺的地图中的缩小表达式。如果你们能做到这一点,那么就不会浪费时间来争论。