PHP中&和&&之间的区别

Moo*_*oon 48 php

我很困惑&&&.我有两本PHP书.一个人说他们是一样的,但另一个说他们是不同的.我以为他们也一样.

他们不一样吗?

cle*_*tus 85

&是按位AND.请参阅按位运算符.假设你这样做14 & 7:

    14 = 1110
     7 = 0111
    ---------
14 & 7 = 0110 = 6
Run Code Online (Sandbox Code Playgroud)

&&是合乎逻辑的.请参阅逻辑运算符.考虑一下这个真值表:

 $a     $b     $a && $b
false  false    false
false  true     false
true   false    false
true   true     true
Run Code Online (Sandbox Code Playgroud)

  • 我将补充说,当你比较布尔值或整数,并将结果视为布尔值时,它们*看起来*是相同的. (6认同)
  • @kibibu不一定.2和1(二进制10和01)是0,这是假的,但如果PHP完全合理,则2 && 1应为真... (5认同)

Mat*_*hen 51

其他答案是正确的,但不完整.逻辑AND的一个关键特性是它短路,这意味着只在必要时才评估第二个操作数.PHP手册给出了以下示例来说明:

$a = (false && foo());
Run Code Online (Sandbox Code Playgroud)

foo永远不会被调用,因为在评估false之后结果是已知的.另一方面用

$a = (false & foo());
Run Code Online (Sandbox Code Playgroud)

foo 将被调用(同样,结果是0而不是假).


Chr*_*ras 7

马修关于逻辑与 &&运算符的最大区别的回答;逻辑比较会在找到打破链条的东西时停止。此外,还有一个更大的区别是结果类型/值

tl;博士

通过使用Logical And &&,它将始终返回一个布尔类型/值truefalse

false & 1 // int(0)
false && 1 // bool(false)
Run Code Online (Sandbox Code Playgroud)

在返回具有逻辑结果的函数时使用布尔类型/值很重要,因为有人可以使用相同的比较运算符 ===来比较结果(这种情况很可能发生),如果您使用这样的东西,它将失败:

(false & 1) === false // bool(false)
(true & true) === true // bool(false)
Run Code Online (Sandbox Code Playgroud)

当您需要进行逻辑比较时,尤其是从具有逻辑结果的函数返回值时,切勿使用Bitwise And &。而是使用逻辑与 &&

(false && 1) === false // bool(true)
(true && true) === true // bool(true)
Run Code Online (Sandbox Code Playgroud)

比较字符时,逻辑与 &&总是会导致true,即使是NUL字符,除非它被转换为整数:

'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)
Run Code Online (Sandbox Code Playgroud)

如果对字符使用Bitwise And &,则会在这两个字符之间产生对应于Bitwise And运算的字符:

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

01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '@'
Run Code Online (Sandbox Code Playgroud)

当与整数字符(它们是特殊类型的整数)以外的类型一起使用时,请注意Bitwise And 的 &使用。例如,如果你用它与实数浮点/双精度,那么它可能会导致到即使两个操作数是不是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)
Run Code Online (Sandbox Code Playgroud)

此外,如果我们进入汇编指令级别,我们可以看到差异以及编译器如何处理,因此逻辑与 &&用于cmp <var>, 0比较并且如果一个操作数失败则不会继续执行;Bitwise And用于and <var1>, <var2>生成按位结果,然后测试它是否0有价值。我知道这个问题被标记为并且行为可能与不同,但我将使用一个小的程序来演示编译器在使用LogicalBitwise And时的行为。

让我们假设我们有一个使用按位逻辑与的程序:

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

if (a & b)
    c = 3;

if (a && b)
    c = 4;
Run Code Online (Sandbox Code Playgroud)

编译器将生成以下程序集操作码(x86 的 W32Dasm 结果<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> // <---  <---
Run Code Online (Sandbox Code Playgroud)

编译器不仅使用不同的指令在LogicalBitwaise And之间进行比较,而且:0253if (a && b)逻辑比较的行中,我们看到 if a == 0then 它跳转并且不检查其余操作数。

所以,我不同意animuson的评论

它们都是同一件事,它们只是用于完成相同任务的两种不同事物。– animuson 2010 年 3 月 4 日 1:42

它们不是一回事,两者都/ (应该)用于特定任务,具体取决于程序的逻辑/流程。


Pav*_*mar 5

 

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