Разница между & и && в PHP - PullRequest
       120

Разница между & и && в PHP

45 голосов
/ 04 марта 2010

Я путаюсь с & и &&. У меня есть две книги по PHP. Один говорит, что они одинаковы, а другой говорит, что они разные. Я думал, что они такие же.

Разве они не одинаковы?

Ответы [ 6 ]

82 голосов
/ 04 марта 2010

& - поразрядное И. См. Битовые операторы . Предполагая, что вы делаете 14 & 7:

    14 = 1110
     7 = 0111
    ---------
14 & 7 = 0110 = 6

&& логично И. См. Логические операторы . Рассмотрим эту таблицу истинности:

 $a     $b     $a && $b
false  false    false
false  true     false
true   false    false
true   true     true
50 голосов
/ 19 октября 2010

Остальные ответы верны, но неполны. Ключевой особенностью логического И является то, что он замыкает накоротко, то есть второй операнд оценивается только при необходимости. В руководстве по PHP приведен следующий пример:

$a = (false && foo());

foo никогда не будет вызван, так как результат известен после оценки false. С другой стороны, с

$a = (false & foo());
Будет вызван

foo (также результат 0, а не false).

5 голосов
/ 04 марта 2010
 

AND operation: 

& -> will do the bitwise AND operation , it just doing operation based on
      the bit values. 
&&   -> It will do logical AND operation. It is just the check the values is 
       true or false. Based on the boolean value , it will evaluation the 
       expression 
4 голосов
/ 04 августа 2017

Ответ Мэтью о том, как Логический И && оператор является самой большой разницей; Логическое сравнение остановится, когда найдет что-то, что разорвет цепочку. Кроме того, есть еще одна большая разница - тип результата / значение .

Т.Л., др

Используя Logical And &&, он всегда будет возвращать логический тип / значение , true или false.

false & 1 // int(0)
false && 1 // bool(false)

Важно использовать логический тип / значения при возврате функции с логическим результатом, потому что кто-то может использовать Идентичный оператор сравнения === для сравнения результатов (который высока вероятность того, что произойдет), и он потерпит неудачу, если вы используете что-то вроде этого:

(false & 1) === false // bool(false)
(true & true) === true // bool(false)

Никогда не используйте Побитовое И &, когда вам нужно провести логическое сравнение, особенно при возврате значений из функций с логическими результатами. Вместо этого используйте Logical And &&:

(false && 1) === false // bool(true)
(true && true) === true // bool(true)

При сравнении символов Logical And && всегда приводит к true, даже с символом NUL, если только он не преобразуется в целое число:

'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)

Если вы используете Битовая И & с символами, в результате будет получен символ, соответствующий операции Битовая И между этими двумя символами:

'A' & 'B' // string(1) "@"

01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '@'

Остерегайтесь использования Побитового И & при использовании с типами, отличными от Целые числа и Символы (которые являются специальным видом целых чисел). Например, если вы используете его с действительными числами float / double , то это может привести к 0, даже если оба операнда NOT 0:

1.0 & 1.0 // int(1)
2.0 & 1.0 // int(0)

1.0 && 1.0 // bool(true)
2.0 && 1.0 // bool(true)

Кроме того, если мы перейдем на уровень инструкций по сборке, мы увидим эту разницу и то, как компилятор справится с этим, поэтому Logical And && использует cmp <var>, 0 для сравнения и не продолжает выполнение если один операнд терпит неудачу; Побитовое И использует and <var1>, <var2> для получения побитового результата и затем проверяет, имеет ли оно значение 0. Я знаю, что этот вопрос помечен для и поведение может отличаться от , но я буду использовать небольшую программу чтобы продемонстрировать, как ведет себя компилятор при использовании Logical и Bitwise And .

Предположим, у нас есть программа в , в которой используются Битовая и Логическая А :

int a = 0;
int b = 1;
int c = 2;

if (a & b)
    c = 3;

if (a && b)
    c = 4;

Компилятор сгенерирует следующие коды операций сборки ( Результат W32Dasm для x86 ; я изменил адреса памяти с именами <variable> для простоты и большей понятности):

:0229  mov <a>, 0
:0230  mov <b>, 1
:0237  mov <c>, 2
// if (a & b) begins
:023E  mov eax, <a>
:0241  and eax, <b>        // a bitwise and b, result stored to eax
:0244  test eax, eax       // test eax and set ZeroFlag if equals to 0
:0246  je 024F             // >---  Jump if ZeroFlag is set
:0248  mov <c>, 3          //    |  or set c = 3
// if (a && b) begins            |
:024F  cmp <a>, 0          // <---  compare a to 0 and sets ZeroFlag if difference is 0
:0253  je 0262             // >---  Jump if ZeroFlag is set (a == 0)
:0255  cmp <b>, 0          //    |  compare b to 0 and sets ZeroFlag if differemce is 0
:0259  je 0262             //    |  >--- Jump if ZeroFlag is set (b == 0)
:025B  mov <c>, 4          //    |     | or set c = 4
:0262  <program continues> // <---  <---

Компилятор не только использует различные инструкции для сравнения между Logical и Bitwaise And , но и в строке :0253 в if (a && b) в логическом сравнении, мы видим, что если a == 0 затем он прыгает и не проверяет остальные операнды.

Итак, я не согласен с комментарием анимусона :

Они оба одно и то же, они просто используются для двух разных вещи для выполнения той же задачи. - animuson 4 марта 2010 года в 1:42

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

3 голосов
/ 04 марта 2010

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

Double && - это либо true, либо false (в некоторых языках 0 или 1), если левая и правая части имеют значение true (или не ноль).

Я бы также добавил, что это не только в PHP. Так же и во многих других языках, таких как C, Java, Ruby и т. Д.

0 голосов
/ 01 августа 2017

&& - это &, выполняемое с операндами, уменьшенными до 1 или 0.

(Другими словами, && является побитовым оператором под оговоркой, что он меняет свои операнды. То есть логические операции являются подмножеством побитовых операций.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...