Main > Java | Java labs > Логическое и побитовое "И"

Логическое и побитовое "И"

26.03.2012 2 comments » Views: 15,950

Амперсанд

Очень часто, молодых специалистов легко завести в тупик, спросив чем отличаются два условия:
if (a&&b){}
и if (a&b){}. Сегодня я расскажу в чем отличие.

Для начала нам необходимо знать, что:

&& = это логическое "И"
& = это битовое "И"

Давайте посмотрим что нам говорит Wikipedia:

В компьютерных языках используется два основных варианта конъюнкции: логическое "И" и побитовое (поразрядное) "И". Например, в языках C/C++ логическое "И" обозначается символом "&&", а побитовое — символом "&". В терминологии, используемой в C#, операцию "&" принято называть логическим "И", а операцию "&&" - условным "И", поскольку значения операндов являются условиями для продолжения вычисления. В языках Pascal/Delphi оба вида конъюнкции обозначается с использованием ключевого слова "and", а результат действия определяется типом операндов. Если операнды имеют логический тип (например, Boolean) — выполняется логическая операция, если целочисленный (например, Byte) — поразрядная.

Если Вы все поняли, можете дальше не читать. Для тех же, кто в цитате увидел, просто набор букв, я объясню проще:

  • При использовании && происходит логическое сравнение, двух результатов,
    например: false && true = false
  • При использовании & происходит побитовое сравнение, двух результатов,
    например: 001 & 101 = 001

Это в свою очередь нам дает такой результат:

  • При использовании &&, в случае, если результат равен false, дальнейшая проверка не выполняется.
    Пример: (false && a() && b()). Методы a() и b() не будут вызваны, т.к. на первом месте стоит false и это означает что все выражение будет false.
  • При использовании &, в любом случае будут выполнены все проверки, т.к. побитовый сдвиг "надо делать с цифрами", а на этапе выполнения выражения, мы не можем предсказать результат.
    Пример: (false & a() & b()) . Методы a() и b() будут вызваны.

 

Давайте теперь проверим:

Результат выполнения:

 

Итак, в первом случае я использую логическое "и" (&&) и мы видим что метод test() выполняется только один раз (тот что слева от &&), т.к. он возвращает false, то компилятор оптимизирует вычисления и второй вызов test() не делает.
Во втором случае, мы используем побитовое "и" (&), соответственно для вычисления результата компилятору необходимо знать оба результата, поэтому метод тест вызывается дважды (тот что слева от & и тот что справа).

Вопросы для собеседования:

  • Чему будет равно выражение: ( false ) && ( false & true && true & false & false && true )
    Ответ: результат будет false, т.к. слева у нас false, и дальше оператор логического "и" (&&), а это значит что выражение во вторых скобках компилятор не будет считать.
  • Чему будет равно выражение: if ( 1 & 1 && 1 ){}
    Ответ: Ничему. Произойдет ошибка компиляции. Тут допущено три ошибки:
    а) if должен на вход получать boolean значение, а у нас int;
    б) операция && (логическое "и") может быть выполнена только с boolean значениями;
    в) операция & (побитовое "и") может быть выполнена только с цифрами.

Author: | Rating: 4/5 | Tags:

2 comments.

Write a comment
  1. Anton Reply
    30.07.2014 в 11:11 pm
    if ( 1 & 1 && 1 ){}
    Ответ: Ничему. Произойдет ошибка компиляции.

    На заметку:
    В СИ оператор if спокойно кушает int
    А в целом статья справедлива и для СИ.
    • Алексей Reply
      17.04.2018 в 10:31 pm
      Как бы да. Если это вопрос для собеседования, то я бы из такой конторы сам убежал.

Leave a Reply

Your email address will not be published. Required fields are marked *

Allowed HTML-tags: <a>, <code>, <i>, <em>, <strong>, <b>, <u>, <strike>