第四章 表达式
第四章 表达式
表达式基础
- 重载运算符:当运算符作用在类类型的运算对象时,用户可以自行定义其含义。
- 左值和右值:
- C中原意:左值可以在表达式左边,右值不能。
C++
:当一个对象被用作右值的时候,用的是对象的值(内容);- 被用做左值时,用的是对象的身份(在内存中的位置)。
算术运算符
- 溢出:当计算的结果超出该类型所能表示的范围时就会产生溢出。
逻辑运算符
- 短路求值:逻辑与运算符和逻辑或运算符都是先求左侧运算对象的值再求右侧运算对象的值,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。
赋值运算符
- 如果赋值运算的左右侧运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型。
- 赋值运算符满足右结合律,这点和其他二元运算符不一样。
ival = jval = 0;
等价于ival = (jval = 0);
- 赋值运算优先级比较低。
条件运算符
- 条件运算符(
?:
)允许我们把简单的if-else
逻辑嵌入到单个表达式中去,按照如下形式:cond? expr1: expr2
位运算符
- 位运算符是作用于整数类型的运算对象。
- 二进制位向左移(
<<
)或者向右移(>>
),移出边界外的位就被舍弃掉了。 - 位取反(
~
)、与(&
)、或(|
)、异或(^
)
sizeof运算符
- 返回一条表达式或一个类型名字所占的字节数。返回的类型是
size_t
。 - 两种形式:
sizeof (type)
和sizeof expr
类型转换
隐式类型转换
- 比
int
类型小的整数值先提升为较大的整数类型。 - 条件中,非布尔转换成布尔。
- 初始化中,初始值转换成变量的类型。
- 算术运算或者关系运算的运算对象有多种类型,要转换成同一种类型。
- 函数调用时。
显式类型转换(尽量避免)
- static_cast:任何明确定义的类型转换,只要不包含底层const,都可以使用。
double slope = static_cast<double>(j);
- dynamic_cast:支持运行时类型识别。
- const_cast:只能改变运算对象的底层const,一般可用于去除const性质。
const char *pc; char *p = const_cast<char*>(pc)
- reinterpret_cast:通常为运算对象的位模式提供低层次上的重新解释。
P120-P151
4.1 基础 重载运算符:为已经存在的运算符赋予了另外一层含义。
左值、右值:
当一个对象用作右值得时候,用的是对象的值(内容)。
当对象被用作左值得时候,用的是对象的身份(在内存中的位置)。
4.2 算术运算符 %:参与取余运算的运算对象必须是整数类型。
4.3 逻辑和关系运算符
运算符 |
---|
! |
< |
<= |
> |
>= |
== |
!= |
&& |
&& 运算符和 || 运算符都是先求左侧运算对象的值再求右侧运算对象的值。
注意
进行比较运算的时候,除非比较的对象是bool类型,否则不要使用布尔字面值true,false作为运算对象。
4.4 赋值运算符 赋值运算符满足右结合律。
不要混淆相等运算符和赋值运算符
if (i = j)
if (i == j)
4.5 递增和递减运算符 递增运算符 ++
递减运算符 --
4.6 成员访问运算符 点运算符和箭头运算符
n = (*p).size();
n = p->size();
4.7 条件运算符
condition ? expression1 : expression2;
4.8 位运算符 | 运算符 | 功能 | 用法 | 备注 | | :----- | ------ | -------------- | :------------------------------------------- -- | | ~ | 位求反 | ~expr | 1置为0,0置为1 | | << | 左移 | expr << expr2 | 在右侧插入值位0的二进制位 | | >> | 右移 | expr1 >> expr2 | | | & | 位与 | expr1 & expr2 | 对应位置都是1,则结果1,否则为0。 | | ^ | 位异或 | expr1 ^ expr2 | 对应位置有且只有1个为1,则结果是1,否则为0。| | | | 位或 | expr1 | expr2 | 对应位置至少有1个位1,则结果是1,否则为0。 |
4.9 sizeof运算符
sizeof运算符返回一条表达式或一个类型名字所占的字节数,其所得值是一个size_t类型,是一个常量表达式。
sizeof (type)
sizeof expr
4.10 逗号运算符 逗号运算符含有两个运算对象,按照从左向右的顺序依次求值。
4.11 类型转换 隐式转换
显式转换
命名的强制类型转换
cast-name<type>(expression)
// cast-name是static_cast,dynamic_cast,const_cast,reinterpret_cast
由于强制类型转换干扰了正常的类型检查,因此建议避免强制类型转换。