PHP中&和&&的区别

我很困惑&&&。我有两本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将永远不会被调用,因为结果在评估错误之后是已知的。另一方面与

$a = (false & foo());

foo 将被调用(也是,结果是0而不是假的)。

 

 

AND操作: 

& - >将执行按位AND操作,它只是基于的操作
      位值。 
&&  - >它会做逻辑与操作。这只是检查值是
       对或错。基于布尔值,它将评估
       表达 

正如其他人所说的,一个人&是位智者。它基本上将左边的值转换成比特表示,右边的转换成比特表示,然后在它们之间执行逻辑与并输出结果。

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

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

 

马修关于逻辑和 &&运算符是如何最大的区别的答案 ; 逻辑比较将会停止,当它会发现一些打破链条。另外,还有一个更大的区别就是结果类型/值

通过使用逻辑和 &&,它总是会返回一个布尔类型/值true或者false

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

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

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

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

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

如果使用Bitwise和Character &,则会导致这两个字符之间的Bitwise And操作对应的字符:

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

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

注意Bitwise 的用法&当使用除整数字符(这是一种特殊的整数)以外的类型。例如,如果你用它与实数浮点/双精度,那么它可能会导致到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有价值。我知道这个问题是标记为行为可能不同于,但我会用一个小型的程序来演示如何使用逻辑按位和编译器的行为。

假设我们有一个程序同时使用按位逻辑与

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

if (a & b)
    c = 3;

if (a && b)
    c = 4;

编译器将生成下面的程序集操作码(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> // <---  <---

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

所以,我不同意这个看法:

他们都是一样的东西,他们只是用于完成相同的任务两个不同的东西。 – animuson 10年3月4日在1:42

它们不是一回事,根据程序的逻辑/流程,它们都是/ (应该)被用于特定的任务。

Tags:

添加评论

友情链接:蝴蝶教程