如何证明 '&&' 的优先级和'||'通过Java编码?

发布于 2024-10-07 04:31:31 字数 609 浏览 3 评论 0原文

我从某个地方知道逻辑 AND: && 在 Java 中比逻辑 OR: || 具有更高的优先级,但到目前为止我还没有找到任何线索这种优先级实际上是如何发挥作用的。如果我不知道两者的优先顺序会发生什么,我会犯什么错误? 我尝试编写一些代码来证明 &&|| 的优先级,但失败了,例如:

boolExp1 || boolExp2 && boolExp3 || boolExp4

无论优先级如何,上面的代码都会产生相同的结果&&||,即,

false || false && true || false

无论优先级如何,都会导致 false

我想要一个可以证明 &&|| 优先级的方法或函数。它应该根据 &&|| 的优先级产生不同的结果。是否可以?

I know from somewhere that logical AND: && has a higher precedence than logical OR: || in Java, but until now I haven't found any clue about how this precedence really acts. What would happen if I didn't know about the precedence of the two and what mistake would I make?
I tried to write some code to PROVE the precedence of && and || but failed, for example:

boolExp1 || boolExp2 && boolExp3 || boolExp4

The code above produces the same results no matter the precedence of && and ||, that is,

false || false && true || false

results in false no matter what the precedence is.

I want a method or function that can PROVE the precedence of && and ||. It should produce different results depending on the precedence of && and ||. Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

不…忘初心 2024-10-14 04:31:31

让我们以您的示例表达式为例:

boolExp1 || boolExp2 && boolExp3 || boolExp4

现在我们认为它的作用是:

boolExp1 || (boolExp2 && boolExp3) || boolExp4

对吗?

因此,让我们假设相反的情况为真,实际上是

(boolExp1 || boolExp2) && (boolExp3 || boolExp4)

boolExp1 等的哪些值会给我们不同的结果?

好吧,让我们假设:

boolExp1 = true
boolExp2 = false
boolExp3 = false
boolExp4 = false

在“&&具有更高的优先级”规则下,结果将是正确的。在“||具有更高优先级规则”下,结果将是错误的。然而,快速测试表明该表达式的计算结果为 true。

当然,这实际上并不能证明 &&优先级高于|| - 仅此||没有比 && 更高的优先级。我们可以考虑它们是否具有相等优先级 - 并以类似的方式用其他表达式进行测试...找到一个示例表达式和值,它们在不同的优先级规则下会给出不同的结果,并测试它们。

但最终,我更喜欢:

  • 相信规范,除非我有具体疑问
  • 使用括号来明确我的意图

我不会首先使用第一个表达式“按原样”...因为除非您实际上知道 优先规则(我怀疑许多 Java 开发人员不这样做 - 我不能发誓我会得到 && 和 || 正确的)你一无所知。最好把有任何疑问的地方说清楚。

Let's take your example expression:

boolExp1 || boolExp2 && boolExp3 || boolExp4

Now we believe that acts as:

boolExp1 || (boolExp2 && boolExp3) || boolExp4

right?

So let's suppose the opposite is true, and it's actually

(boolExp1 || boolExp2) && (boolExp3 || boolExp4)

What values of boolExp1 etc would give us different results?

Well, let's take:

boolExp1 = true
boolExp2 = false
boolExp3 = false
boolExp4 = false

Under the "&& has higher precedence" rules, the result would be true. Under the "|| has higher precedence rules", the result would be false. A quick test shows that the expression evaluates to true, however.

Of course, this doesn't actually prove that && has higher precedence than || - merely that || doesn't have higher precedence than &&. We could consider whether they have equal precedence - and test that with other expressions in a similar way... find a sample expression and values which would give different results under different precedence rules, and test them.

Ultimately though, I prefer:

  • To trust the spec unless I have specific doubts
  • To use parentheses to make my intentions clear

I wouldn't use the first expression "as is" in the first place... because unless you actually know the precedence rules (and I suspect many Java devs don't - I couldn't swear that I'd have got && and || right) you're in the dark. Better to make it explicit and clear where there's any doubt.

悸初 2024-10-14 04:31:31

如果 && 的优先级不高于 ||,则此表达式:

a || b && c

将按如下方式求值:

(a || b) && c

要验证是否是这种情况,
您可以生成 abc 的所有组合,
并比较这两个表达式的结果,
查看它们是否始终相等,即:

  1. 对于 abc 的所有组合
  2. 验证:(a || b && c) == ((a || b) && c)

示例代码:

