您的位置:首页 > 编程语言 > C语言/C++

C/C++中,优先级的那些事儿

2016-01-31 14:34 267 查看
大家首先看两个程序:

1.    while( c = ' '  ||  c == '\t'  ||  c == '\n')

2.     if  (flags & board  != 0 )

3.     1<<3+2

大家看完,什么感觉?我觉得应该好一部分人应该这样理解:

第一个:不就是现将空格字符赋值给了变量c然后进行后面的(||)或运算,依次比较

第二个:也不就是变量flags和变量board进行二进制的(&)&运算,产生结果跟0比较

同理:第三个也不就是1先想左移3位,变成了8,然后在加上2变成了10

但是,事实真的是这样的吗??

我们大家先来看个东西:

                                 运算符                                                   结合性

                       (),[],->,.(4种)                                 从左到右

   !,~,++,--,-,(type),*,&,sizeof(8种)          从右到左

                             *,/,%(3种)                                        从左到右

                                 +,- (2种)                                         从左到右

                              <<,>>(2种)                                        从左到右

                        <,<=,>=,>(4种)                                       从左到右

                                ==,!=(2种)                                            从左到右

                                      &(1种)                                          从左到右

                                      ^(1种)                                                 从左到右

                                       |(1种)                                                 从左到右

                                       &&(1种)                                    
        从左到右

                                        ||(1种)      
                                        从左到右

                                        ?:(1中)    
                                         从左到右

                     
             逗号运算符                                            从左到右

当然,情况太多了,如果我们能对他们进行分组,那么情况就会很容易记忆的,上图的优先性是从下道上(上面最高)

1.优先级最高者(括号,数组,结构体指向操作符(->和.(两个找成员的方法))),某种意义上,它们就不能当做运算符,但是优先级确实最高

2.单目运算符(自增,自减,取非,&,强转),在所有的真正意义上,优先级最高(也就是说,除了上面的)

3.算术运算符(加,减,乘,除,取余)
,优先级也仅次于单目,也就是所谓的双目运算符

4.移位运算符低于算术运算符,也就是说(左移,右移)都要低于(加减乘除)

5.关系运算符低于任何一个移位运算符,也就是(大于,小于,等于,不小于)都低于(左移,右移)

6.对于逻辑运算符是相对最低的

7.最后就是三目运算符,但是比逗号运算符要高(也就是说逗号运算符最低了)

总结一下:

单目---双目---算术---移位---关系---逻辑---三目---逗号

所以对于结合性的话:单目,三目, 赋值其他都是从右往左的

(声明1:

值得注意的是:赋值运算符低于三目,但是高于逗号,而且结合性,也是从右到左的

所以: a = b = c = 0,也可以理解为 :a = (b =(c = 0))

声明2:

逗号运算符:g(x,y)这时表示的是一个函数,而g((x,y)), 指的是这个函数的参数只有一个,里面用到的是逗号运算符

声明3:

关于printf的一点想法:

vc6.0编译器设计的是:从右到左

Dev-C++编译器设计的是:从左到右

Linux下的编译器设计的也是:从左到右



由上可知(易错点):

a.b.c根据结合性:那就是(a.b).c

经常遇到的函数指针:(*p)(),     如果我们*p不加括号,形容*p(),   根据结合性,那就变成了*(p()),也就由函数转变为单目运算符了

*p++,由于优先级相同,但是结合性是从右到左,所以可以理解成这样*(p++),地址先移动,然后取出地址里存放的值

值得注意的是6个关系运算符中:==和!=的优先级最低               也就是说   a<b  == c>d   的时候,处理的顺序不一样了

对于逻辑运算符中:按位运算符要高于另外一种,且这里面,并没有加入(!,也就是非运算符,因为是单目,所以优先级更高),而且对于两种,都是(与,&,位与(&&))大于(或 ,|,位或(||))  

现在:大家在看上面的例子,是不是明白了呢?

while里面:c = ' '  ||  c == '\t'  ||  c == '\n'      赋值运算符的优先级低,所以相当于:c = (' '  ||  c == '\t'  ||  c == '\n')

if里面:      flags & board  != 0                     逻辑运算符小于关系,所以相当于:    flags & (board  != 0 )     

运算符的求值顺序:

c中,只规定了4中(&&,||, ?:,和逗号)

&&和||:首先对左侧的表达式求值,只有一定的需要时才会求取右边表达式的值

               if((a>b) &&  (c=7/d)),也就是说当a<=b时,就会跳出程序,并不会在去考虑d会不会为零的情况

?:       :a?b:c,操作数a首先被求值,根据a的值再去求b或c的值

,      :首先求左侧的值,然后丢弃,在求下一个值,依次重复,知道最后
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息