&和和&&用PHP

时间:2010-03-04 01:39:28

标签: php

我对&&&感到困惑。我有两本PHP书。一个人说他们是一样的,但另一个说他们是不同的。我认为它们也一样。

它们不一样吗?

6 个答案:

答案 0 :(得分:82)

&是按位AND。见Bitwise Operators。假设你做14 & 7

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

&&是合乎逻辑的AND。见Logical Operators。考虑一下这个真值表:

 $a     $b     $a && $b
false  false    false
false  true     false
true   false    false
true   true     true

答案 1 :(得分:49)

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

$a = (false && foo());
永远不会调用

foo,因为在评估false之后结果是已知的。另一方面用

$a = (false & foo());

foo将被调用(同样,结果为0而不是false)。

答案 2 :(得分: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 

答案 3 :(得分:4)

Matthew's answer关于逻辑和 &&运算符的最大区别;逻辑比较会在找到破坏链条的东西时停止。另外,结果类型/值还有一个很大的区别。

TL;博士

使用逻辑和 &&,它将始终返回布尔类型/值truefalse

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

在返回具有逻辑结果的函数时,使用布尔类型/值非常重要,因为有人可以使用相同比较运算符 ===进行比较结果(很可能发生)很可能会失败,如果你使用这样的东西:

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

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

(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)

如果您将按位和 &与字符一起使用,则会产生与这两个字符之间的按位和操作相对应的字符:

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

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

当使用整数字符以外的类型时,请注意按位和 &的使用(这是特殊种类)整数)。例如,如果您将它与实数 float / double 一起使用,那么即使两个操作数都是 NOT 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)

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

我们假设我们在中有一个程序,它同时使用按位逻辑和

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

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

所以,我不同意animuson's comment

  

它们都是一样的,它们只是用于两种不同的方式   要完成同样任务的事情。 - animuson 2010年3月4日1:42

它们不是同一个东西,并且/ (应该)用于特定任务,具体取决于程序的逻辑/流程。

答案 4 :(得分:3)

正如其他人所说,单个&是按位的。它基本上将左手值转换为其位表示,右手侧也转换为位表示,然后在它们之间执行逻辑AND并输出结果。

如果左侧和右侧都为真(或非零),则双&&为真或假,(在某些语言中为0或1)。

我还要补充一点,这不仅仅是在PHP中。它就像许多其他语言一样,如C,Java,Ruby等。

答案 5 :(得分:0)

HybridHttpOrThreadLocalScoped() &&对操作数减少为&1执行。

(换句话说,0是一个按位运算符,它会改变它的操作数。也就是说,逻辑运算是按位运算的一个子集。)