简体   繁体   English

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

[英]How to PROVE the precedence of '&&' and '||' by CODING in java?

I knew from somewhere that logical and: '&&' has a higher precedence than logical or: '||'我从某处知道逻辑和:'&&' 的优先级高于逻辑或:'||' in java.And while programming I rarely make mistakes on them.在 java.And 编程时,我很少在它们上犯错误。 But till now I didn't find any clue about how this precedence really act?但直到现在我还没有找到任何关于这种优先级究竟是如何起作用的线索? 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 would produce same results no matter the precedence of '&&' and '||', that is , 'false ||无论 '&&' 和 '||' 的优先级如何,上面的代码都会产生相同的结果,即 'false ||' false && true ||假 && 真 || false' results false no matter what the precedence are. false' 结果为 false,无论优先级如何。

So, in other words, I want a method or function, that could PROVE the precedence of '&&' and '||', it should produce different results depends on the precedence of '&&' and '||'... How could this function being made?Is it possible?所以,换句话说,我想要一个方法或函数,可以证明 '&&' 和 '||' 的优先级,它应该产生不同的结果取决于 '&&' 和 '||' 的优先级......如何这个功能可以做吗?可以吗? I guess it maybe a tough question or a dramatically simple one...may be it's not a java problem but something math... All in all, somebody help?我想这可能是一个棘手的问题,也可能是一个非常简单的问题……可能不是 Java 问题而是数学问题……总而言之,有人帮忙吗? Thanks.谢谢。

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? boolExp1等的哪些值会给我们不同的结果?

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.我不会首先使用“原样”的第一个表达式......因为除非你真的知道优先规则(我怀疑许多 Java 开发人员不知道 - 我不能发誓我会得到 &&和 || 对)你在黑暗中。 Better to make it explicit and clear where there's any doubt.最好在有任何疑问的地方说清楚。

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:要验证是否是这种情况,您可以生成abc所有组合,并比较这两个表达式的结果,看它们是否总是相等,即:

  1. For all combinations of a , b , and c对于abc所有组合
  2. Verify that: (a || b && c) == ((a || b) && c)验证: (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 ||因此, &&优先级高于|| . .

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 ||.所以在这个例子中很容易看出,在 Java 中,逻辑 && 比 || 具有更高的优先级。

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.如果您仅仅依赖于阅读示例代码和编写测试程序,您很可能会养成一些误解和坏习惯,而这些习惯会让您很难忘记。

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.所以除了测试,还要检查语言规范。

I was looking at the java specification to see if they defined operator precedence for && and ||我正在查看 java 规范,看看他们是否为&&||定义了运算符优先级

Both are defined as left-associative and no operator precedence is defined.两者都定义为左关联,并且没有定义运算符优先级。

See s.s。 15.7.3 a bit down from s. 15.7.3 比 s 低一点。 17.7 , && s. 17.7&& 15.23 , || 15.23|| s. s。 15.24 15.24

ie Java defines:即Java定义:

boolExp1 || boolExp2 && boolExp3 || boolExp4

As:作为:

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

This is relyed upon all the time in lines like the following.这在如下几行中一直依赖。

Clearly these examples would blow up if the first expression were not always evaluated and the second expression not evaluated conditionally.很明显,如果第一个表达式不总是被求值并且第二个表达式不是有条件地求值,那么这些例子就会失败。

// second expression on evaluated if text != null in both cases.
String text = ??
if (text != null && text.length() > 0) 

if (text == null || text.length() == 0
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

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但是现在让我更改 arg3() 以返回 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 ie所以总而言之..评估是从左到右进行的,即

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

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM