C语言关于&与&&运算符

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

C语言关于&与&&运算符

我们知道在很多场景中&和&&通常可以相互代替那么它们到底有什么不同呢

先看一段代码

bool a, b, c;
c = a & b;

使用clang++ -S编译出来的指令如下

	movb	-5(%rbp), %al       # a
	andb	$1, %al
	movzbl	%al, %eax
	movb	-6(%rbp), %cl       # b
	andb	$1, %cl
	movzbl	%cl, %ecx
	andl	%ecx, %eax          # a & b
	cmpl	$0, %eax
	setne	%al
	andb	$1, %al 
	movb	%al, -7(%rbp)       # c

使用clang++ -S -O3编译出来的指令如下

	movzbl	-1(%rbp), %edx
	andb	-2(%rbp), %dl

再看一段代码

bool a, b, c;
c = a && b;

其汇编代码为

    xorl	%eax, %eax
	testb	$1, -5(%rbp)        # a
	movb	%al, -8(%rbp)                   
	je	.LBB2_2
# %bb.1:
	movb	-6(%rbp), %al       # b
	movb	%al, -8(%rbp)                   
.LBB2_2:
	movb	-8(%rbp), %al                   
	andb	$1, %al
	movb	%al, -7(%rbp)       # c

反汇编一下

tmp = a;
if(a==1) {
    tmp = b;
}
c = tmp & 1;

通过对比两段汇编代码就很清晰了&运算在底层表现为一条指令and而&&运算实际上需要通过分支的方式实现。

那么能否说明&的效率比&&要高呢不一定

我们知道&是与运算例如要得到a & b的值就必须分别求得a和b的值。但是&&通过分支的方式实现要想得到a && b的值其实不必都求出a和b的值如果先求出a的值是0那么就不必再求b了。

再看一段代码

bool funcA() {
    
}

bool funcB() {
    
}

int main () {
    bool c = funcA() & funcB();
    bool d = funcA() && funcB();
}

上述代码中表达式funcA() & funcB() 与 funcA() && funcB() 哪一个效率更高

需要具体分析funcA()和funcB()的返回值分布与复杂度如果funcA()和funcB()复杂度很低并且大部分情况下返回1那么funcA() & funcB()的效率可能会高些如果funcA()和funcB()复杂度较高并且有可能返回0那么funcA() && funcB()会高一些。

另外值得一提的是funcA() && funcB()与funcB() && funcA()哪个效率高

返回0概率复杂性(耗时)
funcA()a_pza_cost
funcB()b_pzb_cost

funcA() && funcB() 期望耗时为:

a_cost + (1-a_pz) * b_cost

funcB() && funcA() 期望耗时为:

b_cost + (1-b_pz) * a_cost

举个例子

返回0概率复杂性(耗时)
funcA()0.950
funcB()0.840

funcA() && funcB() 期望耗时为54 funcB() && funcA() 期望耗时为50

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6