短路评估和前缀增量运算符的顺序

时间:2018-04-03 23:15:32

标签: java boolean logic

在java中评估布尔表达式时,我发现自己对短路评估和预修复增量运算符感到有些困惑。请考虑以下事项:

    int e=20;
    int f=25;
    if(++e>21 || ++e>21 && f>30){

        System.out.println("Hi");
    }
    System.out.println(e);

据我所知,如果++ e大于21,则IF语句的其余部分将跳过(由于短路eval)。但在这种情况下,它不会,因为第一部分不是真的,所以我们继续讨论AND语句。此时,还是20?或者在短路评估期间,它是否达到了21?

好吧,我假设在这一点上,我们评估AND语句(正如我们通常在OR之前做的那样),我们将e加1,我假设现在变为21?它是错误的,因此整个AND语句都是错误的。

此时,我们是否返回并执行OR语句?既然AND之后呢?现在不应该抽到22?因为它是一个OR语句,它应该是TRUE或FALSE,它应该是TRUE,并且“Hi”应该出现在屏幕上。但事实并非如此。

奇怪的是,当代码完成时,e的值为22。 22是IF语句为真所需的值,但内部条件没有运行。

我非常困惑。

1 个答案:

答案 0 :(得分:6)

让我们放松实际的短路!

int e=20;
int f=25;
if((++e>21) || (++e>21 && f>30)){

    System.out.println("Hi");
}
System.out.println(e);

所以,如果or条件的左侧评估为真,我们不需要再做任何事情了,所以让我们更明确一点:

int e=20;
int f=25;
if (++e > 21)
{
    System.out.println("Hi");
}
// the or becomes an else if, if the first condition fails then we check the second
else if (++e>21 && f>30)
{
    System.out.println("Hi");
}
System.out.println(e);

现在,让我们更明确一下第一次增量的发生时间:

int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
    System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e>21 && f>30)
{
    System.out.println("Hi");
}
System.out.println(e);

再次,让我们展开and在短路方面的含义

int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
    System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e > 21) // the and becomes a nested if, first the left must be true before we test the right
{
    if (f > 30)
    {
        System.out.println("Hi");
    }
}
System.out.println(e);

再次,让我们明确一下这个增量!

int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
    System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else 
{
    e += 1;
    if (e > 21) // e is now 22, this condition succeeds
    {
        if (f > 30) // f is not >30, this condition fails!
        {
            System.out.println("Hi");
        }
    }
    // e is still 22
}
// e is still 22
System.out.println(e);

希望这一切都清楚了!

编辑:实际上,重复阅读你的问题几次,看起来你对逻辑运算符的优先级感到困惑。您似乎认为and应该在or权利之前执行?大概是因为and具有更高的优先权。然而,所有这些意味着隐含括号首先围绕and,如此;

p || q && r == p || (q && r)

您应该能够看到,在此表单中,必须先在or之前评估外部and。我们总是从左到右评价!