for (int i = 0; i < 8; ++i) {
    boolean a = ((i >> 2) & 1) == 1;
    boolean b = ((i >> 1) & 1) == 1;
    boolean c = (i & 1) == 1;
    boolean x1 = (a || b && c);
    boolean x2 = ((a || b) && c);

    if (x1 != x2) {
        System.out.println(String.format("%s %s %s", a, b, c));
        System.out.println(String.format("   %s || %s  && %s => %s", a, b, c, x1));
        System.out.println(String.format("  (%s || %s) && %s => %s", a, b, c, x2));
    }
}

输出:

true false false
   真实 ||假&&假=>真的
  (真 || 假)&&假=>错误的
真 真 假
   真实 ||真&&假=>真的
  (真 || 真)&&假=>错误的

因此,&& 的优先级高于 ||

If && didn't have higher precedence than ||, then this expression:

a || b && c

would be evaluated like this:

(a || b) && c

To verify if this is the case or not,
you can generate all combinations of a, b, and c,
and compare the result of these two expressions,
to see if they are always equal or not, that is:

  1. For all combinations of a, b, and c
  2. Verify that: (a || b && c) == ((a || b) && c)

Sample code:

for (int i = 0; i < 8; ++i) {
    boolean a = ((i >> 2) & 1) == 1;
    boolean b = ((i >> 1) & 1) == 1;
    boolean c = (i & 1) == 1;
    boolean x1 = (a || b && c);
    boolean x2 = ((a || b) && c);

    if (x1 != x2) {
        System.out.println(String.format("%s %s %s", a, b, c));
        System.out.println(String.format("   %s || %s  && %s => %s", a, b, c, x1));
        System.out.println(String.format("  (%s || %s) && %s => %s", a, b, c, x2));
    }
}

The output:

true false false
   true || false  && false => true
  (true || false) && false => false
true true false
   true || true  && false => true
  (true || true) && false => false

As such, && has higher precedence than ||.

甜心 2024-10-14 04:31:31

我也有同样的问题,但答案实际上已经给了我。
这是我的示例:

true || true && false

相当于

true || (true && false)

所以通过这个示例,很容易看出 Java 中的逻辑 &&优先级高于||。

I too had this same question but the answer was practically giving to me.
Here is my example:

true || true && false

is equivalent to

true || (true && false)

So with this example it is easy to see that under the hood in Java the logical && has a higher precedence than ||.

各自安好 2024-10-14 04:31:31

仅通过编写/运行示例无法证明编程语言的任何有用之处。据您所知,编译器可能会以不合逻辑、不一致或不确定的方式编译代码。

即使您假设确定性编译和确定性执行,编译/运行示例唯一能证明的是该特定示例表现出特定行为。您无法在逻辑上从一个示例推广到另一个示例,因为如果不参考规范,编译器只是一个黑匣子。 (您的下一个示例可能是以完全反直觉的方式处理的。)

理解编程语言的正确方法是阅读语言规范、一本好的教科书或一个好的教程。将其与编写代码结合起来以确认您的理解。

如果您仅仅依赖于阅读示例代码和编写测试程序,您很可能会产生误解,并养成很难改掉的坏习惯。

You cannot prove anything useful about a programming language by just writing / running examples. For all you know, the compiler might be implemented so as to compile code in an illogical, inconsistent or non-deterministic fashion.

Even if you assume deterministic compilation and deterministic execution, the only thing that compiling / running an example proves is that that particular example exhibits a particular behavior. You cannot logically generalize from one example to another one, because without reference to a specification the compiler is just a black box. (Your very next example could be the one that is handled in a totally counter-intuitive fashion.)

The correct way to develop an understanding of a programming language is to read the language specification, a good textbook or a good tutorial. Combine this with writing code to confirm your understanding.

If you rely solely on reading example code and writing test programs, you are liable to pick up misconceptions, and bad habits that can be painful to unlearn.

笛声青案梦长安 2024-10-14 04:31:31

我正在查看java规范,看看他们是否为 &&|| 定义了运算符优先级,

两者都被定义为左关联,并且没有定义运算符优先级。

请参阅。 15.7.3 比 s 稍低一些。 17.7,
&& 。 15.23,
|| s。 15.24

即 Java 定义:

boolExp1 || boolExp2 && boolExp3 || boolExp4

为:

((((boolExp1) || boolExp2) && boolExp3) || boolExp4)

I was looking at the java specification to see if they defined operator precedence for && and ||

Both are defined as left-associative and no operator precedence is defined.

See s. 15.7.3 a bit down from s. 17.7,
&& s. 15.23,
|| s. 15.24

i.e. Java defines:

boolExp1 || boolExp2 && boolExp3 || boolExp4

As:

