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的值
, :首先求左侧的值,然后丢弃,在求下一个值,依次重复,知道最后
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的值
, :首先求左侧的值,然后丢弃,在求下一个值,依次重复,知道最后
相关文章推荐
- C#中38个常用运算符的优先级的划分和理解
- Ruby的运算符和语句优先级介绍
- Android中进程生命周期的优先级
- jquery 中ajax执行的优先级
- Javascript算符的优先级介绍
- C语言运算符及其优先级汇总表口诀
- Java线程优先级示例代码
- 优先级队列PriorityBlockingQueue
- 使用PriorityBlockingQueue进行任务按优先级同步执行,摘自Think in Java
- java中关于优先级队列的实现
- java中PriorityQueue优先级队列使用方法
- PriorityQueue优先级队列 学习
- 影响你成功的15条坏习惯,你,占几条?
- mysql的表分区
- Java四种线程池的使用
- 对haproxy配置学习过程中几个点进行总结
- 优先级翻转
- web.xml中classpath和classpath*的区别
- CCNP中优先级的比较
- 运算符的运算优先级