Skip to content

Latest commit

 

History

History
172 lines (99 loc) · 6.14 KB

表达式.md

File metadata and controls

172 lines (99 loc) · 6.14 KB

Table of Contents generated with DocToc

操作符执行什么操作以及操作结果的类型取决于操作数的类型。

算术操作符

一元操作符优先级最高,其次是乘除,接着是二元的加减。

求模操作符%的操作数只能为整型,包括boolcharshortintlong以及对应的unsigned

两个操作数都是负数,除法结果为正,求模操作为负。如果只有一个操作数为负,这两种操作的结果取决于机器;求模结果的符号取决于机器,除法结果为负或零。

关系操作符和逻辑操作符

逻辑表达式存在短路求值。

不应该串接使用关系操作符 a > b > c。 

位操作符

如果操作数为负数,则位操作符如何处理其符号位依赖于机器。

移位操作的右操作数不可以是负数,且必须是小于左操作数的值,否则操作的效果未定义。

IO操作为左结合。 

赋值操作符

赋值操作符是右结合的,返回左值。

使用复合赋值+=时,左操作数只计算一次,而使用相似的长表达式时,左操作数计算两次。 

自增和自减操作符

*iter++ 等效于 *(iter++)

箭头操作符

箭头操作符相当于引用和指针操作符加上括号。

 (*p).foo 等价于 p->foo;

条件操作符

cond ? expr1 : expr2

cond肯定要计算,后两个只有一个表达式被计算。

避免条件操作符的深度嵌套。

在输出表达式中使用条件表达式,通常要用括号。

cout << (i < j ? i : j); //ok: prints larger of i and j
cout << (i <j) ? i : j; //print 1 or 0,相当于 cout << (i <j) ; cout ? i : j
cout << i < j ? i : j ; //error:compares cout to int

sizeof操作符

sizeof返回一个对象或类型名的长度,类型为size_tsizeof的结果是编译时常量。

sizeof作用于expr时,并没有计算表达式的值。

对数组做sizeof等效于对其元素类型做sizeof的结果乘以数组元素的个数,数组不会退化为指针!

逗号操作符

从左至右,其结果最右边表达式。 

复合表达式的求值

优先级和结合性决定了表达式的哪部分用作哪个操作符的操作数。

++的优先级高于*

除了&&||、条件和逗号操作符,C++并未指定其操作数的求值顺序。

处理复合表达式的原则:

1、尽量用括号。

2、要修改操作数的值,则不要再同一个语句的其他地方使用该操作数。也可以分成两个独立于语句。 

new和delete

如果不提供显式初始化,动态创建的对象与函数内定义的变量初始化方式相同:对于类类型的对象,用该类的默认构造函数,内置类型的对象无初始化。

int *pi = new int//pi points to an uninitialized int
int *pi = new int(); //pi points an int value-initialized to 0

new失败会抛出bad_alloc的异常。

如果指针指向的不是new分配的内存地址,那么delete就是不合法的。

零值指针,如果指针为0,则在其上做delete是合法的。

delete之后,该指针变成垂悬指针,很难检测。

允许创建动态的const对象。

以下三种常见的错误与动态内存分配有关:

  1. 删除指向动态分配内存的指针失败:内存泄漏。
  2. 读写已删除的对象。
  3. 对同一内存空间两次delete

类型转换

如果表达式的操作数分别为整数和浮点型,则整数转换为浮点型。

发生隐式转换的情况:

1、 混合类型的表达式中,其操作数转换为相同的类型。

2、 用作条件表达式转换为bool

3、 用同一表达式初始化或赋值某个变量。

算术转换

整数提升:所有比int小的整型,如果该类型的所有可能的值都能包容在int中,就被提升为int,否则就是被提升为unsigned int

包含signedunsigned int的表达式,signed会被转换为unsigned

使用数组时,大多数情况下,数组都会自动转换为指向第一个元素的指针。

指向任何数据类型的指针都可以转换为void*,整形数值常量0可转换为任意指针类型。

将枚举类型提升为什么类型,由机器定义,并依赖于枚举成员的最大值。

 

显式转换 cast-name<type>(expression)

  1. dynamic_cast 支持运行时识别指针或引用指向的对象。
  2.  const_cast 转换掉表达式的const性质。
  3. static_cast 隐式执行的任何类型转换都可以用它完成。
  4. reinterpret_cast 为操作数的位模式提供较低层次的重新解释。

旧式强制类型转换依赖于所涉及的数据类型,具有和const_cast,static_castreinterpret_cast一样的行为。

导航

目录

上一章:4. 数组和指针

下一章:[6. 语句](6. 语句.md)