马修(Matthew)关于逻辑与:0253运算符的最大区别的答案; 当逻辑比较发现会破坏链条时,逻辑比较将停止。 此外,结果类型/值还有一个更大的区别。
tl;博士
通过使用逻辑和:0253,它将始终返回布尔类型/值if (a && b)或a == 0。
false & 1 // int(0)
false && 1 // bool(false)
在返回具有逻辑结果的函数时,请使用布尔类型/值,这一点很重要,因为有人可以使用完全相同的比较运算符:0253来比较结果(很可能会发生这种情况),并且如果您使用类似以下的方法将失败:
(false & 1) === false // bool(false)
(true & true) === true // bool(false)
需要进行逻辑比较时,尤其是从具有逻辑结果的函数返回值时,切勿使用按位与:0253。 而是使用Logical And if (a && b):
(false && 1) === false // bool(true)
(true && true) === true // bool(true)
比较字符时,逻辑和:0253始终会得出if (a && b),即使有a == 0字符也是如此,除非将其转换为整数:
'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)
如果对字符使用按位与:0253,它将导致与这两个字符之间的按位与运算相对应的字符:
'A' & 'B' // string(1) "@"
01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '@'
当与整数和字符(它们是特殊的整数类型)以外的类型一起使用时,请注意按位和:0253的用法。 例如,如果将它与实数浮点/双精度一起使用,那么即使两个操作数都不是a == 0,也可能导致if (a && b):
1.0 & 1.0 // int(1)
2.0 & 1.0 // int(0)
1.0 && 1.0 // bool(true)
2.0 && 1.0 // bool(true)
另外,如果我们进入汇编指令级别,则可以看到这种差异以及编译器如何处理,因此Logical And :0253使用if (a && b)进行比较,如果一个操作数失败,它将不继续执行; 按位与使用a == 0进行按位运算,然后测试其值为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;
编译器将生成以下程序集操作码(x86的W32Dasm结果;为简单起见,为了更易理解,我使用:0253名称更改了内存地址):
:0229 mov , 0
:0230 mov , 1
:0237 mov , 2
// if (a & b) begins
:023E mov eax,
:0241 and eax, // 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 , 3 // | or set c = 3
// if (a && b) begins |
:024F cmp , 0 //
:0253 je 0262 // >--- Jump if ZeroFlag is set (a == 0)
:0255 cmp , 0 // | compare b to 0 and sets ZeroFlag if differemce is 0
:0259 je 0262 // | >--- Jump if ZeroFlag is set (b == 0)
:025B mov , 4 // | | or set c = 4
:0262 //
编译器不仅使用不同的指令在Logical和Bitwaise And之间进行比较,而且在if (a && b)逻辑比较中的行:0253上,我们看到如果a == 0则它跳转并且不检查其余操作数。
因此,我不同意animuson的评论:
它们都是同一件事,只是用于两种不同的用途 完成相同任务的事物。 – animuson 10年3月4日在1:42
它们不是一回事,根据程序的逻辑/流程,两者都(应该)用于特定任务。