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

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

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

先看一段代码

cpp 复制代码
bool a, b, c;
c = a & b;

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

asm 复制代码
	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编译出来的指令如下:

asm 复制代码
	movzbl	-1(%rbp), %edx
	andb	-2(%rbp), %dl

再看一段代码:

cpp 复制代码
bool a, b, c;
c = a && b;

其汇编代码为:

asm 复制代码
    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

反汇编一下:

cpp 复制代码
tmp = a;
if(a==1) {
    tmp = b;
}
c = tmp & 1;

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

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

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

再看一段代码:

cpp 复制代码
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_pz a_cost
funcB() b_pz b_cost

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

a_cost + (1-a_pz) * b_cost

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

b_cost + (1-b_pz) * a_cost

举个例子

返回0概率 复杂性(耗时)
funcA() 0.9 50
funcB() 0.8 40

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

相关推荐
敲敲敲-敲代码2 分钟前
游戏设计:推箱子【easyx图形界面/c语言】
c语言·开发语言·游戏
ROC_bird..10 分钟前
STL - vector的使用和模拟实现
开发语言·c++
MavenTalk16 分钟前
Move开发语言在区块链的开发与应用
开发语言·python·rust·区块链·solidity·move
simple_ssn24 分钟前
【C语言刷力扣】1502.判断能否形成等差数列
c语言·算法·leetcode
ahadee44 分钟前
蓝桥杯每日真题 - 第10天
c语言·vscode·算法·蓝桥杯
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】生产消费模型 & 阻塞队列
java·开发语言·java-ee
2401_840192271 小时前
python基础大杂烩
linux·开发语言·python
@东辰1 小时前
【golang-技巧】- 定时任务 - cron
开发语言·golang·cron
机器人天才一号1 小时前
C#从入门到放弃
开发语言·c#
好想有猫猫1 小时前
【51单片机】LCD1602液晶显示屏
c语言·单片机·嵌入式硬件·51单片机·1024程序员节