一、算数运算符
算术运算符表:
运算符 | 功能 | 用法 |
+ | 一元正号 | +expr |
- | 一元负号 | -expr |
* | 乘法 | expr * expr |
/ | 除法 | expr / expr |
% | 求余 | expr % expr |
+ | 加法 | expr + expr |
- | 减法 | expr - expr |
上表所有运算符都满足左结合律,意味着当优先级相同时按照从左向右的顺序进行组合。
1、算数运算符的运算对象和求值结果都是右值。
2、对大多数运算符来说,布尔类型的运算对象将被提升为int类型。
3、c++11新标准规定商一律向0取整(即直接切除小数部分)。
4、根据取余运算的定义,如果m和n是整数且n非0,则表达式(m/n)*n+m%n的求值结果与m相等。隐含的意思是,如果m%n不等于0,则它的符号与m相同。除了-m导致溢出的情况,其他时候(-m)/n=-(m/n),m/(-n)=-(m/n),m%(-n)=m%n,(-m)%n=-(m%n),具体示例如下:
1 int main() 2 { 3 int x1 = 21 / 6, y1 = 21 % 6; 4 int x2 = 21 / 7, y2 = 21 % 7; 5 int x3 = (-21) / (-8), y3 = (-21) % (-8); 6 int x4 = 21 / (-5), y4 = 21 % (-5); 7 std::cout << x1 << "," << y1 << std::endl; 8 std::cout << x2 << "," << y2 << std::endl; 9 std::cout << x3 << "," << y3 << std::endl; 10 std::cout << x4 << "," << y4 << std::endl; 11 return 0; 12 }
二、逻辑和关系运算符
结合律 | 运算符 | 功能 | 用法 |
右 | ! | 逻辑非 | !expr |
左 | < | 小于 | expr < expr |
左 | <= | 小于等于 | expr <= expr |
左 | > | 大于 | expr > expr |
左 | >= | 大于等于 | expr >= expr |
左 | == | 相等 | expr == expr |
左 | != | 不相等 | expr != expr |
左 | && | 逻辑与 | expr && expr |
左 | || | 逻辑或 | expr || expr |
关系运算符作用于算术类型或指针类型,逻辑运算符作用于任意能转换成布尔值的类型。逻辑运算符和关系运算符的返回值都是布尔类型,运算对象和求值结果都是右值。
对于逻辑与运算符来说,当且仅当左侧运算对象为真时才会对右侧运算对象求值。对于逻辑或运算符来说,当且仅当左侧运算对象为假时才会对右侧运算对象求值。
三、赋值运算符
赋值运算符的左侧运算对象必须是一个可修改的左值。赋值运算符满足右结合律。
C++11新标准允许使用花括号括起来的初始值列表作为赋值语句的右侧运算对象。如果左侧运算对象是内置类型,那么初始值列表最多只能包含一个值,而且该值即使转换的话其所占空间也不应该大于左侧运算对象类型的空间。无论左侧运算对象的类型是什么,初始值列表可以为空,此时,编译器将创建一个值初始化的临时变量并将其赋给左侧运算对象。
四、递增和递减运算符
递增和递减运算符有两种形式:前置版本和后置版本。前置版本首先将运算对象加1(减1),然后将改变后的对象作为求值结果。后置版本也会将运算对象加1(减1),但是求值结果是运算对象改变之前那个值的副本。
五、成员访问运算符
点运算符和箭头运算符都可用于访问成员,其中,点运算符获取类对象的一个成员;箭头运算符和点运算符有关,表达式ptr->mem等价于(*ptr).mem。
六、条件运算符
条件运算符(?:)允许我们把简单的if-else逻辑嵌入到单个表达式中,条件运算符按照如下形式使用:
cond?expr1:expr2
其中cond是判断条件的表达式,而expr1和expr2是两个类型相同或可能转换为某个公共类型的表达式。条件运算符满足右结合律。
七、位运算符
位运算符作用于整数类型的运算对象,并把运算对象看成是二进制位的集合。位运算符都满足左结合律。
运算符 | 功能 | 用法 |
~ | 位求反 | ~expr |
<< | 左移 | expr1 << expr2 |
>> | 右移 | expr1 >> expr2 |
& | 位与 | expr & expr |
^ | 位异或 | expr ^ expr |
| | 位或 | expr | expr |
一般来说,如果运算对象是“小整型”,则它的值会被自动提升成较大的整数类型。运算对象可以是带符号的,也可以是无符号的。如果运算对象是带符号的且它的值为负,那么位运算符如何处理运算对象的“符号位”依赖于机器。而且,此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。
八、sizeof运算符
sizeof运算符返回一条表达式或一个类型名字所占的字节数。sizeof运算符满足右结合律,其所得的值是一个size_t类型的常量表达式。运算符的运算对象有2种形式:
sizeof (type)
sizeof expr
在第2种形式中,sizeof返回的是表达式结果类型的大小。
sizeof运算符的结果部分地依赖于其作用的类型:
- 对char或者类型为char的表达式执行sizeof运算,结果得1。
- 对引用类型执行sizeof运算得到被引用对象所占空间的大小。
- 对指针指向sizeof运算得到指针本身所占空间的大小。
- 对解引用指针指向sizeof运算得到指针指向的对象所占空间的大小,指针不需要有效。
- 对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。sizeof运算不会把数组转换成指针处理。
- 对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间。
九、逗号运算符
逗号运算符含有两个运算对象,按照从左向右的顺序依次求值。和逻辑与、逻辑非以及条件运算符一样,逗号运算符也规定了运算对象求值的顺序。
对于逗号运算符来说,首先对左侧的表达式求值,然后将求值结果丢弃掉。逗号运算符真正的结果是右侧表达式的值。如果右侧运算对象是左值,那么最终的求值结果也是左值。