Как доказать приоритетность '&&' и '||' по кодированию в яве? - PullRequest
8 голосов
/ 14 декабря 2010

Я откуда-то знал, что логично, и: '&&' имеет более высокий приоритет, чем логический или: '||' в java. И во время программирования я редко допускаю в них ошибки. Но до сих пор я не нашел никакой подсказки о том, как этот прецедент действительно действует? Что бы произошло, если бы я не знал о приоритете двух и какую ошибку я бы сделал? Я пытался написать код, чтобы доказать приоритет '&&' и '||' но не удалось, например:

boolExp1 || boolExp2 && boolExp3 || boolExp4

приведенный выше код будет давать одинаковые результаты независимо от приоритета '&&' и '||', то есть 'ложь || false && true || false 'результаты false независимо от приоритета.

Итак, другими словами, я хочу метод или функцию, которые могли бы ДОКАЗАТЬ приоритет '&&' и '||', он должен давать разные результаты, в зависимости от приоритета '&&' и '||'. .. Как эта функция может быть выполнена? Возможно ли это? Я думаю, это может быть сложный вопрос или очень простой вопрос ... может быть, это не проблема Java, а что-то математическое ... В общем, кто-нибудь поможет? Спасибо.

Ответы [ 8 ]

17 голосов
/ 14 декабря 2010

Давайте возьмем пример выражения:

boolExp1 || boolExp2 && boolExp3 || boolExp4

Теперь мы считаем, что действует как:

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

право

Итак, давайте предположим, что напротив истинно, и на самом деле

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

Какие значения boolExp1 и т. Д. Дадут нам разные результаты?

Хорошо, давайте возьмем:

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

В соответствии с правилами "&& имеет более высокий приоритет" результат будет истинным. В соответствии с «|| имеет более высокие правила приоритета», результат будет ложным. Быстрый тест показывает, что выражение оценивается как истинное.

Конечно, это не доказывает, что && имеет более высокий приоритет, чем || - просто это || не имеет более высокого приоритета, чем &&. Мы могли бы рассмотреть, имеют ли они равный приоритет, - и проверить это аналогичным образом с другими выражениями ... найти образец выражения и значения, которые дали бы разные результаты при разных правилах приоритета, и проверить их.

В конечном счете, я предпочитаю:

  • Доверять спецификации, если у меня нет особых сомнений
  • Использование скобок, чтобы прояснить мои намерения

Во-первых, я бы не использовал первое выражение "как есть" ... потому что, если вы на самом деле не знаете правил приоритета (и я подозреваю, что многие разработчики Java не - я не смог клянусь, что я бы понял && и || правильно) ты в темноте. Лучше сделать это ясно и ясно, где есть какие-либо сомнения.

10 голосов
/ 20 мая 2015

Если && не имеет более высокого приоритета, чем ||, то это выражение:

a || b && c

будет оцениваться так:

(a || b) && c

Чтобы проверить, если этов этом случае или нет, вы можете сгенерировать все комбинации a, b и c и сравнить результат этих двух выражений, чтобы увидеть, всегда ли они равны или нет, то есть:

  1. Для всех комбинаций a, b и c
  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
   true || false  && false => true
  (true || false) && false => false
true true false
   true || true  && false => true
  (true || true) && false => false

Таким образом, && имеет более высокий приоритет, чем ||.

3 голосов
/ 18 сентября 2015

У меня тоже был такой же вопрос, но ответ мне практически давали.Вот мой пример:

true || true && false

эквивалентно

true || (true && false)

Так что в этом примере легко увидеть, что под капотом в Java логический && имеет более высокий приоритет, чем ||.

3 голосов
/ 14 декабря 2010

Вы не можете доказать ничего полезного в языке программирования, просто написав / выполнив примеры. Насколько вы знаете, компилятор может быть реализован так, чтобы компилировать код нелогичным, противоречивым или недетерминированным образом.

Даже если вы предполагаете детерминистическую компиляцию и детерминированное выполнение, единственное, что компилирует / запускает пример, это то, что этот конкретный пример демонстрирует определенное поведение. Вы не можете логически обобщать один пример в другой, потому что без ссылки на спецификацию компилятор является просто черным ящиком. (Ваш следующий пример может быть совершенно нелогичным.)

Правильный способ развить понимание языка программирования - это прочитать спецификацию языка, хороший учебник или хорошее руководство. Объедините это с написанием кода, чтобы подтвердить свое понимание.

Если вы полагаетесь исключительно на чтение примера кода и написание тестовых программ, вы можете обнаружить неверные представления и вредные привычки, которые могут быть болезненными, чтобы их не изучать.

3 голосов
/ 14 декабря 2010

Я смотрел на спецификацию java, чтобы увидеть, определили ли они приоритет оператора для && и ||

Оба определены как левоассоциативные, и приоритет оператора не определен.

См. с. 15.7.3 немного по сравнению с с. 17,7 , && с. 15,23 , || с. 15,24

т.е. Java определяет:

boolExp1 || boolExp2 && boolExp3 || boolExp4

В

((((boolExp1) || boolExp2) && boolExp3) || boolExp4)
1 голос
/ 20 сентября 2015

Простой тест:

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.");
    }
}

Обратите внимание, что это объясняет возможность того, что && и || могут иметь равный приоритет, а затем, в этом случае, определяет, выполняются ли они слева направо или справа налево.

К сожалению, это не учитывает приоритет, который изменяется или прецедент, основанный изнутри наружу или снаружи внутрь, или многие другие возможные порядки работы, не говоря уже о том, что он может быть побежден злонамеренными или сломанными компиляторами, вредоносными или сломанными компьютерами и космические лучи.

В любом случае, действительно трудно доказать, что ваш компилятор / компьютер / вселенная не связывается с вами. Поэтому проверьте спецификацию языка в дополнение к тестированию.

0 голосов
/ 04 октября 2017

И &&, и || имеют одинаковый приоритет, оценка происходит слева направо. Позвольте мне объяснить на примере.

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 

Надеюсь, это поможет.

0 голосов
/ 14 декабря 2010

Это все время полагается на строки, подобные следующим.

Очевидно, что эти примеры взорвались бы, если бы первое выражение не всегда оценивалось, а второе выражение не оценивалось условно.

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

if (text == null || text.length() == 0
...