第四章 表达式
本章内容繁杂且没有什么规律,却是极其重要的一讲。
4.1基础部分
1.一元运算符和二元运算符,这二者继承自c语言,一元运算符指对一个对象进行运算,二元运算符则是对俩个对象进行运算,例如*,==,就是对俩个对象进行运算,而*,&是一元运算符
2.组合运算符和运算对象:对于含有多个运算符的复杂表达式来说,要想理解他的含义必须理解运算符的优先级和结合律,稍后会介绍这一点。
3.运算对象的转换:很多时候其实类型不同的对象也可以存在与同一表达式(只要他们可以转换为同一类型)
4.重载运算符:当运算符作用与类类型的运算对象时,用户可以自行定义其含义。这种行为类似于重载,因此又叫重载运算符(overloaded operator)。i/o库中的<<,>>都是重载运算符。
5.左值和右值:c++的表达式只存在右值和左值,当一个对象被当作右值时,用的是对象的值,当作左值是,用的是对象的身份,即使用他的位置。
4.1.2优先级和结合律
复合表达式(compound expression)是指含有俩个或多个运算符的表达式。**编写程序时可以用括号来辅助运算。
4.1.3求值顺序
对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误以及未定义的操作,eg:
cout<
另外明确规定了求值顺序的只有&&,||,?;,和逗号运算符。
4.2算术运算符
运算符 | 功能 | 用法 |
+ | 一元正号 | + expr |
- |
一元负号 | - expr |
* | 乘号 | expr*expr |
/ | 除法 | expr/expr |
% | 求余 | expr%expr |
+ | 加法 | expr+expr |
- | 减法 | expr-expr |
***一元负号运算符对运算对象值取负后,返回其副本 eg:
bool b=ture;
bool b2=-b;//b2是ture!因为-b是-1,而不是0!因此说bool值不适合加入运算中。
4.3逻辑和关系运算符
结合律 | 运算符 | 功能 | 用法 |
---|---|---|---|
右 | ! | 逻辑非 | !expr |
左 | < | 小于 | expr<expr |
左 | > | 大于 | expr>expr |
左 | <= | 小于等于 | expr<=expr |
左 | >= | 大于等于 | expr>=expr |
左 | == | 相等 | expr==expr |
左 | != | 不等于 | expr!=expr |
左 | && | 逻辑与 | expr&&expr |
左 | || | 逻辑或 | expr||expr |
**这里重点注意&&与||,若&&第一个元素值为0,就不再执行第二个表达式,若||第一个元素为1,就不再执行第二个表达式
4.4赋值运算符
赋值运算符的左边必须是一个左值
赋值运算符满足右结合律
***int i=j=0;//成立,都被赋值为零
4.5递增和递减运算符
递增或递减运算符有前置和后置版本,前置版本就是在表达式之前将对象加一,而后置版本完成这一过程是在调动对象后
4.6成员访问运算符->
eg:ptr->mem;等价于(*ptr).mem;
4.7条件运算符
条件运算符?:是if else的另一种形式。
eg:string finalgrade=(grade<60)?"final":"pass";//表达式成立,则返回第一个,反之,返回第二个。
4.8 sizeof()运算符
sizeof()运算符返回一条表达式或一个类型名字所占的字节数。
eg:Sales_data data,*p;
sizeof(sales_data);//返回一个sale_data的所占字节数
sizeof data;//同上
***sizeof()运算符的结果部分地依赖于其作用的类型
1.对char类型的表达式执行sizeof,得1
2.对引用类型执行sizeof,得被引用类型的大小
3.对指针执行sizeof(),得到指针本身所占空间的大小
4.对解引用指针,得到指针所指向对象类型的大小。
5.对数组执行sizeof,得到数组所占空间的大小,等价于对数组中所有元素各执行一次然后求和。
4.10逗号运算符
逗号运算符含有俩个运算对象,按照从左往右的顺序依次取值。首先求出左侧表达式的值,然后将左侧表达式的值抛弃掉,他的真实值是右侧表达式的值