C/C++操作符的优先级和结合性问题浅析
两个相邻操作符的执行顺序由它们的优先级决定。例如: a + b*c,在这个表达式中,乘法和加法操作符是两个相邻的操作符,由于乘法的优先级比加法高,所以乘法运算先于加法运算执行。编译器在这里别无选择,它必须先执行乘法运算。
如果它们的优先级相同,它们的执行顺序由它们的结合性决定。例如:a + b + c,由于 + 操作符的结合性是由左到右(L-R),所以先计算a+b,然后计算(a+b)+c。
除此之外,编译器可以自由决定使用任何顺序对表达式进行求值,只要它不违背逗号、&&、||和?:操作符所施加的限制。
上面这句话是什么意思呢?举个例子说明: a*b+ c*d + e*f,对于这个表达式,如果仅有优先级决定这个表达式的求值顺序,那么所有3个乘法运算将在所有加法运算之前进行。事实上,这个顺序并不是必需的。实际上,只要保证每个乘法运算在它相邻的加法运算之前执行即可。
例如这个表达式可能会以下面的顺序进行:
a*b
c*d
(a*b)+(c*d)
e*f
(a*b)+(c*d)+(e*f)
注意第一个加法运算在最后一个乘法运算之前执行。
如果这个表达式按下面这个顺序执行,其结果也是一样的:
c*d
e*f
a*b
(a*b)+(c*d)
(a*b)+(c*d)+(e*f)
如果编译器足够变态,当然可以以这个顺序进行,因为标准并没有对此进行限制。
注:除此之外,我还需要讲解一下上文提到的,只要只要它不违背逗号、&&、||和?:操作符所施加的限制。
这说明上面提到的这个几个操作符的特殊性,它们对求值顺序进行了控制。
首先是逗操作符:
用法如下:
expression1,expression2,...,expressionN
逗号表达式将两个或多个表达式分隔开来。这些表达式自左向右逐个求值,整个逗号表达式的值就是最后那个表达式的值。
说完了它的用法,那么整个逗号操作符的意义何在?
请看下面的代码示例:
其次,就是&&与||这两个操作符,它们是逻辑操作符,逻辑操作符具有短路性质,就是如果表达式的值根据左操作数就可以确定,那么它就不在对右操作数进行求值。
例如,a > 5 && a < 10
首先我们知道,比较操作符的优先级高于逻辑操作符,故上面的表达式等价于:
( a > 5 ) && ( a < 10)
但是,尽管&&操作符的优先级低,但是它仍然会对两个关系表达式施加限制,下面是它的工作原理:
&&操作符的左操作数总是首先进行求值,如果它的值为真,那么就紧接着对右操作数求值。如果左操作数为假,那么右操作数不再求值,因为整个表达式肯定是假的,右操作数已经无关紧要。
同理,可以类似地分析||。
最后一个就是?:条件操作符。例如 a>b?c=a:c=b;
它的优先级低于比较操作符,赋值操作符,但是它仍然对它们进行控制。
作用原理是,如果a>b成立的话,执行语句c=a;否则c=b。
下表截取C和指针给出的优先级、结合性等比较全的版本:
如果感觉上面的比较乱,那再来一个中文版本:
口诀:
括号成员第一; //括号运算符[]() 成员运算符. ->
全体单目第二; //所有的单目运算符比如++、 --、 +(正)、 -(负) 、指针运算*、&乘除余三,加减四; //这个"余"是指取余运算即%
移位五,关系六; //移位运算符:<< >> ,关系:> < >= <= 等
等于(与)不等排第七; //即== 和!=
位与异或和位或; //这几个都是位运算: 位与(&)异或(^)位或(|)
"三分天下"八九十;
逻辑或跟与; //逻辑运算符:|| 和 &&
十二和十一; //注意顺序:优先级(||) 底于 优先级(&&)
条件高于赋值, //三目运算符优先级排到13 位只比赋值运算符和","高
逗号运算级最低! //逗号运算符优先级最低
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/82149622
- 点赞
- 收藏
- 关注作者
评论(0)