引入
诸如下面这些表达式,它的计算过程,计算顺序是怎样的?计算结果为多少?
今天我们就一起来解决一下这个问题吧!
运算符的优先级
解决这个问题,首先我们必须要了解清楚各种运算符的优先级。
首先,可以简单记,!!>算术运算符>关系运算符>&&>||>赋值运算符
再详细一点记的话,可以根据下面的口诀来记忆。
括号成员第一; //括号运算符[](),成员运算符.
->
全体单目第二;//++ ,–,+(正),-(负),指针运算符*、&
乘除余三,加减四// 余即%
取余运算符
位移五,关系六//位移运算符<<
>>
,关系运算符>,<,≥,≤
等于(与)不等排第七// == 和! !=
位与异或和位或,三分天下,八九十//位与 &
第八,异或^
第九,位或|
第十
逻辑或跟与,十二和十一//逻辑 或||
十二,逻辑与&&
十一
条件高于赋值//三目运算符优先级排到13位只比赋值运算符和逗号运算符高
逗号运算级最低//,
运算级最低
更详细的可以看下面这张表(图片来源于)
算术表达式的运算规则
算术表达式的运算遵循运算符优先级和结合性的原则。
表达式运算的具体过程是:对表达式自左向右
扫描运算对象,然后考察运算对象两侧的运算符,如果运算对象两侧的运算符优先级不相同
则该运算对象和高
优先级的运算符结合;如果运算对象两侧的运算符优先级相同
时,则按照运算符的结合性原则
去结合,如果运算符是左结合的,则和左侧的运算符结合,如果是右结合的,则和右侧的运算符结合。当某运算符所需的运算对象全部都和该运算符结合后进行运算,运算后的中间结果
就是下一个被扫描到的运算对象,当某运算符所需的运算对象没有全部结合则继续扫描下一个运算对象。
引例
了解了上面运算符的优先级之后,我们来举个例子说明一下。
int a=3,b=1;
则下述表达式的值为:
分析
表达式a+b*5/6的具体运算过程是:
①对该表达式自左向右扫描,扫描到的第1个运算对象是变量a
,其左侧无运算符,右侧是运算符+
,于是a必须和+结合,而加法运算是双目
运算,无法进行运算,于是继续扫描下一个运算对象;
②扫描到的第2个运算对象是变量b
,其左侧+运算符,右侧是运算符*,*
的优先级高
于+,于是b必须和*结合,而乘法运算是双目运算,无法进行运算,于是继续扫描下一个运算对象;
③扫描到的第3个运算对象是常量5
,其左侧是*运算符,右侧是运算符/,*
和/
优先级相同
且是左结合
的,于是5必须和*结合,乘法运算的双目
都已经和*结合,于是完成b*5
乘法运算,得到中间结果为5
;
④中间结果5
就是要扫描的第4个运算对象,其左侧运算符+,右侧是运算符/,/
的优先级高
于+,于是5必须和/结合,而除法运算是双目
运算,无法进行运算,于是继续扫描下一个运算对象;
⑤扫描到的第5个运算对象是常量6
,其左侧运算符/,右侧无运算符,于是6必须和/结合,除法运算的双目都已经和/结合,于是完成5/6除法运算,得到中间结果
为0
;
⑥中间结果0
就是要扫描的第6个运算对象,其左侧运算符+,右侧无运算符,于是0必须和+
结合,
加法运算的双目
都已经和+结合,于是完成a+0
加法运算,得到结果为3,运算结束,得到表达式的结果为值3。
图解如下:
(上方的序号是运算过程,下方的序号为运算对象的排序)
例题
(一)
int x=3,y=4,z=5;
计算下表达式的值
分析过程如例题所示。
最终结果为1。
(二)
int x=3,y=4,z=5;
计算下述表达式的值
分析过程如下:
int a=3,b=2,c=1,f;
计算下表达式的值:
f=a>b>c;
分析过程如下:
这个表达式含关系运算
,关系运算的结果分为成立或者不成立,用逻辑量"0"和"1"表示。
关系运算符是左结合
运算符。
故表达式的值为0;
(三)
int m=2,n=1,a=1,b=2,c=3;
则执行完上面这个表达式之后,n的值为 ? m的值为?
分析过程如下:
故执行完上述的过程之后,n的值为0,m的值为1。
(四)
int m=5,y=2;
则计算表达式
y+=y-=m*=y
这个表达式中含复合的算术赋值运算符
。
什么是复合的算术赋值运算符呢?
就是在赋值运算符"="前加上其他的运算符,从而构成复合的赋值运算符。
C语言提供了5种复合的算术赋值运算符,分别是+=
,==
,*=
,/=
,%=
,复合的算术运算符是双目运算符,优先级和赋值运算符相同,也是右结合性的。
这个表达式的分析过程如下:
故y的值为-16。