Chapter 4 表达式
表达式基础
由1到多个操作数组成,可以求值并通常返回求值结果
- 最基本的表达式:变量、字面值
- 通常包含操作符/运算符
操作符特性
- 接收几个操作数(一元、二元、三元)
- 操作数的类型-类型转换
- 操作数是左值还是右值
- 结果的类型
- 结果是左值还是右值
- 优先级与结合性(cpp-reference),可用小括号修改运算顺序
- 操作符的重载——不改变操作数个数、优先级和结合性
操作数求值的不确定性
fun(x=x+1,x=x+1) // 两个参数的执行先后不确定
glvalue
:(泛左值)标识一个对象、位或函数prvalue
:(纯右值)用于初始化对象或作为操作数xvalue
:(亡值)表示其资源可以被重新使用分类方式:
1
2
3
4
5expression
/ \
glvalue rvalue
/ \ / \
lvalue xvalue prvalueC++中左值不一定能放在等号左边,右值可能放在等号左边;
再论decltype
- prvalue -> type:若表达式值类别为纯右值,则decltype产生T
- lvalue -> type&:若表达式值类别为左值,则decltype产生T&
- xvalue -> type&&:若表达式的值类别为亡值,则decltype产生T&&
类型转换
隐式转换:
- 自动发生
- 实际上是有限长度的转型序列
- implicit conversion
显式转换:
显式引入的转换
static_cast
static_cast<double>(3) + 0.5; // 把3转换为double
编译期执行
const_cast 可以改变const类型对象
dynamic_cast 运行期执行
reinterpret_cast 强行重新解释对象存储空间,对象值可能改变(存储格式不同)
C形式的类型转换
- ```C++ (double)3;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- 自动以以下顺序尝试转换对象:`const_cast -> static_cast -> static_cast(带扩展)后随const_cast -> reinterpret_cast -> reinterpret_cast后随const_cast`
### 算数操作符
- 三个优先级
- +, - (一元,正负)
- *, /, %
- +, - (二元)
- 均为左结合的,从左开始计算
- 操作数和结果均为算数类型的右值,但加减法和正号可接收指针
- 一元+操作符会产生integral promotion,例如short 转为int
- 整数相除会产生整数,舍弃小数点后的部分
- 求余 `%` 只能接收整数类型的操作数,**结果的符号与第一个操作数相同**
### 逻辑与关系操作符
- 逻辑操作符:
- !
- &&
- ||
- 关系操作符接收算数或指针类型操作数;
- 逻辑操作符接收可转换为bool值的操作数;
- 除逻辑非外,其它操作符都是左结合的
- 逻辑与、逻辑或具有短路特性,(A && B),如果A为假,则不判断B
- 逻辑与优先级 > 逻辑或 (a || b && c) 等价于 (a || (b && c))
- 不能写连续的不等于
- ```c++
auto res = (a <=> b) // a>b返回值大于0;a<b返回值小于0;a=b返回值等于0;
if (res > 0){
}else if (res < 0){
}else if(res == 0){
}
- ```C++ (double)3;
位操作符
- ```c++
-
// 按位非操作 & // 按位与操作 ^ // 按位异或操作 | // 按位或操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 没有短路机制
- 注意整数的符号与位操作的相关影响
- integral promotion 会根据整数的符号影响其结果
- 右移保持符号,但左移不能保证
### 赋值操作符
- 赋值操作是右结合的;
- 求值结果为左操作数;
- 区分=和==
- 复合赋值运算符
- ```c++
+=
-=
*=
/=
^=
自增与自减运算符
++ --
分为前缀和后缀情况
操作数为左值;前缀时返回左值;后缀时返回右值;
建议使用前缀形式
表达式详述-其它操作符
- 成员访问操作符:.和->
->
等价于(*)
.
的左操作数是左值或右值,返回左值或右值 xvalue._>
的左操作数指针,返回左值
- 条件操作符
- 唯一的三元操作符
true ? 3 : 5;//问号前面是true时,判断第一个表达式是否为真,并返回表达式结果;问号前是false时,判断第二个表达式是否为真,并返回表达式结果
- 接收一个可转换为bool的表达式与两个类型相同的表达式,只有一个表达式会被求值
- 第二个和第三个表达式类型需要一致
- 如果表达式均是左值,那么就返回左值,否则返回右值
- 右结合
- 唯一的三元操作符
- 逗号操作符
- 确保操作数会被从左向右求值
- 求值结果为右操作数
- 左结合
- sizeof操作符
- 操作数可以使一个类型或一个表达式
- 并不会实际求值,而是返回相应的尺寸
- 其它操作符
- 域解析操作符
::
- 函数调用操作符
()
- 索引操作符
[]
- 抛出异常操作符
throw
- ...
- 域解析操作符