((((boolExp1) || boolExp2) && boolExp3) || boolExp4)
冧九 2024-10-14 04:31:31

一个简单的测试是:

boolean a = true || false && false;
boolean b = false && false || true;

if (a == b) { // different precedence
    if (a == true) {
        System.out.println("&& has higher precedence than ||");
    } else { // a == false
        System.out.println("|| has higher precedence than &&");
    }
} else { // a != b, same precedence
    if (a == true) { // and b == false
        System.out.println("&& and || have equal precedence, and are executed right to left.");
    } else { // a == false, b == true
        System.out.println("&& and || have equal precedence, and are executed left to right.");
    }
}

请注意,这考虑了 &&|| 可能具有相同优先级的可能性,然后在这种情况下确定它们是否'从左到右或从右到左重新执行。

不幸的是,这并没有考虑到基于从内到外或从外到内的更改或优先级,或许多其他可能的操作顺序,更不用说它可能被恶意或损坏的编译器、恶意或损坏的计算机和宇宙所击败。射线。

不管怎样,要证明你的编译器/计算机/宇宙没有扰乱你真的很困难。因此除了测试之外还要检查语言规范。

A simple test is:

boolean a = true || false && false;
boolean b = false && false || true;

if (a == b) { // different precedence
    if (a == true) {
        System.out.println("&& has higher precedence than ||");
    } else { // a == false
        System.out.println("|| has higher precedence than &&");
    }
} else { // a != b, same precedence
    if (a == true) { // and b == false
        System.out.println("&& and || have equal precedence, and are executed right to left.");
    } else { // a == false, b == true
        System.out.println("&& and || have equal precedence, and are executed left to right.");
    }
}

Note that this accounts for the possibility that && and || could have equal precedence, and then, in that case, determines if they're executed left to right, or right to left.

Unfortunately, this does not account for precedence that changes or precedence based on inside to outside or outside to inside, or many other possible orders of operation, not to mention it can be defeated by malicious or broken compilers, malicious or broken computers, and cosmic rays.

Anyway, it's really hard to prove your compiler/computer/universe isn't messing with you. So check the language specification in addition to testing.

似最初 2024-10-14 04:31:31
public static void main(String[] args) {
    
    boolean res = b(false,1) || b(true,2) && b(false,3) || b(false,4);
    System.out.println(res);
}   
static boolean b(boolean b, int i){
    System.out.println(i);
    return b;
}
// 1 2 3 4 false
public static void main(String[] args) {
    
    boolean res = b(false,1) || b(true,2) && b(false,3) || b(false,4);
    System.out.println(res);
}   
static boolean b(boolean b, int i){
    System.out.println(i);
    return b;
}
// 1 2 3 4 false
你的呼吸 2024-10-14 04:31:31

两者 &&和 ||具有相同的优先级,评估从左到右进行。让我用一个例子来解释一下。

public static void main(String[] args) {

    System.out.println("Result = " + (arg1() || arg2() && arg3() || arg4()));
}

private static boolean arg1() {
    System.out.println("arg1");
    return false;
}

private static boolean arg2() {
    System.out.println("arg2");
    return true;
}

private static boolean arg3() {
    System.out.println("arg3");
    return true;
}

private static boolean arg4() {
    System.out.println("arg4");
    return false;
}

其计算结果为:-

arg1
arg2
arg3
Result = true

但现在让我更改 arg3() 以返回 false

private static boolean arg3() {
    System.out.println("arg3");
    return false;
}

这会导致:-

arg1
arg2
arg3
arg4
Result = false

因此得出结论.. 评估从左到右进行,即

arg1 || arg2 && arg3 || arg4
   output    && arg3 || arg4
           output    || arg4
                   output 

希望这会有所帮助。

Both && and || have the same precedence, Evaluation happens from left to right. Let me explain with an example.

public static void main(String[] args) {

    System.out.println("Result = " + (arg1() || arg2() && arg3() || arg4()));
}

private static boolean arg1() {
    System.out.println("arg1");
    return false;
}

private static boolean arg2() {
    System.out.println("arg2");
    return true;
}

private static boolean arg3() {
    System.out.println("arg3");
    return true;
}

private static boolean arg4() {
    System.out.println("arg4");
    return false;
}

this evaluates to :-

arg1
arg2
arg3
Result = true

But now let me change arg3() to return false

private static boolean arg3() {
    System.out.println("arg3");
    return false;
}

this results in :-

arg1
arg2
arg3
arg4
Result = false

So to conclude.. the evaluation takes place form left to right i.e

arg1 || arg2 && arg3 || arg4
   output    && arg3 || arg4
           output    || arg4
                   output 

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文