第1章 C++介绍 1
1.1 程序与编程语言 1
1.1.1 计算机是什么 1
1.1.2 计算机编程 3
1.1.3 编译器、解释器和C++语言 4
1.1.4 C++语言介绍 4
1.1.5 C++程序开发步骤 5
1.2 C++程序结构 6
1.2.1 最简单的C++程序 6
1.2.2 函数 6
1.2.3 语句 7
1.2.4 程序注释 7
1.2.5 hello world程序 8
1.2.6 标准输入输出库和cout 8
1.2.7 名字空间 9
1.2.8 字符串和字符 10
1.2.9 运算符和运算数 11
1.2.10 宏定义# define 12
1.2.11 变量 13
1.2.12 标准输入流对象cin 14
1.2.13 用户定义类型 14
1.3 数和字符的表示 15
1.3.1 数的表示 15
1.3.2 字符的表示 17
1.4 编译、执行C++程序 19
1.5 习题 20
第2章 变量和类型 23
2.1 变量 23
2.1.1 变量的定义及初始化 23
2.1.2 auto 24
2.1.3 typeid运算符 24
2.1.4 decltype 25
2.1.5 赋值运算符= 25
2.1.6 const 25
2.1.7 标识符、关键字、文字量 26
2.2 数据类型 26
2.2.1 基本类型 27
2.2.2 sizeof运算符 29
2.2.3 文字量 30
2.2.4 格式化输出 33
2.2.5 类型转换 34
2.2.6 类型别名 36
2.2.7 枚举 37
2.3 局部变量与全局变量、变量的作用域与生命期 37
2.3.1 程序块、局部变量和全局变量 37
2.3.2 作用域和生命期 38
2.4 习题 39
第3章 运算符与表达式 42
3.1 运算符 42
3.1.1 运算符的分类 42
3.1.2 优先级和结合性 43
3.2 表达式 44
3.3 算术运算符 44
3.3.1 算术运算符需要注意的几个问题 45
3.3.2 自增++和自减-- 46
3.3.3 数学计算函数库cmath 47
3.4 位运算 49
3.5 赋值运算符 51
3.6 关系运算符 52
3.7 逻辑运算符 54
3.8 特殊运算符 54
3.8.1 条件运算符 54
3.8.2 逗号运算符 55
3.9 习题 55
第4章 语句 58
4.1 简单语句、复合语句和控制语句 58
4.1.1 简单语句 58
4.1.2 复合语句 58
4.1.3 控制语句 59
4.2 条件语句 59
4.2.1 if语句 59
4.2.2 switch语句 62
4.2.3 if/switch语句中的初始化语句 65
4.3 循环语句 66
4.3.1 while语句 66
4.3.2 for语句 68
4.4 跳转语句 69
4.5 实战:控制台游戏——Pong游戏 70
4.5.1 Pong游戏 70
4.5.2 初始化 71
4.5.3 绘制场景 71
4.5.4 让球动起来 73
4.5.5 事件处理:用挡板击打球 77
4.6 习题 78
第5章 复合类型:数组、指针和引用 82
5.1 引用 82
5.2 指针 83
5.2.1 指针类型 83
5.2.2 指针的其他运算 85
5.2.3 void*无类型指针 85
5.2.4 指针的指针 86
5.2.5 指针的引用 87
5.2.6 引用和指针的比较 87
5.3 数组 87
5.3.1 数组和下标运算符 87
5.3.2 复杂的数组声明 89
5.3.3 C风格字符串 90
5.3.4 指针访问数组 91
5.3.5 range for 94
5.3.6 多维数组 95
5.4 动态内存 98
5.4.1 程序堆栈区 98
5.4.2 new和delete运算符 99
5.4.3 动态内存表示多维数组 101
5.5 const修饰符 102
5.5.1 const和指针 102
5.5.2 const对象的引用 104
5.6 实战:查找、排序、最短路径 105
5.6.1 二分查找 105
5.6.2 排序:冒泡、选择 108
5.6.3 Floyd最短路径算法 109
5.7 习题 113
第6章 函数 119
6.1 函数是命名的程序块 119
6.1.1 最大公约数 119
6.1.2 函数的定义 122
6.2 静态变量 124
6.3 函数的形参 125
6.3.1 参数传递 125
6.3.2 默认参数 126
6.3.3 数组作为形参 127
6.3.4 const与形参 129
6.3.5 可变数目的形参 129
6.4 递归函数:调用自身的函数 131
6.4.1 递归和递归函数 131
6.4.2 实战:二分查找的递归实现 133
6.4.3 实战:汉诺塔问题 133
6.4.4 实战:快速排序算法 135
6.4.5 实战:迷宫问题 137
6.5 函数重载与重载解析 139
6.5.1 函数重载 139
6.5.2 重载解析 140
6.5.3 const对象的引用或指针 142
6.6 inline函数 142
6.7 constexpr 143
6.8 实战:二维字符图形库ChGL 145
6.8.1 如何在字符终端上绘图 145
6.8.2 字符图形库ChGL 146
6.8.3 曲线绘制API函数plot() 149
6.9 实战:基于ChGL的控制台游戏 151
6.9.1 游戏程序的框架 151
6.9.2 用ChGL和函数重写Pong游戏 151
6.10 实战:机器学习-线性回归 156
6.10.1 机器学习 156
6.10.2 假设函数、回归和分类 157
6.10.3 线性回归 157
6.10.4 多变量函数的最小值、正规方程 158
6.10.5 梯度下降法 159
6.10.6 梯度下降法求解线性回归问题:模拟数据 160
6.10.7 批梯度下降法 165
6.10.8 房屋价格预测 166
6.10.9 样本特征的规范化 167
6.10.10 预测房屋价格 170
6.11 习题 170
第7章 类和对象 174
7.1 面向对象编程 174
7.2 类 177
7.2.1 定义一个类 177
7.2.2 定义类的对象(变量) 178
7.2.3 成员函数 180
7.2.4 this指针 180
7.2.5 类对象的大小 183
7.3 构造函数 183
7.3.1 创建类对象的构造函数 183
7.3.2 初始化成员列表 187
7.3.3 拷贝构造函数 187
7.3.4 赋值运算符:operator= 189
7.3.5 隐式类型转换、explicit 190
7.3.6 委托构造函数 192
7.3.7 delete 193
7.3.8 类对象数组 193
7.3.9 类体外定义成员函数和构造函数 194
7.4 访问控制和接口 195
7.5 const对象、const成员函数、mutable成员变量 196
7.5.1 const对象和const成员函数 196
7.5.2 重载const 198
7.5.3 mutable成员变量 200
7.6 析构函数 200
7.7 静态成员 202
7.7.1 非静态成员变量和静态成员变量 202
7.7.2 静态常量 204
7.7.3 静态成员函数 205
7.7.4 类自身类型的静态成员变量 205
7.8 友元 207
7.9 内联成员函数 207
7.10 重新定义拷贝构造函数和赋值运算符函数 208
7.11 实战:线性表及应用 209
7.11.1 线性表 209
7.11.2 线性表的顺序实现:顺序表 211
7.11.3 线性表的链式实现:链表 215
7.11.4 实现一个图书管理的程序 222
7.12 实战:面向对象游戏——基于链表的贪吃蛇游戏 224
7.12.1 面向对象游戏引擎 224
7.12.2 贪吃蛇游戏 226
7.13 习题 237
第8章 运算符重载 242
8.1 运算符重载的2种方式 242
8.2 赋值运算符= 246
8.3 下标运算符[] 246
8.4 输入输出运算符 247
8.5 比较运算符 248
8.6 函数调用运算符() 250
8.7 类型转换运算符 250
8.8 自增和自减运算符 252
8.9 可以重载的运算符 253
8.10 实战:矩阵 253
8.11 习题 257
第9章 派生类 259
9.1 继承与派生 259
9.1.1 继承关系和派生类 259
9.1.2 is a和belong to 260
9.1.3 派生类的定义 260
9.1.4 成员的隐藏 261
9.1.5 继承方式 263
9.1.6 基类指针和派生类指针 264
9.2 派生类的构造函数和析构函数 266
9.3 多继承和虚基类 272
9.3.1 多继承 272
9.3.2 虚基类 274
9.4 多态 276
9.4.1 对象的切割和类型转换 276
9.4.2 基类指针(引用)和向下类型转换 277
9.4.3 虚函数和多态 280
9.4.4 虚函数的一些语法规则 283
9.4.5 基类指针数组 285
9.4.6 虚析构函数 286
9.4.7 纯虚函数和抽象类 286
9.5 实战:仿“雷电战机”游戏 288
9.5.1 精灵 288
9.5.2 游戏引擎GameEngine 291
9.5.3 碰撞检测和精灵的销毁 295
9.5.4 让敌方战机运动和发射子弹 297
9.6 习题 300
第10章 模板 305
10.1 函数模板 305
10.1.1 函数模板的定义与实例化 306
10.1.2 模板参数推断 307
10.1.3 模板专门化 308
10.1.4 函数模板和重载 309
10.1.5 模板的返回类型推断 310
10.1.6 非类型模板参数 311
10.1.7 模板模板参数 313
10.1.8 模板参数的默认值 313
10.1.9 可变模板参数 314
10.1.10 constexpr if 317
10.2 类模板 317
10.2.1 标准库类模板vector 317
10.2.2 类模板Vector 320
10.2.3 定义类模板的成员函数 321
10.2.4 类模板的模板参数推断 327
10.2.5 类模板的专门化 328
10.2.6 类模板的友元 329
10.2.7 类模板std::initializer_list<> 330
10.3 实战:强化学习Q-Learning求解最佳路径 332
10.3.1 强化学习 332
10.3.2 Q-Learning 334
10.3.3 Q-Learning的C++实现 336
10.4 习题 343
第11章 移动语义 347
11.1 左值和右值 347
11.1.1 左值和右值概述 347
11.1.2 左值和右值的转换 349
11.1.3 左值引用和右值引用 349
11.2 移动 350
11.2.1 复制和移动 350
11.2.2 移动构造函数 353
11.2.3 移动赋值运算符函数 353
11.2.4 std::move 354
11.2.5 右值引用 355
11.2.6 push_back() 355
11.3 习题 357
第12章 函数指针、函数对象、Lambda表达式 359
12.1 函数指针 359
12.1.1 函数类型和函数指针类型 359
12.1.2 给函数指针类型起别名 361
12.1.3 函数指针作为其他函数的参数 361
12.2 函数对象 363
12.3 Lambda表达式 366
12.3.1 定义和使用Lambda表达式 366
12.3.2 捕获子句 368
12.3.3 返回类型 370
12.3.4 Lambda表达式的实质 371
12.4 std::function 371
12.5 std::bind 374
12.6 习题 376
第13章 C++标准库介绍 378
13.1 输入输出流库 379
13.1.1 C++的I/O流库 379
13.1.2 格式化输入输出 382
13.1.3 非格式化输入输出 386
13.1.4 文件位置 392
13.1.5 流状态 393
13.1.6 管理输出缓冲区 395
13.1.7 文件输入输出 395
13.1.8 字符串流 397
13.2 容器 399
13.2.1 标准容器 399
13.2.2 序列容器 401
13.2.3 容器适配器 406
13.2.4 关联容器 408
13.3 迭代器 411
13.3.1 迭代器及其分类 411
13.3.2 迭代器适配器 416
13.3.3 数组、字符串和迭代器 423
13.4 算法 423
13.4.1 自定义通用算法 424
13.4.2 策略参数 425
13.4.3 标准库的常用算法 426
13.5 智能指针 442
13.5.1 raw指针和智能指针 442
13.5.2 unique_ptr 443
13.5.3 shared_ptr 447
13.5.4 weak_ptr 448
13.6 字符串 449
13.6.1 字符:<cctype>、<cwctype> 449
13.6.2 C风格字符串 449
13.6.3 C++的字符串 450
13.7 习题 455
第14章 异常处理 459
14.1 错误和异常处理 459
14.1.1 错误的分类 459
14.1.2 传统的错误处理方法 459
14.1.3 C++的异常处理 460
14.2 throw、try、catch 461
14.2.1 throw 461
14.2.2 try、catch 461
14.2.3 异常类型的匹配 463
14.3 堆栈展开和RAII 464
14.3.1 堆栈展开 464
14.3.2 资源获取即初始化 466
14.4 习题 470
参考文献 473