新書推薦:
《
城邦政治与灵魂政治——柏拉图《理想国》中的政治哲学研究
》
售價:HK$
129.8
《
3分钟漫画墨菲定律:十万个为什么科普百科思维方式心理学 胜天半子人定胜天做事与成事的权衡博弈之道
》
售價:HK$
54.8
《
1911:危亡警告与救亡呼吁
》
售價:HK$
76.8
《
旷野人生:吉姆·罗杰斯的全球投资探险
》
售價:HK$
75.9
《
笼中王国 : 18世纪法国的珍禽异兽与社会文化
》
售價:HK$
74.8
《
思考的框架3:风靡华尔街的思维训练法
》
售價:HK$
64.9
《
被记忆的西周史(中山大学中珠学术译丛)
》
售價:HK$
151.8
《
森林疗法:拥抱大自然、获得幸福的季节性方法
》
售價:HK$
74.8
|
編輯推薦: |
C 是软件开发中使用非常广泛的语言之一。在经验丰富的程序员眼中,C 可以写出任何程序员都会引以为傲的可读性较高、短小精悍且高效的代码。你将通过本书学习现代C 的所有主要特性,包括: ?基本类型、引用类型和用户自定义类型; ?使用模板的编译时多态和使用虚拟类的运行时多态; ?对象生命周期,包括存储期、调用栈、内存管理、异常和RAII范式; ?高级表达式、语句和函数; ?智能指针、数据结构、日期和时间、数值工具和概率/统计工具; ?容器、迭代器、字符串和算法; ?流、文件、并发性、网络和应用程序开发。本书包含500多个代码样本和近100个练习,可以让你打下坚实的C 基础。
|
內容簡介: |
本书是为中高级程序员设计的,它深入介绍了现代C 的核心。本书分为两大部分:部分介绍C 语言的核心,深入讲解从类型和函数到对象生命周期和表达式的所有内容;第二部分介绍C 标准库和Boost库,深入讲解所有可用的高质量、全功能的工具,涵盖了特殊的工具类、数据结构和算法,并介绍了如何操作文件系统和构建通过网络进行通信的高性能程序。本书包含500多个代码样本和近100个练习,可以让你打下坚实的C 基础,助你写出让自己引以为傲的可读性较高、短小精悍且高效的代码。
|
目錄:
|
目 录 Contents
序
前言
致C语言程序员
第一部分 C 语言核心
第1章 启动和运行2
1.1 C 程序的基本结构2
1.1.1 创建第一个C 源文件3
1.1.2 main函数:C 程序的入口点3
1.1.3 程序库:引入外部代码3
1.2 编译器工具链4
1.2.1 设置开发环境4
1.2.2 Windows 10以及后续版本:
Visual Studio5
1.2.3 macOS: Xcode6
1.2.4 Linux和GCC7
1.2.5 文本编辑器10
1.3 开始认识C 11
1.3.1 C 类型系统11
1.3.2 声明变量11
1.3.3 初始化变量的状态11
1.3.4 条件语句12
1.3.5 函数14
1.3.6 printf格式指定符15
1.3.7 重新审视step_function16
1.3.8 注释 17
1.4 调试18
1.4.1 Visual Studio18
1.4.2 Xcode19
1.4.3 用GDB和LLDB对GCC和
Clang进行调试20
1.5 总结23
练习23
拓展阅读24
第2章 类型25
2.1 基本类型25
2.1.1 整数类型25
2.1.2 浮点类型28
2.1.3 字符类型30
2.1.4 布尔类型31
2.1.5 std::byte类型33
2.1.6 size_t类型34
2.1.7 void35
2.2 数组35
2.2.1 数组初始化35
2.2.2 访问数组元素35
2.2.3 for循环简介36
2.2.4 C风格字符串38
2.3 用户自定义类型41
2.3.1 枚举类型41
2.3.2 普通数据类44
2.3.3 联合体45
2.4 全功能的C 类46
2.4.1 方法47
2.4.2 访问控制47
2.4.3 构造函数49
2.4.4 初始化51
2.4.5 析构函数55
2.5 总结56
练习56
拓展阅读56
第3章 引用类型57
3.1 指针57
3.1.1 寻址变量58
3.1.2 指针解引用59
3.1.3 成员指针运算符60
3.1.4 指针和数组61
3.1.5 指针很危险63
3.1.6 void指针和std::byte指针65
3.1.7 nullptr和布尔表达式65
3.2 引用65
3.3 指针和引用的使用66
3.3.1 前向链表:经典的基于指针的
数据结构66
3.3.2 使用引用68
3.3.3 this指针69
3.3.4 const正确性69
3.3.5 const成员变量71
3.3.6 成员初始化列表71
3.4 auto类型推断72
3.4.1 用auto进行初始化73
3.4.2 auto和引用类型73
3.4.3 auto和代码重构73
3.5 总结74
练习74
拓展阅读75
第4章 对象生命周期76
4.1 对象的存储期76
4.1.1 分配、释放和生命周期76
4.1.2 内存管理77
4.1.3 自动存储期77
4.1.4 静态存储期77
4.1.5 线程局部存储期80
4.1.6 动态存储期81
4.2 追踪对象的生命周期83
4.3 异常84
4.3.1 throw关键字84
4.3.2 使用try-catch代码块85
4.3.3 stdlib异常类86
4.3.4 异常处理88
4.3.5 用户定义的异常89
4.3.6 noexcept关键字90
4.3.7 调用栈和异常90
4.4 SimpleString类92
4.4.1 追加和打印93
4.4.2 使用SimpleString94
4.4.3 组合SimpleString95
4.4.4 调用栈展开96
4.4.5 异常和性能98
4.4.6 异常的替代方法98
4.5 复制语义99
4.5.1 复制构造函数101
4.5.2 复制赋值103
4.5.3 默认复制105
4.5.4 复制指南106
4.6 移动语义106
4.6.1 复制行为可能浪费资源106
4.6.2 值类别108
4.6.3 左值引用和右值引用108
4.6.4 std::move函数109
4.6.5 移动构造110
4.6.6 移动赋值110
4.6.7 终成果111
4.6.8 编译器生成的方法113
4.7 总结114
练习114
拓展阅读115
第5章 运行时多态116
5.1 多态116
5.2 一个有启发性的例子116
5.2.1 添加新的日志记录器119
5.2.2 接口119
5.2.3 对象组合和实现继承119
5.3 定义接口120
5.3.1 基类继承120
5.3.2 成员继承121
5.3.3 虚方法122
5.3.4 纯虚类和虚析构函数124
5.3.5 实现接口125
5.3.6 使用接口126
5.4 更新银行日志记录器126
5.4.1 构造函数注入127
5.4.2 属性注入127
5.4.3 构造函数注入和属性注入的
选择128
5.5 总结129
练习129
拓展阅读129
第6章 编译时多态130
6.1 模板130
6.2 声明模板130
6.2.1 模板类定义131
6.2.2 模板函数定义131
6.2.3 实例化模板131
6.3 类型转换函数132
6.3.1 const_cast132
6.3.2 static_cast133
6.3.3 reinterpret_cast134
6.3.4 narrow_cast134
6.4 mean:模板函数示例136
6.4.1 通用mean136
6.4.2 模板类型推断138
6.5 SimpleUniquePointer:模板类
示例139
6.6 模板中的类型检查142
6.7 concept143
6.7.1 定义concept143
6.7.2 类型特征144
6.7.3 约束要求146
6.7.4 从requires表达式构建
concept147
6.7.5 使用concept147
6.7.6 临时requires表达式151
6.8 static_assert:concept之前的权宜
之计153
6.9 非类型模板参数154
6.10 可变参数模板156
6.11 高级模板主题156
6.11.1 模板特化156
6.11.2 名字绑定157
6.11.3 类型函数157
6.11.4 模板元编程157
6.12 模板源代码组织157
6.13 运行时多态与编译时多态对比158
6.14 总结158
练习158
拓展阅读159
第7章 表达式160
7.1 运算符160
7.1.1 逻辑运算符160
7.1.2 算术运算符161
7.1.3 赋值运算符162
7.1.4 自增和自减运算符163
7.1.5 比较运算符163
7.1.6 成员访问运算符164
7.1.7 三元条件运算符164
7.1.8 逗号运算符165
7.1.9 重载运算符165
7.1.10 重载运算符new167
7.1.11 运算符优先级和结合性172
7.1.12 求值顺序174
7.2 自定义字面量175
7.3 类型转换175
7.3.1 隐式类型转换176
7.3.2 显式类型转换178
7.3.3 C风格的类型转换179
7.3.4 用户自定义类型的转换180
7.4 常量表达式181
7.4.1 有关色彩的示例182
7.4.2 关于constexpr的说明184
7.5 volatile表达式184
7.6 总结185
练习186
拓展阅读186
第8章 语句187
8.1 表达式语句187
8.2 复合语句188
8.3 声明语句189
8.3.1 函数189
8.3.2 命名空间192
8.3.3 类型别名195
8.3.4 结构化绑定197
8.3.5 属性198
8.4 选择语句199
8.4.1 if语句199
8.4.2 switch语句203
8.5 迭代语句204
8.5.1 while循环204
8.5.2 do-while循环205
8.5.3 for循环206
8.5.4 基于范围的for循环208
8.6 跳转语句211
8.6.1 break语句212
8.6.2 continue语句212
8.6.3 goto语句213
8.7 总结214
练习215
拓展阅读215
第9章 函数216
9.1 函数声明216
9.1.1 前缀修饰符216
9.1.2 后缀修饰符217
9.2 auto返回类型220
9.3 auto和函数模板220
9.4 重载解析221
9.5 可变参数函数222
9.6 可变参数模板223
9.6.1 用参数包编程223
9.6.2 再谈sum函数224
9.6.3 折叠表达式225
9.7 函数指针225
9.7.1 声明函数指针225
9.7.2 类型别名和函数指针226
9.8 函数调用运算符227
9.9 计数例子227
9.10 lambda表达式229
9.10.1 用法229
9.10.2 参数和表达式体230
9.10.3 默认参数231
9.10.4 泛型232
9.10.5 返回类型233
9.10.6 捕获列表233
9.10.7 constexpr lambda表达式239
9.11 std :: function 239
9.11.1 声明函数239
9.11.2 扩展示例240
9.12 main函数和命令行242
9.12.1 main的三个重载变体242
9.12.2 程序参数243
9.12.3 更深入的例子244
9.12.4 退出状态246
9.13 总结246
练习246
拓展阅读247
第二部分 C 库和框架
第10章 测试250
10.1 单元测试250
10.1.1 集成测试250
10.1.2 验收测试251
10.1.3 性能测试251
10.2 扩展示例:汽车制动服务251
10.2.1 实现AutoBrake253
10.2.2 测试驱动开发254
10.2.3 添加服务总线接口264
10.3 单元测试框架和模拟框架270
10.3.1 Catch单元测试框架270
10.3.2 Google Test276
10.3.3 Boost Test282
10.3.4 总结:测试框架287
10.4 模拟框架287
10.4.1 Google Mock289
10.4.2 HippoMocks296
10.4.3 其他模拟框架:FakeIt和
Trompeloeil300
10.5 总结300
练习301
拓展阅读302
第11章 智能指针303
11.1 智能指针概述303
11.2 智能指针所有权304
11.3 作用域指针304
11.3.1 构造304
11.3.2 引入Oath Breaker304
11.3.3 基于所有权的隐式布尔转换305
11.3.4 RAII包装器306
11.3.5 指针语义306
11.3.6 与nullptr比较307
11.3.7 交换307
11.3.8 重置和替换scoped_ptr308
11.3.9 不可转移性309
11.3.10 boost::scoped_array309
11.3.11 支持的部分操作310
11.4 独占指针310
11.4.1 构造311
11.4.2 支持的操作311
11.4.3 可转移的专属所有权311
11.4.4 独占数组312
11.4.5 删除器313
11.4.6 自定义删除器和系统编程313
11.4.7 支持的部分操作315
11.5 共享指针31
|
內容試閱:
|
前 言 Preface
拿起画笔,和我们一起画画吧!
—Bob Ross
系统编程的需求是巨大的。随着浏览器、移动设备和物联网应用于我们的生活,也许从来没有一个时刻像现在这样,这是人们成为一名系统程序员的佳时机。在任何情况下我们都需要高效、可维护和正确的代码,而我坚信C 是适合这项工作的语言。
在经验丰富的程序员手中,C 可以产生比地球上任何其他系统编程语言所能产生的更小、更高效、更可读的代码。它是一种致力于实现零开销抽象机制的语言—因此程序可以快速地被开发,同时也可以简单、直接地映射到硬件上。因此,当需要时,我们也可以进行底层控制。当用C 编程时,我们其实已经站在了巨人的肩膀上,他们花了几十年的时间精心设计了一门令人难以置信的强大而灵活的语言。
学习C 的一大好处是可以免费获得C 标准库,即stdlib。stdlib包含三个相互关联的部分:容器、迭代器和算法。如果你曾经手动编写过quicksort算法,或者曾经编写过系统代码并受到缓冲区溢出、悬空指针、使用已释放内存和重复释放内存等问题的困扰,那么你会喜欢stdlib的。它可以同时为你提供无与伦比的类型安全、正确性和效率。此外,你会为代码的紧凑和富有表现力而欣喜。
C 编程模型的核心是对象生命周期,它为正确释放程序所使用的资源(如文件、内存和网络套接字)提供了强有力的保证,即使在发生错误时。而异常,当正确使用时,可以从代码中去掉大量的错误检查。另外,移动/复制语义在管理资源所有权方面兼顾了安全性、效率和灵活性,而早期的系统编程语言(如C语言)根本没有提供这类功能。
C 是一门活跃的语言,30多年来,国际标准化组织(International Organization for Standardization,ISO)的C 委员会定期对该语言进行改进。在过去的十几年中,该标准已经发布了几个新版本,即C 11、C 14、C 17和C 20,它们分别于2011年、2014年、2017年和2020年发布。
当我使用“现代C ”(modern C )这个术语时,指的是包含新的功能和范式的新标准。这些更新对该语言进行了认真的改进,提高了它的表现力、效率、安全性和整体可用性。从某种程度上说,这门语言从未像现在这样流行,它也不会很快消失。如果你决定学习C ,那么你将在未来几年内得到回报。
写作目的
虽然现代C 程序员已经可以接触到一些质量非常高的书籍,如Scott Meyer的Effective Modern C 和Bjarne Stroustrup的The C Programming Language(第4版),
但它们通常是面向高级程序员的。也有一些介绍性的C 书籍,但因为它们是为初学编程的人准备的,所以往往会跳过一些关键的细节。而对于有经验的程序员来说,往往不知道去哪里学习C 。
我更喜欢有意识地学习复杂的命题,从其基本的元素开始建立概念。C 之所以获得“C 是一门复杂的语言”的评价,是因为它的基本元素紧密地嵌套在一起,使得我们很难对这门语言有一个完整的认识。当我自己学习C 的时候,我不得不辗转于书本、视频和疲惫的同事之间,费尽心思地去弄懂这门语言。基于此,我写了这本我认为很早之前就应该有的书。
读者对象
本书是为已经熟悉基本编程概念的中高级程序员编写的。如果你没有专门的系统编程经验,那没关系,本书也适合有经验的应用程序员。
如果你是一名经验丰富的C语言程序员或者有抱负的系统程序员,想知道是否应该学习C ,请务必阅读“致C语言程序员”,以了解详情。
本书内容
本书分为两部分。第一部分讨论C 语言核心。读者不需要按时间顺序学习C 语言(即从C 98开始一直学到现代的C 11/14/17),而是可以直接学习地道的现代C 。第二部分介绍C 标准库(stdlib),在这里读者将学到重要的基本概念。
第一部分 C 语言核心
第1章:启动和运行 本章将帮助你建立C 开发环境。你将编译和运行第一个程序,并学习如何调试它。
第2章:类型 本章将探索C 类型系统。你将了解基本类型,这是所有其他类型的基础。你也将了解普通数据类和全功能类。你还将深入了解构造函数、初始化和析构函数的作用。
第3章:引用类型 本章介绍存储其他对象的内存地址的对象。这种类型是许多重要的编程模式的基石,它能够产生灵活、高效的代码。
第4章:对象生命周期 本章在存储期的背景下继续讨论类的不变量和构造函数。同时,本章将探讨析构函数与资源获取即初始化(Resource Acquisition Is Initialization,RAII)范式。你将了解异常机制,以及它如何保证类的不变量、如何完善RAII。在了解了移动和复制语义后,你将探索如何用构造函数和赋值运算符来操作它们。
第5章:运行时多态 本章介绍接口,接口是一个允许你编写运行时的多态代码的编程概念。你将学习继承和对象组合的基础知识,这是在C 中使用接口的基础。
第6章:编译时多态 本章介绍模板,这也是一种允许你编写多态代码的语言特性。你还将探索将被添加到未来C 版本中的一个语言特性concept,以及允许你将对象从一种类型转换为另一种类型的类型转换函数。
第7章:表达式 你将深入研究操作数和运算符。在牢牢掌握类型、对象生命周期和模板之后,你将进入C 语言核心部分的学习,而表达式便是切入点。
第8章:语句 本章探讨组成函数的元素。你将学习表达式语句、复合语句、声明语句、迭代语句和跳转语句。
第9章:函数 本章讨论如何将语句变成工作单元。你将学习函数定义、返回类型、重载解析、可变参数函数、可变参数模板和函数指针等。你还将学习使用函数调用运算符和lambda表达式创建可调用的用户自定义类型的方法。你将探索std::function—一个存储可调用对象的容器类。
第二部分 C 库和框架
第10章:测试 本章介绍单元测试和模拟框架。你将练习测试驱动开发,为自动驾驶系统开发软件,同时学习一些框架,如Boost Test、Google Test、Google Mock等。
第11章:智能指针 本章介绍标准库为处理动态对象的所有权提供的特殊实用类。
第12章:工具库 本章介绍标准库和Boost库中用于处理常见编程问题的类型、类和函数。你将了解数据结构、数值函数和随机数生成器。
第13章:容器 本章介绍Boost库和标准库中的许多特殊数据结构,它们可以帮助你组织数据。你将了解顺序容器、关联容器和无序关联容器。
第14章:迭代器 迭代器是容器和字符串之间的接口。本章介绍不同类型的迭代器以及如何设计它们以便更灵活地编写程序。
第15章:字符串 本章介绍如何在单一容器中处理人类语言数据。你将了解内置于字符串中的特殊设施(facility),这些设施可以让你执行一些简单的任务。
第16章:流 本章介绍支撑输入和输出操作的主要概念。你将学习如何用格式化和非格式化的操作处理输入与输出流,以及如何使用操纵符。你还将学习如何从文件中读取数据以及如何向文件写入数据。
第17章:文件系统 本章介绍标准库中用于操作文件系统的工具。你将学习如何构建和操作路径,如何检查文件和目录,以及如何枚举目录结构。
第18章:算法 本章介绍标准库中可以轻松解决的几十个问题。你将了解这些高质量算法令人惊讶的适用范围。
第19章:并发和并行 本章介绍一些简单的多线程编程方法,这些方法是标准库的一部分。你将了解future、互斥量、条件变量和原子类型。
第20章:用Boost Asio进行网络编程 本章介绍如何构建通过网络进行通信的高性能程序。你将了解如何使用Boost Asio的阻塞式和非阻塞式输入与输出。
第21章:编写应用程序 这是本书的收尾部分,讨论了几个重要的主题。你将了解程序支持设施,这些设施可以帮助你构建更加完整的应用程序。你还将了解Boost ProgramOptions,这个库可以让你直接编写接受用户输入的控制台应用程序。
请访问配套网站https://ccc.codes/获得本书中的代码。
致谢
首先,感谢我的家人给我创作空间,我花了两倍的时间才写出我计划的一半内容,感谢他们的耐心陪伴,我欠他们的无法估量。
感谢Kyle Willmon和Aaron Bray,是他们教会了我C ;感谢Tyler Ortman,是他把这本书从提案中“孕育”了出来;感谢Bill Pollock,是他润色了本书;感谢Chris Cleveland、Patrick De Justo、Anne Marie Walker、Annie Choi、Meg Sneeringer和Riley Hoffman,是他们一流的编辑能力让本书变得更好;感谢早期的读者,是他们提供了不可估量的反馈。
后,感谢Jeff Lospinoso,他把那本翻过很多遍、沾满咖啡的“骆驼书”送给了他那年仅10岁的侄子,帮他点燃了编程的火花。
|
|