第二篇 基本语言
第三章C++数据类型
3.1 文字常量
字符型char 通常用来表示单个字符和小整数它可以用一个机器字节来表示。
整型int 短整型short 长整型long 它们分别代表不同长度的整数值典型情况下short 以半个字表示int 以一个机器字表示而long 为一个或两个机器字在32 位机器中int 和long 通常长度相同。
浮点型float 双精度double 和长双精度long double 分别表示单精度浮点数双精度浮点数和扩展精度的浮点数值典型情况下float 为一个字double 是两个字long double 为三个或四个字。
整数文字常量可以被写成十进制八进制或者十六进制的形式这不会改变该整数值的位序列。
我们可以在文字常量后面加一个 L 或l 字母L 的大写形式或者小写形式将其指定为long 类型。
我们可以在整型文字常量的后面加上u 或U 将其指定为一个无符号数。
浮点型文字常量可以被写成科学计数法形式或普通的十进制形式使用科学计数法指数可写作e 或E 浮点型文字常量在缺省情况下被认为是double 型单精度文字常量由值后面的f 或F 来标示类似地扩展精度中值后面跟的l 或L 来指示注意”f””F””l””L” 后缀只能用在十进制形式中。
3.2 变量
变量为我们提供了一个有名字的内存存储区可以通过程序对其进行读写和处理。
变量和文字常量都有存储区并且有相关的类型区别在于变量是可寻址的addressable 对于每一个变量都有两个值与其相关联:
1.它的数据值。
2.它的地址值——即存储数据值的那块内存的地址。
变量名即变量的标识符identifier 可以由字母数字以及下划线字符组成它必须以字母或下划线开头并且区分大写字母和小写字母语
对于命名对象有许多已普遍接受的习惯主要考虑因素是程序的可读性:
对象名一般用小写字母例如我们往往写成index 而不写INDEX 一般把Index当作类型名而INDEX 则一般被看作常量值通常用预处理器指示符#define 定义
标识符一般使用助记的名字——即能够对程序中的用法提供提示的名字如on_loan 或salary 至于是应写成table 还是tbl 这纯粹是风格问题不是正确性的问题
对于多个词构成的标识符习惯上一般在每个词之间加一个下划线或内嵌的每个词第一个字母大写例如一般会写成student_loan 或studentLoan 而不是studentloan
如果一个变量是在全局域(global scope)内定义的那么系统会保证给它提供初始值0 。
在因为使用未初始化对象是个常见错误而且很难发现所以一般建议为每个被定义的对象提供一个初始值。
3.3 指针类型
我们通过在标识符前加一个解引用操作符(*)来定义指针。
3.4 字符串类型
C++提供了两种字符串的表示C 风格的字符串和标准 C++引入的string 类类型。
3.5 const 限定修饰符
3.6 引用类型
引用(reference)有时候又称为别名(alias)它可以用作对象的另一个名字。
3.7 布尔类型
布尔型对象可以被赋以文字值true 或false。
当表达式需要一个算术值时布尔对象(如found)和布尔文字都被隐式地提升成 int(false 变成0 而true 变成1)。
正如文字false 和true 能自动转换成整数值0 和1 一样。如果有必要算术值和指针值也能隐式地被转换成布尔类型的值。0 或空指针被转换成false 所有其他的值都被转换成true
3.8 枚举类型
枚举类型用关键字enum 加上一个自选的枚举类型名来定义,类型名后面跟一个用花括号括起来的枚举成员列表枚举成员之间用逗号分开。在缺省情况下第一个枚举成员被赋以值0 ,后面的每个枚举成员依次比前面的大1。
3.9 数组类型
数组定义由类型名,标识符和维数组成。维数指定数组中包含的元素的数目,它被写在一对方括号里边。我们必须为数组指定一个大于等于1 的维数。维数值必须是常量表达式——即必须能在编译时刻计算出它的值。
数组可以被显式地用一组数来初始化,这组数用逗号分开,放在大括号中。
多维数组的索引访问要求对程序员希望访问的每个索引都有一对方括号。
数组标识符代表数组中第一个元素的地址,它的类型是数组元素类型的指针在。
3.10 vector 容器类型
vector 类为内置数组提供了一种替代表示。
3.11 复数类型
3.12 typedef 名字
typedef 机制为我们提供了一种通用的类型定义设施,可以用来为内置的或用户定义的数据类型引入助记符号。
3.13 volatile 限定修饰符
编译器执行的某些例行优化行为不能应用在已指定为volatile 的对象上。
volatile 限定修饰符的用法同const 非常相似——都是作为类型的附加修饰符。
volatile 修饰符的主要目的是提示编译器,该对象的值可能在编译器未监测到的情况下被改变。因此编译器不能武断地对引用这些对象的代码作优化处理。
3.14 pair 类型
pair 类也是标准库的一部分。它使得我们可以在单个对象内部把相同类型或不同类型的两个值关联起来。
3.15 类类型
类的定义由关键字class 开始,后面是一个标识符,该标识符也被用作类的类型指示符.
第四章 表达式
4.1 什么是表达式?
表达式由一个或多个操作数(operand)构成。
作用在一个操作数上的操作符被称为一元操作符(unary operator),比如取地址操作符(&)和解引用操作符(*) 。
作用在两个操作数上的操作符比如加法操作符减法操作符被称为二元操作符(binary operator)。
当两个或两个以上的操作符被组合起来的时候这样的表达式被称为复合表达式(compound expression)。
子表达式的计算顺序由操作符的优先级(precedence)和结合性(associativity)来决定。
4.2 算术操作符
操作符 | 功能 | 用法 |
* | 乘 | expr * expr |
/ | 除 | expr / expr |
% | 求余 | expr % expr |
+ | 加 | expr + expr |
- | 减 | expr - expr |
4.3 等于,关系和逻辑操作符
操作符 | 功能 | 用法 |
! | 逻辑非 | !expr |
< | 小于 | expr < expr |
<= | 小于等于 | expr <= expr |
> | 大于 | expr > expr |
>= | 大于等于 | expr >= expr |
== | 等于 | expr == expr |
!= | 不等于 | expr != expr |
&& | 逻辑与 | expr && expr |
|| | 逻辑或 | expr || expr |
这些操作符的结果是bool 类型。
等于,关系和逻辑操作符的计算结果是布尔常量true 或false。如果这些操作符用在要求整数值的上下文环境中它们的结果将被提升成1(true)或0(false)。
4.4 赋值操作符
复合赋值操作符的一般语法格式是 a op= b;
这里的op=可以是下列十个操作符之一 += -= *= /= %= <<= >>= &= ^= |=
每个复合赋值操作符都等价于以下普通写法的赋值 a = a op b;
4.5 递增和递减操作符
递增(++)和递减(--)操作符为对象加1 或减1 操作提供了方便简短的表示。它们最一般的用法是对索引,迭代器或指向一个集合内部的指针加1 或减1 。
4.6 复数操作
标准库提供的复数(complex)类是基于对象的类抽象的完美模型。
4.7 条件操作符
条件操作符为简单的if-else 语句提供了一种便利的替代表示法。
4.8 sizeof 操作符
siseof 操作符的作用是返回一个对象或类型名的字节长度。
返回值的类型是size_t ,这是一种与机器相关的typedef 定义。
4.9 new 和delete 表达式
4.10 逗号操作符
逗号表达式是一系列由逗号分开的表达式。
这些表达式从左向右计算。
逗号表达式的结果是最右边表达式的值。
4.11 位操作符
操作符 | 功能 | 用法 |
~ | 按位非 | ~expr |
<< | 左移 | expr1 << expr2 |
>> | 右移 | expr1 >> expr2 |
& | 按位与 | expr1 & expr2 |
^ | 按位异或 | expr1 ^ expr2 |
| | 按位或 | expr1 | expr2 |
&= | 按位与赋值 | expr1 &= expr2 |
^= | 按位异或赋值 | expr1 ^= expr2 |
|= | 按位或赋值 | expr1 |= expr2 |
位操作符把操作数解释成有序的位集合,这些位可能是独立的,也可能组成域(field)。
每个位可以含有0(off)或1(on)。位操作符允许程序员设置或测试独立的位或位域。
4.12 bitset 操作
操作符 | 功能 | 用法 |
test( pos ) | pos 位是否为1 | a.test( 4 ) |
any() | 任意位是否为1 | a.any() |
none() | 是否没有位为1 | a.none() |
count() | 值是1 的位的个数 | a.count() |
size() | 位元素的个数 | a.size() |
[pos] | 访问pos 位 | a[ 4 ] |
flip() | 翻转所有的位 | a.flip() |
flip( pos ) | 翻转pos 位 | a.flip( 4 ) |
set() | 将所有位置1 | a.set() |
set( pos ) | 将pos 位置1 | a.set( 4 ) |
reset() | 将所有位置0 | a.reset() |
reset(pos) | 将pos 位置0 | a.reset( 4 ) |
用to_string()操作将任意bitset 对象转换成string 表示string bitval( bitvec3.to_string());
用to_ulong()操作将任意bitset 对象转换成unsigned long 型的整数表示,只要该bitset 对象的底层表示能用一个unsigned long 来表示。
4.13 优先级
操作符优先级是指复合表达式中操作符计算的顺序。
4.14 类型转换
4.14.1 隐式类型转换
1.在混合类型的算术表达式中。在这种情况下,最宽的数据类型成为目标转换类型。这也被称为算术转换(arithmetic conversion)。
2.用一种类型的表达式赋值给另一种类型的对象。目标转换类型是被赋值对象的类型。
3. 把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同。目标转换类型是形式参数的类型。
4. 从一个函数返回一个表达式,表达式的类型与返回类型不相同。目标转换类型是函数的返回类型。
4.14.2 算术转换
算术转换保证了二元操作符(如加法或乘法)的两个操作数被提升为共同的类型。两个通用的指导原则如下:
1.为防止精度损失,如果必要的话,类型总是被提升为较宽的类型。
2. 所有含有小于整型的有序类型的算术表达式在计算之前其类型都会被转换成整型。
4.14.3 显式转换
显式转换也被称为强制类型转换(cast),包括下列命名的强制类型转换操作符:
static_cast,dynamic_cast,const_cast 和reinterpret_cast。
1.void*型指针不能直接被解除引用,因为没有类型信息可用来指导编译器怎样解释底层的位模式。相反,void*的指针必须先被转换成某种特定类型的指针。
2.改变通常的标准转换。
3.要避免出现多种转换可能的歧义情况
显式转换符号的一股形式如下: cast-name< type >( expression );
const_cast, 正如其名字所暗示的,将转换掉表达式的常量性(以及volatile 对象的volatile性)。
编译器隐式执行的任何类型转换都可以由static_cast 显式完成。
4.14.4 旧式强制类型转换
只有当我们为C 语言或标准C++之前的编译器编写代码时才使用这种语法。
4.15 栈类实例
第五章 语句
5.1 简单语句和复合语句
5.2 声明语句
5.3 if 语句
5.4 switch 语句
5.5 for 循环语句
首先进行条件的真值测试。
5.6 while 语句
首先进行条件的真值测试。
5.7 do while 语句
保证语句或语句块至少被执行一次——在这些语句被执行之后进行条件测试。
5.8 break 语句
break 语句终止最近的while,do while,for或switch 语句。程序的执行权被传递给紧接着被终止语句之后的语句。
终止整个循环。
5.9 continue 语句
continue 语句导致最近的循环语句的当前迭代结束,执行权被传递给条件计算部分。
终止当前的迭代。
5.10 goto 语句
goto 语句提供了函数内部的无条件分支,它从goto 语句跳转到同一函数内部某个位置的一个标号语句。
第六章 抽象容器类型