运算符优先级

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 呢?

原文地址:https://www.cnblogs.com/ET2006/p/ysyxj.html