• 运算符优先级


    rt,发现自己搞不清楚这东西,不管三七二十一先水一篇 blog 再说

    大概就是运算优先级是有括号先算括号,然后先算 ++ -- ~ ! 这类一元运算符以及正负号,其次是 * / %,再其次 + -,再其次 << >>,然后是 <= < >= >,再其次 == !=,再其次 & ^ |,最后是 && ||

    比如说 a=1,b=2,c=3,那么表达式 (~a+b%c+c<<c|~b*--a<c/c&c) 的计算方式为先计算 ~a,~b,--a,值分别为 \(-2,-3,0\),然后计算 b%c~b*--ac/c,值分别为 \(2,0,1\),然后计算 ~a+b%c+c,值为 \(3\),然后计算 ~a+b%c+c<<c,值为 3<<3=24,其次是 ~b*--a<c/c,即 0<=1,返回真,其次是 ~b*--a<c/c&c\(1\& 3=1\),最后计算 ~a+b%c+c<<c|~b*--a<c/c&c,值为 \(25\)

    还有就是同级运算符结合的顺序,普通的运算符,譬如 + - * / % << >> & | 肯定都是从左到右计算的,譬如 a=1,b=2,c=3,d=1,e=2,那么 a<<b<<c>>d>>e 就按照从左往右的顺序算,值为 \(4\),但是有的(一般是什么什么等于)运算符是从右往左结合的,比如说 <<= >>=, 比方说还是 a=1,b=2,c=3,d=1,e=2,那么 a<<=b<<=c>>=d>>=e 就先计算 d>>=e,以此类推,最后表达式的结果为 \(65536\)\(b=16,c=3,d=0,e=2\)

    最后其实加括号完全可以避免这个问题,并且效率上也差别也不是太大,比方说

    ll s=0,a=7,b=10,c=100000000,d=18,e=23;
    for(int i=1;i<=1000000000;i++){
        s+=a&b^++e*~d|--c;
        e^=a|++d%b^!c;
    } printf("%lld\n",s);
    

    ll s=0,a=7,b=10,c=100000000,d=18,e=23;
    for(int i=1;i<=1000000000;i++){
        s+=(((a&b)^((++e)*(~d)))|(--c));
        e^=((a|(++d)%b)^(!c));
    } printf("%lld\n",s);
    

    前者跑了 4.3s,后者跑了 4.5s,并且还是在运算量超大(\(10^9\))的情况下才体现出 0.2s 的差异,所以其实加括号完全可以避免这个问题。
    所以我为什么要水一篇 blog 呢?

  • 相关阅读:
    js点击显示全部内容(用于内容比较长时)
    vs中运行时如何去除虚拟目录
    selenium使用中的几个问题
    解决播客程序不能播放Flv文件的问题
    VS2005 + VSS6.0 简单应用示例
    IList转换为DataTable
    asp.net根据生日计算年龄(具体到年月天)
    vs2005菜单中没有显示源代码管理怎么办
    asp.net解决中文乱码问题
    跨域删除cookie的问题
  • 原文地址:https://www.cnblogs.com/ET2006/p/ysyxj.html
Copyright © 2020-2023  润新知