当前位置: 首页 > 知识库问答 >
问题:

Java语言中逻辑运算顺序混乱

边意
2023-03-14

我有一个小测验中的操作顺序问题,解释并没有什么帮助。代码如下:

package com.udayan.oca;

public class Test {
     public static void main(String [] args) {
         int a = 2;
         boolean res = false;
         res = a++ == 2 || --a == 2 && --a == 2;
         System.out.println(a);
     }
}

它说它打印了3个,因为我测试过,但我不明白怎么做。以下是他们的解释:

a++ == 2 || --a == 2 && --a == 2;

[给定表达式].(a)==2||--a==2

[后缀的优先级高于其他运算符]。

(a++) == 2 || (--a) == 2 && (--a) == 2;

[后缀后,前缀优先]。

((a++) == 2) || ((--a) == 2) && ((--a) == 2);

[==的优先级高于

((a++) == 2) || (((--a) == 2) && ((--a) == 2));

[

让我们开始解决它:((a)==2) || (((--a)==2)

[a=2,res=false]。

(2 == 2) || (((--a) == 2) && ((--a) == 2));

[a=3,res=false]<代码>真| |(((-a)==2)

[a=3,res=false]。

||是短路运算符,因此不需要计算右侧的表达式。

res为真,a为3。

是的,顺便说一句,我理解短路,所以不需要解释。

然而,我的想法是:

res = a++ == 2 || --a == 2 && --a == 2 ->
(((a++) == 2) || (((--a) == 2) && ((--a) == 2))) [a = 2]

(((a++) == 2) || ((**1** == 2) && ((--a) == 2))) [a = 1]

(((a++) == 2) || (**false** && (**0** == 2))) [a = 1] //short-circuits

(((a++) == 2) || **false**) [a = 1] //short circuits

(**false**) [a = 1]

???? 另一点是答案键说先做一个,然后再做下一个。是啊,这很有道理。但是我想


共有3个答案

谭昊乾
2023-03-14

最后当((a)=2)| | false)[a=1]完成时,作为| |运算符的优先级比这里的低,a将变为3。。然后它将打印a=3,尽管它是一个短路操作员,但它必须先执行操作员。

邢修明
2023-03-14
res = a++ == 2 || --a == 2 && --a == 2 (res is true)

1. a++ (post-increment, no) -> a = a + 1 -> it's still 2 -> when true -> it becomes 3
2. --a (pre-increment, right to left) -> a - 1 = a -> 1
3. --a (pre-increment, right to left) -> a - 1 = a -> 0 (its because of logical and, it never execute this part) 
4. == (equality, left to right) -> 2 == 2 || 1 == 2 && 0 == 2 -> true || false && false
5. && (logical and, left to right) -> false -> no more steps 
6. || (logical or, left to right) -> true -> go to 1.

// so take 3
// moral of the story is always use paranthesis
// op is correct for short-circuit 
茹照
2023-03-14

根据Java语言规范,

条件or运算符| |运算符类似于|(§15.22.2),但仅当其左侧操作数的值为false时才计算其右侧操作数

所以,这比你想象的要简单。res=a==2||--a==2

res = ((a++ == 2) || ((--a == 2) && (--a == 2)));

a==2?后增量表示a读作2。然后计算该表达式。2==2,这是true。短路意味着表达式的其余部分永远不会被计算。

所以,基本上上面的所有代码都是res=a==2;

我做了一个简单的程序来测试这个:

public class TestSOCode {
    public static void main(String [] args) {
        test1();
    }

    private static void test1(){
        int a = 2;
        boolean res = false;
        //res = a++ == 2 || --a == 2 && --a == 2;
        res = expression(a++, "One") || expression(--a, "Two") && expression(--a, "Three");
        System.out.println(res +" "+ a);
    }

    private static boolean expression(int i, String s){
        System.out.println(s+ " called with "+ i);
        return i == 2;
    }
}

这就是结果

One called with 2
true 3

更新:经过一些讨论和研究,我认为在逻辑运算符方面,对优先级和执行顺序之间的区别存在误解。

res = a++ == 2 || --a == 2 && --a == 2;

上述语句的优先级是在对其进行计算之前计算出来的。我将不讨论其他优先规则,因为它会使这个答案复杂化,所以我将简化它:

res = x || y && z;
res = x || (y && z);

如我们所见,

 res = expression(a = 8, "One") || expression(a = 16, "Two") && expression(a = 32, "Three");

这相当于false | |(false

One called with 8
Two called with 16
false 16

首先计算||,然后计算的左侧

 类似资料:
  • 主要内容:逻辑运算的结果,优先级现在假设有这样一种情况,我们的软件比较特殊,要求使用者必须成年,并且成绩大于等于60,该怎么办呢? 或许你会想到使用嵌套的 if 语句,类似下面这样的代码: 这种方法虽然能够行得通,但不够简洁和专业,我们可以将其压缩为一条 if else 语句: 是一个新的运算符,称为 逻辑运算符,表示 和 两个条件必须同时成立才能执行 if 后面的代码,否则就执行 else 后面的代码。 在高中数学中,我们就学

  • 在之前的 C 语言标准中,逻辑运算符是表示两个数值之间逻辑关系的运算符。通常用 0 和 1 来表示假值和真值。但是在 C 语言中会认为非 0 的数值在逻辑运算中都为 1 。逻辑运算的返回值也是整数型,不是 0 就是 1 ,这点和其他很多编程语言是不同的。 但是,在 C99 标准中引入了布尔类型。所以 C 语言中的逻辑运算就简单了很多。要想使用布尔类型,需要引入 stdbool.h 这个库即可。但是

  • 指针逻辑运算符操作 指针变量存储的是一个地址,可以将它理解成一个数值。只是编译器会因为它是一个指针类型而将它读取作为一个地址。逻辑运算符包括>=,<=,==,!=;显然我们比较两个地址的数值的大小是没有意义的。 指针中最常用的逻辑操作符==,!=这两个是最常用的。 我们将0x0规定为地址的无效值,结束标志。NULL就是一个在C编译器中一个被定义好了的宏,它代表了这个无效地址。我们经常使用p==NU

  • 逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。 逻辑运算符是对布尔型变量进行运算,其结果也是布尔型,具体如表 1 所示。 表 1 逻辑运算符的用法、含义及实例 运算符 用法 含义 说明 实例 结果 && a&&b 短路与 ab 全为 true 时,计算结果为 true,否则为 false。 2>1&&3<4

  • 问题内容: 运算符和有什么不一样?和运算符|| ?? 而且&和&& ??有什么区别? 谢谢… 问题答案: 主要区别在于,在表达式中,如果为false,则不会进行计算,而在两者中,无论如何都将进行计算。可以说是“ 短路 ”评估。 同样,对于:如果为true,则不会进行评估,而对于两者而言,则无论如何都将被评估。

  • and, or, not 其中,and 和 or 与 C 语言区别特别大。 在这里,请先记住,在 Lua 中,只有 false 和 nil 才计算为 false,其它任何数据都计算为 true,0 也是 true! and 和 or 的运算结果不是 true 和 false,而是和它的两个操作数相关。 a and b: 如果 a 为 false,则返回 a;否则返回 b a or b: 如果 a