Почему выходные данные отличаются в случае &&, &, ||?

Вот сегменты кода

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

1) Выход

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t && ((i++) == 0));
        b = (f && ((i+=2) > 0));
        System.out.println(i);      
    }
}

в этом случае равен 1

2) Выход

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t & ((i++) == 0));
        b = (f & ((i+=2) > 0));
        System.out.println(i);      
    }
}

в этом случае равен 3

3 ) Выход

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t || ((i++) == 0));
        b = (f || ((i+=2) > 0));
        System.out.println(i);      
    }
}

в этом случае равен 2

4) Выход

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t | ((i++) == 0));
        b = (f | ((i+=2) > 0));
        System.out.println(i);      
    }
}

в этом случае равен 3

6
задан Bill the Lizard 18 September 2012 в 17:10
поделиться

5 ответов

Почему вывод отличается в случае &&, &, || ?

Так же как в C/C++ && оценивается "лениво", а & - нет.

Если a ложно, то a && b вернет false, даже не оценивая b.

То же самое касается a || b: Если первый операнд, a, истинен, то все выражение истинно, а второй операнд, b, никогда не оценивается. Для a | b, однако, и a, и b будут оценены.

Это имеет последствия, если операнд, который не оценивается при использовании && (или ||), имеет побочные эффекты, как в ваших примерах.


Побочное замечание: немногие java-программисты знают, что ^ (xor) работает и для булевых чисел. (Версии ^^ не существует просто потому, что она была бы избыточной)

.
12
ответ дан 8 December 2019 в 05:52
поделиться

Существует 4 булевых бинарных оператора, которые мы здесь рассматриваем:

  • && - условный и оператор
    • & - логический и оператор
  • || - условный оператор or
    • | - логический оператор or

Вот ключевой момент:

  • "условный" означает замыкание: он не оценивает правый операнд, если это не повлияет на результат операции
  • "логический" не замыкается: он оценивает оба операнда, сначала левый, потом правый.
  • Результат "and" true только если оба операнда true
    • Если левый операнд false, результат будет false независимо от правого операнда
  • Результатом "или" будет true только если хотя бы один операнд будет true
    • Если левый операнд будет true, результат будет true независимо от правого операнда

Другими словами, при условии отсутствия исключений и т.д:

  • & и | всегда оценивают оба операнда
  • && и || оценивают правый операнд условно; правый операнд оценивается только если его значение может повлиять на результат бинарной операции. Это означает, что правый операнд НЕ оценивается, если:
    • левый операнд && оценивается в false
      • (потому что независимо от того, во что оценивается правый операнд, все выражение равно false)
    • Левый операнд || оценивается в true
      • (потому что независимо от того, во что оценивается правый операнд, все выражение равно true)

Ссылки

  • JLS 15. 22.2 Булевы логические операторы &, ^ и |
    • Для & результатом будет true, если оба операнда равны true; в противном случае результатом будет false.
    • Для | результатом будет false, если оба операнда равны false; в противном случае результатом будет true.
  • JLS 15.23 Условный оператор && &&
    • Оператор && похож на &, но оценивает свой правый операнд только в том случае, если значение его левого операнда равно true.
  • JLS 15.24 15.24 Условный оператор ||
    • Оператор || подобен |, но оценивает свой правый операнд, только если значение его левого операнда равно false.

См. также

Похожие вопросы

7
ответ дан 8 December 2019 в 05:52
поделиться

&& и || - это логические операторы И и ИЛИ, они всегда приводят к логическому выражению . & и | - побитовые операторы И и ИЛИ, они выполняют побитовое сравнение каждой стороны. Для получения дополнительной информации о том, что делают эти операторы, см. по этой ссылке

1
ответ дан 8 December 2019 в 05:52
поделиться

Это происходит потому, что && и || являются логическими операторами, которые имеют "механизм короткого замыкания". Если вы используете || и первое выражение оценивается как true, второе не будет оценено и, следовательно, i не будет вычислено. & и | - битовые операторы, которые выполняют битовые вычисления на входе. Они не имеют короткого замыкания, и поэтому все выражение оценивается независимо от того, что происходит.

1
ответ дан 8 December 2019 в 05:52
поделиться

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

Разница между случаями 1 и 3 основана на логике короткого замыкания.

В случае 1 оператор && во втором выражении замыкается как false на первое false , в результате чего вторая половина выражения не выполняется быть оцененным.

В случае 3 false в первой половине второго выражения приводит к вычислению второй половины выражения, увеличивая i . ложь || expr может быть только false , если expr также ложно (поэтому оно должно быть вычислено).

1
ответ дан 8 December 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: