我对&
和&&
感到困惑。我有两本PHP书。一个人说他们是一样的,但另一个说他们是不同的。我认为它们也一样。
它们不一样吗?
答案 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关于逻辑和 &&
运算符的最大区别;逻辑比较会在找到破坏链条的东西时停止。另外,结果类型/值还有一个很大的区别。
使用逻辑和 &&
,它将始终返回布尔类型/值,true
或false
。
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
值。我知道此问题已标记为php且php行为可能与c不同,但我将使用一个小c程序来演示编译器在使用时的行为< em>逻辑和按位和。
我们假设我们在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> // <--- <---
编译器不仅使用不同的指令在逻辑和 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
是一个按位运算符,它会改变它的操作数。也就是说,逻辑运算是按位运算的一个子集。)