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

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

Разве они не такие?

Solutions Collecting From Web of "Разница между & и && в PHP"

& побитовое И. См. Поразрядные операторы . Предполагая, что вы делаете 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 

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

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

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

 $a = (false & foo()); 

foo будет вызываться (также результат равен 0, а не false).

 

 И операция: 

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

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

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

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

TL; DR

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

Используя 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) 

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

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

Если вы используете побитовые символы And & с символом, это приведет к тому, что символ, соответствующий операции « Побитовое и» между этими двумя символами:

 'A' & 'B' // string(1) "@" 01000001 // ASCII 'A' & 01000010 // ASCII 'B' = 01000000 // ASCII '@' 

Остерегайтесь использования Побитового И & при использовании с типами, отличными от Целых и Символов (которые являются особыми целыми числами). Например, если вы используете его с действительными числами float / double , то это может привести к 0 даже если оба операнда НЕ 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) 

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

Предположим, у нас есть программа в c, которая использует как побитовое, так и логическое И :

 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> // <--- <--- 

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

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

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

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

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

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