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

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值