c++定义了一元运算符(&,*)、二元运算符(==,+)、三元运算符、函数调用也是一种特殊的运算符(运算对象的数量没有限制)。有的运算符既可以作为一元运算符也可以作为二元运算符,如*,具体情况由上下文决定。对于含有多个运算符的复杂表达式来说,想要理解它的含义首先要理解运算符的优先级、结合律、和运算对象的求值顺序。
优先级:优先级决定了运算对象的组合方式,高优先级的运算对象比低优先级对象优先组合在一起。
结合律:对于优先级相同的运算符,其进一步组合由结合律确定。
求值顺序:运算对象的求值顺序。
大多数情况下,不会明确指定求值的顺序,也是为了代码的生成效率,对于没有指定执行顺序的运算符来说,如果表达式指向并修改了同一对象,将会产生未定义的行为:
int i = 0;
cout << i <<" "<<++i << endl;//按理说结果应该是0 1,在vs2013上运行的结果是1 1
有4中运算符明确规定了运算对象的求值顺序:
- 逻辑与(&&):先求左侧对象的值,左侧为真时才求右侧对象的值。
- 逻辑或(||):先求左侧对象值,左侧为假时才求右侧对象的值。
- 条件运算符(?:):
- 逗号运算符(,):
一、算数运算符
表达式求值之前,小整数运算对象会被提升成较大的整数类型,所有运算对象最终转换成同一类型。都满足左结合律,按照优先级从高到低顺序:
(1)一元正号(+)、一元负号(-):
+作用于一个指针或算术值时,返回运算对象的一个(提升后的)副本。
-对运算对象值取负后,返回其(提升的)副本:
bool b=true;
bool b2=-b;//b2是true,-1转换成bool值是1
(2)乘法(*)、除法(/)、求余(%):
/:整数相除结果还是整数,同号为正,异号为负。
%:参与取余运算的对象必须是整数。如果m%n的结果不为0,结果的符号与m相同。
最终:(m/n)*n+m%n=m
(3)加法(+)、减法(-)
二、逻辑和关系运算符
关系运算符:>、<、>=、<=、==、!=
逻辑运算符:&&、||、!
其中,逻辑非(!)优先级最高,其次是大小关系运算符(>、<、>=、<=),然后是相等关系运算符(==和!=),然后是逻辑与(&&),最后是逻辑或(||)。
&&和||使用短路求值法:
- 逻辑与(&&):先求左侧对象的值,左侧为真时才求右侧对象的值。
- 逻辑或(||):先求左侧对象值,左侧为假时才求右侧对象的值。
逻辑与的左侧运算对象是为了确保右侧对象求值过程的正确性和安全性:
index!=s.size()&&!isspace(s[index]);//首先检查index是否到达对象末尾,只有index在合理范围才会计算右侧对象的值