编辑推荐
通过阅读本书,读者可快速掌握C 的基本知识并学习其中更高级的功能和概念。本书根据C 14标准进行了全面修订,展望了C 17,并从实用的角度诠释C 语言,帮助读者学习如何使用它创建速度更快、更简洁、更高效的C 应用程序。掌握C 和面向对象编程的基本知识。理解如何使用lambda表达式、移动构造函数和赋值运算符等C 功能编写简洁、高效的代码。学习C 编程的实践并避开常见的陷阱。学习标准模板库,包括大多数真实C 应用程序都要用到的容器和算法。使用每章末尾的练习来检验对知识的掌握程度。本书特色:无需任何编程经验;编写速度更快、功能更强大的C 程序,编译源代码并创建可执行文件;学习封装、抽象、继承和多态等面向对象编程概念;使用标准模板库中的算法和容器编写功能丰富而稳定的C 应用程序;学习自动类型推断是如何帮助简化C 代码的;使用lambda表达式、智能指针和移动构造函数完成复杂的编程工作;通过向编程专家学习,掌握C 功能;学习能够用来编写出简洁且高性能应用程序的C 功能;展望C 17有望引入的新功能。读者可通过www.epubit.com.cn book details 4780下载本书源代码。
内容简介
《21天学通C (第8版)》通过大量短小精悍的程序详细而全面地阐述了C 基本概念和技术,以及C 11、C 14和C 17新增的功能,包括管理输入 输出、循环和数组、面向对象编程、模板、使用标准模板库、列表初始化、lambda表达式、自动类型推断等。这些内容被组织成结构合理、联系紧密的章节,每章都可在1小时内阅读完毕;每章都提供了示例程序清单,并辅以示例输出和代码分析,以阐述该章介绍的主题。为加深读者对所学内容的理解,每章末尾都提供了常见问题及其答案以及练习和测验。读者可对照附录E提供的测验和练习答案,了解自己对所学内容的掌握程度。《21天学通C (第8版)》是针对C 初学者编写的,不要求读者有C语言方面的背景知识,可作为高等院校教授C 课程的教材,也可供初学者自学C 时使用。
作者简介
Siddhartha Rao是全球领先的企业软件提供商SAP SE负责安全响应的副总裁。C 的发展让他深信,您能编写速度更快、更简洁、更强大的C 应用程序。Siddhartha酷爱旅游,还是山地自行车运动的狂热爱好者;他期待着您对本书的反馈。
目录
- 第1章 绪论1
- 1.1 C 简史1
- 1.1.1 与C语言的关系1
- 1.1.2 C 的优点1
- 1.1.3 C 标准的发展历程2
- 1.1.4 哪些人使用C 程序2
- 1.2 编写C 应用程序2
- 1.2.1 生成可执行文件的步骤2
- 1.2.2 分析并修复错误2
- 1.2.3 集成开发环境3
- 1.2.4 编写第一个C 应用程序3
- 1.2.5 生成并执行第一个C 应用程序4
- 1.2.6 理解编译错误5
- 1.3 C 新增的功能5
- 1.4 总结5
- 1.5 问与答6
- 1.6 作业6
- 1.6.1 测验6
- 1.6.2 练习6
- 第2章 C 程序的组成部分8
- 2.1 Hello World程序的组成部分8
- 2.1.1 预处理器编译指令#include9
- 2.1.2 程序的主体—main( )9
- 2.1.3 返回值10
- 2.2 名称空间的概念10
- 2.3 C 代码中的注释11
- 2.4 C 函数12
- 2.5 使用std::cin和std::cout执行基本输入输出操作14
- 2.6 总结15
- 2.7 问与答15
- 2.8 作业15
- 2.8.1 测验16
- 2.8.2 练习16
- 第3章 使用变量和常量17
- 3.1 什么是变量17
- 3.1.1 内存和寻址概述17
- 3.1.2 声明变量以访问和使用内存17
- 3.1.3 声明并初始化多个类型相同的变量19
- 3.1.4 理解变量的作用域19
- 3.1.5 全局变量20
- 3.1.6 命名约定22
- 3.2 编译器支持的常见C 变量类型22
- 3.2.1 使用bool变量存储布尔值23
- 3.2.2 使用char变量存储字符23
- 3.2.3 有符号整数和无符号整数的概念24
- 3.2.4 有符号整型short、int、long和long long24
- 3.2.5 无符号整型unsigned short、unsigned int、unsigned long和unsigned long long25
- 3.2.6 选择正确的数据类型以免发生溢出错误25
- 3.2.7 浮点类型float和double26
- 3.3 使用sizeof确定变量的长度26
- 3.4 使用auto自动推断类型28
- 3.5 使用typedef替换变量类型29
- 3.6 什么是常量30
- 3.6.1 字面常量30
- 3.6.2 使用const将变量声明为常量30
- 3.6.3 使用constexpr定义常量表达式31
- 3.6.4 枚举32
- 3.6.5 使用#define定义常量34
- 3.7 不能用作常量或变量名的关键字34
- 3.8 总结35
- 3.9 问与答36
- 3.10 作业37
- 3.10.1 测验37
- 3.10.2 练习37
- 第4章 管理数组和字符串38
- 4.1 什么是数组38
- 4.1.1 为何需要数组38
- 4.1.2 声明和初始化静态数组39
- 4.1.3 数组中的数据是如何存储的39
- 4.1.4 访问存储在数组中的数据40
- 4.1.5 修改存储在数组中的数据41
- 4.2 多维数组43
- 4.2.1 声明和初始化多维数组44
- 4.2.2 访问多维数组中的元素44
- 4.3 动态数组45
- 4.4 C风格字符串46
- 4.5 C 字符串:使用std::string48
- 4.6 总结50
- 4.7 问与答50
- 4.8 作业50
- 4.8.1 测验51
- 4.8.2 练习51
- 第5章 使用表达式、语句和运算符52
- 5.1 语句52
- 5.2 复合语句(语句块)53
- 5.3 使用运算符53
- 5.3.1 赋值运算符(=)53
- 5.3.2 理解左值和右值53
- 5.3.3 加法运算符( )、减法运算符( )、乘法运算符(*)、除法运算符( )和求模运算符(%)53
- 5.3.4 递增运算符( )和递减运算符( )54
- 5.3.5 前缀还是后缀55
- 5.3.6 相等运算符(==)和不等运算符(!=)56
- 5.3.7 关系运算符56
- 5.3.8 逻辑运算NOT、AND、OR和XOR58
- 5.3.9 使用C 逻辑运算NOT(!)、AND(&&)和OR(||)59
- 5.3.10 按位运算符NOT(~)、AND(&)、OR(|)和XOR(^)63
- 5.3.11 按位右移运算符(>>)和左移运算符(<<)64
- 5.3.12 复合赋值运算符65
- 5.3.13 使用运算符sizeof确定变量占用的内存量67
- 5.3.14 运算符优先级68
- 5.4 总结69
- 5.5 问与答69
- 5.6 作业70
- 5.6.1 测验70
- 5.6.2 练习70
- 第6章 控制程序流程71
- 6.1 使用if…else有条件地执行71
- 6.1.1 使用if…else进行条件编程72
- 6.1.2 有条件地执行多条语句73
- 6.1.3 嵌套if语句74
- 6.1.4 使用switch-case进行条件处理77
- 6.1.5 使用运算符 :进行条件处理80
- 6.2 在循环中执行代码81
- 6.2.1 不成熟的goto循环81
- 6.2.2 while循环83
- 6.2.3 do…while循环84
- 6.2.4 for循环86
- 6.2.5 基于范围的for循环88
- 6.3 使用continue和break修改循环的行为90
- 6.3.1 不结束的循环—无限循环90
- 6.3.2 控制无限循环91
- 6.4 编写嵌套循环93
- 6.4.1 使用嵌套循环遍历多维数组94
- 6.4.2 使用嵌套循环计算斐波纳契数列95
- 6.5 总结96
- 6.6 问与答96
- 6.7 作业97
- 6.7.1 测验97
- 6.7.2 练习97
- 第7章 使用函数组织代码99
- 7.1 为何需要函数99
- 7.1.1 函数原型是什么100
- 7.1.2 函数定义是什么101
- 7.1.3 函数调用和实参是什么101
- 7.1.4 编写接受多个参数的函数101
- 7.1.5 编写没有参数和返回值的函数103
- 7.1.6 带默认值的函数参数103
- 7.1.7 递归函数—调用自己的函数105
- 7.1.8 包含多条return语句的函数106
- 7.2 使用函数处理不同类型的数据107
- 7.2.1 函数重载107
- 7.2.2 将数组传递给函数109
- 7.2.3 按引用传递参数110
- 7.3 微处理器如何处理函数调用111
- 7.3.1 内联函数112
- 7.3.2 自动推断返回类型113
- 7.3.3 lambda函数114
- 7.4 总结115
- 7.5 问与答116
- 7.6 作业116
- 7.6.1 测验116
- 7.6.2 练习116
- 第8章 阐述指针和引用118
- 8.1 什么是指针118
- 8.1.1 声明指针119
- 8.1.2 使用引用运算符(&)获取变量的地址119
- 8.1.3 使用指针存储地址120
- 8.1.4 使用解除引用运算符(*)访问指向的数据122
- 8.1.5 将sizeof( )用于指针的结果124
- 8.2 动态内存分配125
- 8.2.1 使用new和delete动态地分配和释放内存125
- 8.2.2 将递增和递减运算符( 和 )用于指针的结果127
- 8.2.3 将关键字const用于指针129
- 8.2.4 将指针传递给函数130
- 8.2.5 数组和指针的类似之处131
- 8.3 使用指针时常犯的编程错误133
- 8.3.1 内存泄露133
- 8.3.2 指针指向无效的内存单元133
- 8.3.3 悬浮指针(也叫迷途或失控指针)134
- 8.3.4 检查使用new发出的分配请求是否得到满足135
- 8.4 指针编程最佳实践137
- 8.5 引用是什么137
- 8.5.1 是什么让引用很有用138
- 8.5.2 将关键字const用于引用139
- 8.5.3 按引用向函数传递参数140
- 8.6 总结140
- 8.7 问与答141
- 8.8 作业142
- 8.8.1 测验142
- 8.8.2 练习142
- 第9章 类和对象144
- 9.1 类和对象144
- 9.1.1 声明类145
- 9.1.2 作为类实例的对象145
- 9.1.3 使用句点运算符访问成员146
- 9.1.4 使用指针运算符(->)访问成员146
- 9.2 关键字public和private147
- 9.3 构造函数150
- 9.3.1 声明和实现构造函数150
- 9.3.2 何时及如何使用构造函数151
- 9.3.3 重载构造函数152
- 9.3.4 没有默认构造函数的类154
- 9.3.5 带默认值的构造函数参数155
- 9.3.6 包含初始化列表的构造函数156
- 9.4 析构函数157
- 9.4.1 声明和实现析构函数157
- 9.4.2 何时及如何使用析构函数158
- 9.5 复制构造函数160
- 9.5.1 浅复制及其存在的问题160
- 9.5.2 使用复制构造函数确保深复制162
- 9.5.3 有助于改善性能的移动构造函数166
- 9.6 构造函数和析构函数的其他用途166
- 9.6.1 不允许复制的类167
- 9.6.2 只能有一个实例的单例类167
- 9.6.3 禁止在栈中实例化的类169
- 9.6.4 使用构造函数进行类型转换171
- 9.7 this指针172
- 9.8 将sizeof( )用于类173
- 9.9 结构不同于类的地方175
- 9.10 声明友元176
- 9.11 共用体:一种特殊的数据存储机制178
- 9.11.1 声明共用体178
- 9.11.2 在什么情况下使用共用体178
- 9.12 对类和结构使用聚合初始化180
- 9.13 总结183
- 9.14 问与答183
- 9.15 作业184
- 9.15.1 测验184
- 9.15.2 练习184
- 第10章 实现继承185
- 10.1 继承基础185
- 10.1.1 继承和派生186
- 10.1.2 C 派生语法186
- 10.1.3 访问限定符protected188
- 10.1.4 基类初始化—向基类传递参数190
- 10.1.5 在派生类中覆盖基类的方法192
- 10.1.6 调用基类中被覆盖的方法194
- 10.1.7 在派生类中调用基类的方法194
- 10.1.8 在派生类中隐藏基类的方法196
- 10.1.9 构造顺序198
- 10.1.10 析构顺序198
- 10.2 私有继承200
- 10.3 保护继承202
- 10.4 切除问题205
- 10.5 多继承205
- 10.6 使用final禁止继承207
- 10.7 总结208
- 10.8 问与答208
- 10.9 作业208
- 10.9.1 测验208
- 10.9.2 练习209
- 第11章 多态210
- 11.1 多态基础210
- 11.1.1 为何需要多态行为210
- 11.1.2 使用虚函数实现多态行为212
- 11.1.3 为何需要虚构造函数213
- 11.1.4 虚函数的工作原理—理解虚函数表217
- 11.1.5 抽象基类和纯虚函数220
- 11.2 使用虚继承解决菱形问题222
- 11.3 表明覆盖意图的限定符override225
- 11.4 使用final来禁止覆盖函数226
- 11.5 可将复制构造函数声明为虚函数吗227
- 11.6 总结230
- 11.7 问与答230
- 11.8 作业231
- 11.8.1 测验231
- 11.8.2 练习231
- 第12章 运算符类型与运算符重载232
- 12.1 C 运算符232
- 12.2 单目运算符233
- 12.2.1 单目运算符的类型233
- 12.2.2 单目递增与单目递减运算符234
- 12.2.3 转换运算符236
- 12.2.4 解除引用运算符(*)和成员选择运算符(->)238
- 12.3 双目运算符239
- 12.3.1 双目运算符的类型240
- 12.3.2 双目加法与双目减法运算符240
- 12.3.3 实现运算符 =与 =t242
- 12.3.4 重载等于运算符(==)和不等运算符(!=)243
- 12.3.5 重载运算符<、>、<=和>=t245
- 12.3.6 重载复制赋值运算符(=)248
- 12.3.7 下标运算符250
- 12.4 函数运算符operator()253
- 12.5 用于高性能编程的移动构造函数和移动赋值运算符254
- 12.5.1 不必要的复制带来的问题254
- 12.5.2 声明移动构造函数和移动赋值运算符254
- 12.6 用户定义的字面量258
- 12.7 不能重载的运算符260
- 12.8 总结261
- 12.9 问与答261
- 12.10 作业261
- 12.10.1 测验261
- 12.10.2 练习261
- 第13章 类型转换运算符262
- 13.1 为何需要类型转换262
- 13.2 为何有些C 程序员不喜欢C风格类型转换263
- 13.3 C 类型转换运算符263
- 13.3.1 使用static_cast263
- 13.3.2 使用dynamic_cast和运行阶段类型识别264
- 13.3.3 使用reinterpret_cast267
- 13.3.4 使用const_cast267
- 13.4 C 类型转换运算符存在的问题268
- 13.5 总结269
- 13.6 问与答269
- 13.7 作业270
- 13.7.1 测验270
- 13.7.2 练习270
- 第14章 宏和模板简介271
- 14.1 预处理器与编译器271
- 14.2 使用#define定义常量271
- 14.3 使用#define编写宏函数274
- 14.3.1 为什么要使用括号276
- 14.3.2 使用assert宏验证表达式276
- 14.3.3 使用宏函数的优点和缺点277
- 14.4 模板简介278
- 14.4.1 模板声明语法278
- 14.4.2 各种类型的模板声明279
- 14.4.3 模板函数279
- 14.4.4 模板与类型安全281
- 14.4.5 模板类281
- 14.4.6 声明包含多个参数的模板282
- 14.4.7 声明包含默认参数的模板283
- 14.4.8 一个模板示例283
- 14.4.9 模板的实例化和具体化284
- 14.4.10 模板类和静态成员286
- 14.4.11 参数数量可变的模板287
- 14.4.12 使用static_assert执行编译阶段检查290
- 14.4.13 在实际C 编程中使用模板290
- 14.5 总结291
- 14.6 问与答291
- 14.7 作业291
- 14.7.1 测验291
- 14.7.2 练习292
- 第15章 标准模板库简介293
- 15.1 STL容器293
- 15.1.1 顺序容器293
- 15.1.2 关联容器294
- 15.1.3 容器适配器294
- 15.2 STL迭代器295
- 15.3 STL算法295
- 15.4 使用迭代器在容器和算法之间交互295
- 15.5 选择正确的容器297
- 15.6 STL字符串类298
- 15.7 总结298
- 15.8 问与答299
- 15.9 作业299
- 第16章 STL string类300
- 16.1 为何需要字符串操作类300
- 16.2 使用STL string类301
- 16.2.1 实例化和复制STL string301
- 16.2.2 访问std::string的字符内容303
- 16.2.3 拼接字符串305
- 16.2.4 在string中查找字符或子字符串306
- 16.2.5 截短STL string307
- 16.2.6 字符串反转309
- 16.2.7 字符串的大小写转换310
- 16.3 基于模板的STL string实现311
- 16.4 总结312
- 16.5 问与答312
- 16.6 作业313
- 16.6.1 测验313
- 16.6.2 练习313
- 第17章 STL动态数组类314
- 17.1 std::vector的特点314
- 17.2 典型的vector操作314
- 17.2.1 实例化vector314
- 17.2.2 使用push_back( )在末尾插入元素316
- 17.2.3 列表初始化317
- 17.2.4 使用insert( )在指定位置插入元素317
- 17.2.5 使用数组语法访问vector中的元素319
- 17.2.6 使用指针语法访问vector中的元素320
- 17.2.7 删除vector中的元素321
- 17.3 理解大小和容量322
- 17.4 STL deque 类324
- 17.5 总结326
- 17.6 问与答326
- 17.7 作业327
- 17.7.1 测验327
- 17.7.2 练习327
- 第18章 STL list和forward_list328
- 18.1 std::list的特点328
- 18.2 基本的list操作328
- 18.2.1 实例化std::list对象328
- 18.2.2 在list开头或末尾插入元素330
- 18.2.3 在list中间插入元素331
- 18.2.4 删除list中的元素333
- 18.3 对list中的元素进行反转和排序334
- 18.3.1 使用list::reverse( )反转元素的排列顺序334
- 18.3.2 对元素进行排序335
- 18.3.3 对包含对象的list进行排序以及删除其中的元素337
- 18.3.4 C 11引入的std::forward_list340
- 18.4 总结341
- 18.5 问与答342
- 18.6 作业342
- 18.6.1 测验342
- 18.6.2 练习342
- 第19章 STL集合类343
- 19.1 简介343
- 19.2 STL set和multiset的基本操作344
- 19.2.1 实例化std::set对象344
- 19.2.2 在set或multiset中插入元素345
- 19.2.3 在STL set或multiset中查找元素347
- 19.2.4 删除STL set或multiset中的元素348
- 19.3 使用STL set和multiset的优缺点352
- 19.4 总结354
- 19.5 问与答355
- 19.6 作业355
- 19.6.1 测验355
- 19.6.2 练习355
- 第20章 STL映射类356
- 20.1 STL映射类简介356
- 20.2 STL map和multimap的基本操作357
- 20.2.1 实例化std::map和
- std::multimap357
- 20.2.2 在STL map或multimap中插入元素358
- 20.2.3 在STL map或multimap中查找元素361
- 20.2.4 在STL multimap中查找元素363
- 20.2.5 删除STL map或multimap中的元素363
- 20.3 提供自定义的排序谓词365
- 20.4 基于散列表的STL键-值对容器368
- 20.4.1 散列表的工作原理368
- 20.4.2 使用unordered_map和unordered_multimap368
- 20.5 总结372
- 20.6 问与答372
- 20.7 作业372
- 20.7.1 测验373
- 20.7.2 练习373
- 第21章 理解函数对象374
- 21.1 函数对象与谓词的概念374
- 21.2 函数对象的典型用途374
- 21.2.1 一元函数374
- 21.2.2 一元谓词378
- 21.2.3 二元函数380
- 21.2.4 二元谓词381
- 21.3 总结383
- 21.4 问与答384
- 21.5 作业384
- 21.5.1 测验384
- 21.5.2 练习384
- 第22章 lambda表达式385
- 22.1 lambda表达式是什么385
- 22.2 如何定义lambda表达式386
- 22.3 一元函数对应的lambda表达式386
- 22.4 一元谓词对应的lambda表达式387
- 22.5 通过捕获列表接受状态变量的lambda表达式388
- 22.6 lambda表达式的通用语法390
- 22.7 二元函数对应的lambda表达式391
- 22.8 二元谓词对应的lambda表达式392
- 22.9 总结394
- 22.10 问与答394
- 22.11 作业395
- 22.11.1 测验395
- 22.11.2 练习395
- 第23章 STL算法396
- 23.1 什么是STL算法396
- 23.2 STL算法的分类396
- 23.2.1 非变序算法396
- 23.2.2 变序算法397
- 23.3 使用STL算法398
- 23.3.1 根据值或条件查找元素398
- 23.3.2 计算包含给定值或满足给定条件的元素数400
- 23.3.3 在集合中搜索元素或序列401
- 23.3.4 将容器中的元素初始化为指定值403
- 23.3.5 使用std::generate( )将元素设置为运行阶段生成的值405
- 23.3.6 使用for_each( )处理指定范围内的元素406
- 23.3.7 使用std::transform( )对范围进行变换407
- 23.3.8 复制和删除操作409
- 23.3.9 替换值以及替换满足给定条件的元素412
- 23.3.10 排序、在有序集合中搜索以及删除重复元素413
- 23.3.11 将范围分区415
- 23.3.12 在有序集合中插入元素417
- 23.4 总结419
- 23.5 问与答419
- 23.6 作业419
- 23.6.1 测验420
- 23.6.2 练习420
- 第24章 自适应容器:栈和队列421
- 24.1 栈和队列的行为特征421
- 24.1.1 栈421
- 24.1.2 队列422
- 24.2 使用STL stack类422
- 24.2.1 实例化stack422
- 24.2.2 stack的成员函数423
- 24.2.3 使用push( )和pop( )在栈顶插入和删除元素424
- 24.3 使用STL queue类425
- 24.3.1 实例化queue425
- 24.3.2 queue的成员函数426
- 24.3.3 使用push( )在队尾插入以及使用pop( )从队首删除427
- 24.4 使用STL优先级队列428
- 24.4.1 实例化priority_queue类428
- 24.4.2 priority_queue的成员函数429
- 24.4.3 使用push( )在priority_queue末尾插入以及使用pop( )在priority_queue开头删除430
- 24.5 总结432
- 24.6 问与答432
- 24.7 作业432
- 24.7.1 测验432
- 24.7.2 练习432
- 第25章 使用STL位标志433
- 25.1 bitset类433
- 25.2 使用std::bitset及其成员434
- 25.2.1 std:bitset的运算符434
- 25.2.2 std::bitset的成员方法435
- 25.3 vector437
- 25.3.1 实例化vector437
- 25.3.2 vector的成员函数和运算符438
- 25.4 总结439
- 25.5 问与答439
- 25.6 作业439
- 25.6.1 测验439
- 25.6.2 练习440
- 第26章 理解智能指针441
- 26.1 什么是智能指针441
- 26.1.1 常规(原始)指针存在的问题441
- 26.1.2 智能指针有何帮助442
- 26.2 智能指针是如何实现的442
- 26.3 智能指针类型443
- 26.3.1 深复制443
- 26.3.2 写时复制机制445
- 26.3.3 引用计数智能指针445
- 26.3.4 引用链接智能指针445
- 26.3.5 破坏性复制445
- 26.3.6 使用std::unique_ptr447
- 26.4 深受欢迎的智能指针库449
- 26.5 总结449
- 26.6 问与答449
- 26.7 作业450
- 26.7.1 测试450
- 26.7.2 练习450
- 第27章 使用流进行输入和输出451
- 27.1 流的概述451
- 27.2 重要的C 流类和流对象452
- 27.3 使用std::cout将指定格式的数据写入控制台453
- 27.3.1 使用std::cout修改数字的显示格式453
- 27.3.2 使用std::cout对齐文本和设置字段宽度455
- 27.4 使用std::cin进行输入455
- 27.4.1 使用std::cin将输入读取到基本类型变量中455
- 27.4.2 使用std::cin:get将输入读取到char*缓冲区中456
- 27.4.3 使用std::cin将输入读取到std::string中457
- 27.5 使用std::fstream处理文件458
- 27.5.1 使用open( )和close( )打开和关闭文件459
- 27.5.2 使用open( )创建文本文件并使用运算符<<写入文本460>
- 27.5.3 使用open( )和运算符>>读取文本文件460
- 27.5.4 读写二进制文件461
- 27.6 使用std::stringstream对字符串进行转换463
- 27.7 总结464
- 27.8 问与答464
- 27.9 作业465
- 27.9.1 测验465
- 27.9.2 练习465
- 第28章 异常处理466
- 28.1 什么是异常466
- 28.2 导致异常的原因466
- 28.3 使用try和catch捕获异常467
- 28.3.1 使用catch(…)处理所有异常467
- 28.3.2 捕获特定类型的异常468
- 28.3.3 使用throw引发特定类型的异常469
- 28.4 异常处理的工作原理470
- 28.4.1 std::exception类472
- 28.4.2 从std::exception派生出自定义异常类473
- 28.5 总结474
- 28.6 问与答474
- 28.7 作业475
- 28.7.1 测验475
- 28.7.2 练习475
- 第29章 继续前行477
- 29.1 当今的处理器有何不同477
- 29.2 如何更好地利用多个内核478
- 29.2.1 线程是什么478
- 29.2.2 为何要编写多线程应用程序479
- 29.2.3 线程如何交换数据479
- 29.2.4 使用互斥量和信号量同步线程480
- 29.2.5 多线程技术带来的问题480
- 29.3 编写杰出的C 代码480
- 29.4 C 17有望引入的新特性481
- 29.4.1 支持在if和switch中进行初始化481
- 29.4.2 保证复制得以避免482
- 29.4.3 避免内存分配开销的std::string_view482
- 29.4.4 类型安全的共用体替代品std::variant483
- 29.4.5 使用if constexpr有条件地编译代码483
- 29.4.6 改进的lambda表达式484
- 29.4.7 在构造函数中使用类型自动推断功能484
- 29.5 更深入地学习C 484
- 29.5.1 在线文档485
- 29.5.2 提供指南和帮助的社区485
- 29.6 总结485
- 29.7 问与答485
- 29.8 作业485
- 附录A 二进制和十六进制486
- A.1 十进制486
- A.2 二进制486
- A.2.1 计算机为何使用二进制487
- A.2.2 位和字节487
- A.2.3 1KB相当于多少字节487
- A.3 十六进制487
- A.4 不同进制之间的转换488
- A.4.1 通用转换步骤488
- A.4.2 从十进制转换为二进制488
- A.4.3 从十进制转换为十六进制489
- 附录B C 关键字490
- 附录C 运算符优先级491
- 附录D ASCII码492
- 附录E 答案495