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


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

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

    先看一段代码

    bool a, b, c;
    c = a & b;
    
    • 1
    • 2

    使用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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

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

    再看一段代码:

    bool a, b, c;
    c = a && b;
    
    • 1
    • 2

    其汇编代码为:

        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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    反汇编一下:

    tmp = a;
    if(a==1) {
        tmp = b;
    }
    c = tmp & 1;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通过对比两段汇编代码就很清晰了,&运算在底层表现为一条指令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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    上述代码中表达式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

  • 相关阅读:
    golang匿名函数 加油
    大数据_面试题_Java篇集锦
    python实现综合评价模型TOPSIS
    ctfhub-web-warmup
    【SQL Server】数据库开发指南(九)详细讲解 MS-SQL 触发器的的创建、修改、应用与适用场景
    串口收发UART(Verilog HDL)
    23. 云笔记项目
    一文搞懂│XSS攻击、SQL注入、CSRF攻击、DDOS攻击、DNS劫持
    机器学习分类问题标签如何做编码
    asp.net毕业设计项目源码社区保障管理系统
  • 原文地址:https://blog.csdn.net/qq_38600065/article/details/132640983