基本信息
- 原书名:Programming:Principles and Practice Using C++,Second Edition

内容简介
计算机书籍
C++之父Bjarne Stroustrup经典著作《C++程序设计:原理与实践(原书第2版)》基于最新的C++11和C++14,广泛地介绍了程序设计的基本概念和技术,包括类型系统、算术运算、控制结构、错误处理等;介绍了从键盘和文件获取数值和文本数据的方法以及以图形化方式表示数值数据、文本和几何图形;介绍了C++标准库中的容器(如向量、列表、映射)和算法(如排序、查找和内积)的设计和使用。同时还对C++思想和历史进行了详细的讨论,很好地拓宽了读者的视野。
为方便读者循序渐进地学习,加上篇幅所限,《C++程序设计:原理与实践(原书第2版)》分为基础篇和进阶篇两册出版,基础篇包括第1~11章、第17~19章和附录A、C,进阶篇包括第12~16章、第20~27章和附录B、D、E。本书是进阶篇。
本书通俗易懂、实例丰富,可作为大学计算机、电子工程、信息科学等相关专业的教材,也可供相关专业人员参考。
作译者
我是C++语言的设计者和最初的实现者。在过去大约40年间,我使用C++和许多其他程序设计语言进行过各种各样的编程工作。我喜欢那些用在富有挑战性的应用(如机器人控制、绘图、游戏、文本分析以及网络应用)中的优美而又高效的代码。我教过能力和兴趣各异的人设计、编程和C++语言。我是ISO标准组织C++委员会的创建者,现在是该委员会语言演化工作组的主席。
这是我第一本入门性的书。我编著的其他书籍如《The C++ Pro-gramming Language》和《The Design and Evolution of C++》都是面向有经验的程序员的。
我生于丹麦奥尔胡斯一个蓝领(工人阶级)家庭,在家乡的大学获得了数学与计算机科学硕士学位。我的计算机科学博士学位是在英国剑桥大学获得的。我为AT&T工作了大约25年,最初在著名的贝尔实验室的计算机科学研究中心——Unix、C、C++及其他很多东西的发明地,后来在AT&T实验室研究中心。
我现在是美国国家工程院的院士,ACM会士(Fellow)和IEEE会士。我获得了2005年度Sigma Xi(科学研究协会)的科学成就William Procter奖,我是首位获得此奖的计算机科学家。2010年,我获得了丹麦奥尔胡斯大学最古老也最富声望的奖项Rigmor og Carl Holst-Knudsens Videnskapspris,该奖项颁发给为科学做出贡献的与该校有关的人士。2013年,我被位于俄罗斯圣彼得堡的信息技术、力学和光学(ITMO)国立研究大学授予计算机科学荣誉博士学位。
至于工作之外的生活,我已婚,有两个孩子,一个是医学博士,另一个在进行博士后研究。我喜欢阅读(包括历史、科幻、犯罪及时事等各类书籍),还喜欢各种音乐(包括古典音乐、摇滚、蓝调和乡村音乐)。和朋友一起享受美食是我生活中必不可少的一部分,我还喜欢参观世界各地有趣的地方。为了能够享受美食,我还坚持跑步。
关于我的更多信息,请见我的网站www.stroustrup.com。特别是,你可以在那里找到我名字的正确发音。
Lawrence“Pete”Petersen
2006年年末,Pete如此介绍他自己:“我是一名教师。近20年来,我一直在德州农工大学讲授程序设计语言。我已5次被学生选为优秀教师,并于1996年被工程学院的校友会选为杰出教师。我是Wakonse优秀教师计划的委员和教师发展研究院院士。
作为一名陆军军官的儿子,我的童年是在不断迁移中度过的。在华盛顿大学获得哲学学位后,我作为野战炮兵官员和操作测试研究分析员在军队服役了22年。1971年至1973年期间,我在俄克拉荷马希尔堡讲授野战炮兵军官的高级课程。1979年,我帮助创建了测试军官的训练课程,并在1978年至1981年及1985年至1989年期间在跨越美国的九个不同地方以首席教官的身份讲授这门课程。
1991年我组建了一个小型的软件公司,生产供大学院系使用的管理软件,直至1999年。我的兴趣在于讲授、设计和实现供人们使用的实用软件。我在乔治亚理工大学获得了工业管理学硕士学位,在德州农工大学获得了教育管理学硕士学位。我还从NTS获得了微型计算机硕士学位。我在德州农工大学获得了信息与运营管理学博士学位。
我和我的妻子Barbara都生于德州的布莱恩。我们喜欢旅行、园艺和招待朋友;我们花尽可能多的时间陪我们的儿子和他们的家庭,特别是我们的孙子和孙女Angelina、Carlos、Tess、Avery、Nicholas和Jordan。”
令人悲伤的是,Pete于2007年死于肺癌。如果没有他,这门课程绝对不会取得成功。
目录
译者序
前言
引言
作者简介
第15章 容器和迭代器 1
15.1 存储和处理数据 1
15.1.1 处理数据 1
15.1.2 泛化代码 2
15.2 STL理念 4
15.3 序列和迭代器 7
15.3.1 回到实例 8
15.4 链表 9
15.4.1 链表操作 11
15.4.2 遍历 12
15.5 再次泛化vector 13
15.5.1 遍历容器 15
15.5.2 auto 15
15.6 实例:一个简单的文本编辑器 16
15.6.1 处理行 18
译者序
本书的作者Bjarne Stroustrup是C++语言的设计者和最初的实现者,也是《The C++ Programming Language》(Addison-Wesley出版社)一书的作者。他现在是摩根斯坦利技术部门的总经理和哥伦比亚大学的客座教授,美国国家工程院的院士,ACM会士和IEEE会士。在进入学术界之前,他为AT&T贝尔实验室工作多年。他是ISO标准组织C++委员会的创建者,现在是该委员会语言演化工作组的主席。本书第1版已成为程序设计领域的经典著作,第2版又进行了精心的修订,增加了一些新的内容,包括C++14的一些新特性。
虽然是面向初学者,但本书原版仍是大部头。为方便读者循序渐进地学习,我们重新组织了章节顺序,将原版书组织为基础篇和进阶篇两册。基础篇包括第1~11章、第17~19章和附录A、C,进阶篇包括第12~16章、第20~27章和附录B、D、E。
基础篇 原书 进阶篇 原书
第1章 第1章 第15章 第20章
第2章 第2章 第16章 第21章
第3章 第3章 第17章 第12章
第4章 第4章 第18章 第13章
第5章 第5章 第19章 第14章
第6章 第6章 第20章 第15章
第7章 第7章 第21章 第16章
第8章 第8章 第22章 第22章
第9章 第9章 第23章 第23章
第10章 第10章 第24章 第24章
第11章 第11章 第25章 第25章
第12章 第17章 第26章 第26章
第13章 第18章 第27章 第27章
第14章 第19章 附录C 附录B
附录A 附录A 附录D 附录D
附录B 附录C 附录E 附录E
前言
——Admiral Farragut
程序设计是这样一门艺术,它将问题求解方案描述成计算机可以执行的形式。程序设计中很多工作都花费在寻找求解方案以及对其求精上。通常,只有在真正编写程序求解一个问题的过程中才会对问题本身理解透彻。
本书适合于那些从未有过编程经验但愿意努力学习程序设计技术的初学者,它能帮助读者理解使用C++语言进行程序设计的基本原理并获得实践技巧。本书的目标是使你获得足够多的知识和经验,以便能使用最新、最好的技术进行简单有用的编程工作。达到这一目标需要多长时间呢?作为大学一年级课程的一部分,你可以在一个学期内完成这本书的学习(假定你有另外四门中等难度的课程)。如果你是自学的话,不要期望能花费更少的时间完成学习(一般来说,每周15个小时,14周是合适的学时安排)。
三个月可能看起来是一段很长的时间,但要学习的内容很多。写第一个简单程序之前,就要花费大约一个小时。而且,所有学习过程都是渐进的:每一章都会介绍一些新的有用的概念,并通过真实应用中的例子来阐述这些概念。随着学习进程的推进,你通过程序代码表达思想的能力——让计算机按你的期望工作的能力,会逐渐稳步地提高。我绝不会说:“先学习一个月的理论知识,然后看看你是否能使用这些理论吧。”
为什么要学习程序设计呢?因为我们的文明是建立在软件之上的。如果不理解软件,那么你将退化到只能相信“魔术”的境地,并且将被排除在很多最为有趣、最具经济效益和社会效益的领域之外。当我谈论程序设计时,我所想到的是整个计算机程序家族,从带有GUI(图形用户界面)的个人计算机程序,到工程计算和嵌入式系统控制程序(如数码相机、汽车和手机中的程序),以及文字处理程序等,在很多日常应用和商业应用中都能看到这些程序。程序设计与数学有些相似,认真去做的话,会是一种非常有用的智力训练,可以提高我们的思考能力。然而,由于计算机能做出反馈,程序设计不像大多数数学形式那么抽象,因而对多数人来说更易接受。可以说,程序设计是一条能够打开你的眼界,将世界变得更美好的途径。最后,程序设计可以是非常有趣的。
为什么学习C++这门程序设计语言呢?学习程序设计是不可能不借助一门程序设计语言的,而C++直接支持现实世界中的软件所使用的那些关键概念和技术。C++是使用最为广泛的程序设计语言之一,其应用领域几乎没有局限。从大洋深处到火星表面,到处都能发现C++程序的身影。C++是由一个开放的国际标准组织全面考量、精心设计的。在任何一种计算机平台上都能找到高质量的、免费的C++实现。而且,用C++所学到的程序设计思想,大多数可直接用于其他程序设计语言,如C、C#、Fortran以及Java。最后一个原因,我喜欢C++适合编写优美、高效的代码这一特点。
本书不是初学程序设计的最简单入门教材,我写此书的用意也不在此。我为本书设定的目标是——这是一本能让你学到基本的实用编程技术的最简单书籍。这是一个非常雄心勃勃的目标,因为很多现代软件所依赖的技术,不过才出现短短几年时间而已。
我的基本假设是:你希望编写供他人使用的程序,并愿意认真负责地以较高质量完成这个工作,也就是说,假定你希望达到专业水准。因此,我为本书选择的主题覆盖了开始学习实用编程技术所需要的内容,而不只是那些容易讲授和容易学习的内容。如果某种技术是你做好基本编程工作所需要的,那么本书就会介绍它,同时展示用以支持这种技术的编程思想和语言工具,并提供相应的练习,期望你通过做这些练习来熟悉这种技术。但如果你只想了解“玩具程序”,那么你能学到的将远比我所提供的少得多。另一方面,我不会用一些实用性很低的内容来浪费你的时间,本书介绍的内容都是你在实践中几乎肯定会用到的。
如果你只是希望直接使用别人编写的程序,而不想了解其内部原理,也不想亲自向代码中加入重要的内容,那么本书不适合你,采用另一本书或另一种程序设计语言会更好些。如果这大概就是你对程序设计的看法,那么请同时考虑一下你从何得来的这种观点,它真的满足你的需求吗?人们常常低估程序设计的复杂程度和它的重要性。我不愿看到,你不喜欢程序设计是因为你的需求与我所描述的软件世界之间不匹配而造成的。信息技术世界中有很多地方是不要求程序设计知识的。本书面向的是那些确实希望编写和理解复杂计算机程序的人。
考虑到本书的结构和注重实践的特点,它也可以作为学习程序设计的第二本书,适合那些已经了解一点C++的人,以及那些会用其他语言编程而现在想学习C++的人。如果你属于其中一类,我不好估计你学习这本书要花费多长时间。但我可以给你的建议是,多做练习。因为你在学习中常见的一个问题是习惯用熟悉的、旧的方式编写程序,而不是在适当的地方采用新技术,多做练习会帮助你克服这个问题。如果你曾经按某种更为传统的方式学习过C++,那么在进行到第7章之前,你会发现一些令你惊奇的、有用的内容。除非你的名字是Stroustrup,否则你会发现我在本书中所讨论的内容不是“你父辈的C++”。
学习程序设计要靠编程实践。在这一点上,程序设计与其他需要实践学习的技艺是相似的。你不可能仅仅通过读书就学会游泳、演奏乐器或者开车,必须进行实践。同样,你也不可能不读写大量代码就学会程序设计。本书给出了大量代码实例,都配有说明文字和图表。你需要通过读这些代码来理解程序设计的思想、概念和原理,并掌握用来表达这些思想、概念和原理的程序设计语言的特性。但有一点很重要,仅仅读代码是学不会编程实践技巧的。为此,你必须进行编程练习,通过编程工具熟悉编写、编译和运行程序。你需要亲身体验编程中会出现的错误,学习如何修改它们。总之,在学习程序设计的过程中,编写代码的练习是不可替代的。而且,这也是乐趣所在!
另一方面,程序设计远非遵循一些语法规则和阅读手册那么简单。本书的重点不在于C++的语法,而在于理解基础思想、原理和技术,这是一名好程序员所必备的。只有设计良好的代码才有机会成为一个正确、可靠和易维护的系统的一部分。而且,“基础”意味着延续性:当现在的程序设计语言和工具演变甚至被取代后,这些基础知识仍会保持其重要性。
那么计算机科学、软件工程、信息技术等又如何呢?它们都属于程序设计范畴吗?当然不是!但程序设计是一门基础性的学科,是所有计算机相关领域的基础,在计算机科学领域占有重要的地位。本书对算法、数据结构、用户接口、数据处理和软件工程等领域的重要概念和技术进行了简要介绍,但本书不能替代对这些领域的全面、均衡的学习。
代码可以很有用,同样可以很优美。本书会帮你了解这一点,同时理解优美的代码意味着什么,并帮你掌握构造优美代码的原理和实践技巧。祝你学习程序设计顺利!
致学生
到目前为止,我在德州农工大学已经用本书教过几千名大一新生,其中60%曾经有过编程经历,而剩余40%从未见过哪怕一行代码。大多数学生的学习是成功的,所以你也可以成功。
你不一定是在某门课程中学习本书,本书也广泛用于自学。然而,不管你学习本书是作为课程的一部分还是自学,都要尽量与他人协作。程序设计有一个不好的名声——它是一种个人活动,这是不公正的。大多数人在作为一个有共同目标的团体的一份子时,工作效果更好,学习得更快。与朋友一起学习和讨论问题不是“作弊”,而是取得进步最有效同时也是最快乐的途径。如果没有特殊情况的话,与朋友一起工作会促使你表达出自己的思想,这正是测试你对问题理解和确认你的记忆的最有效方法。你没有必要独自解决所有编程语言和编程环境上的难题。但是,请不要自欺欺人——不去完成那些简单练习和大量的习题(即使没有老师督促你,你也不应这样做)。记住:程序设计(尤其)是一种实践技能,需要通过实践来掌握。如果你不编写代码(完成每章的若干习题),那么阅读本书就纯粹是一种无意义的理论学习。
大多数学生,特别是那些爱思考的好学生,有时会对自己努力工作是否值得产生疑问。当你产生这样的疑问时,休息一会儿,重新读一下前言,读一下第1章和第22章。在那里,我试图阐述我在程序设计中发现了哪些令人兴奋的东西,以及为什么我认为程序设计是能为世界带来积极贡献的重要工具。如果你对我的教学哲学和一般方法有疑问,请阅读引言。
你可能会对本书的厚度感到担心。本书如此之厚的一部分原因是,我宁愿反复重复一些解释说明或增加一些实例,而不是让你自己到处找这些内容,这应该令你安心。另外一个主要原因是,本书的后半部分是一些参考资料和补充资料,供你想要深入了解程序设计的某个特定领域(如嵌入式系统程序设计、文本分析或数值计算)时查阅。
序言
——瑞士军队谚语
讲授和学习本书的方法
我们是如何帮助你学习的?又是如何安排学习进程的?我们的做法是,尽力为你提供编写高效的实用程序所需的最基本的概念、技术和工具,包括程序组织、调试和测试、类设计、计算、函数和算法设计、绘图方法(仅介绍二维图形)、图形用户界面(GUI)、文本处理、正则表达式匹配、文件和流输入输出(I/O)、内存管理、科学/数值/工程计算、设计和编程思想、C++标准库、软件开发策略、C语言程序设计技术。认真完成这些内容的学习,我们会学到如下程序设计技术:过程式程序设计(C语言程序设计风格)、数据抽象、面向对象程序设计和泛型程序设计。本书的主题是程序设计,也就是表达代码意图所需的思想、技术和工具。C++语言是我们的主要工具,因此我们比较详细地描述了很多C++语言的特性。但请记住,C++只是一种工具,而不是本书的主题。本书是“用C++语言进行程序设计”,而不是“C++和一点程序设计理论”。
我们介绍的每个主题都至少出于两个目的:提出一种技术、概念或原理,介绍一个实用的语言特性或库特性。例如,我们用一个二维图形绘制系统的接口展示如何使用类和继承。这使我们节省了篇幅(也节省了你的时间),并且还强调了程序设计不只是简单地将代码拼装起来以尽快地得到一个结果。C++标准库是这种“双重作用”例子的主要来源,其中很多主题甚至具有三重作用。例如,我们会介绍标准库中的向量类vector,用它来展示一些广泛使用的设计技术,并展示很多用来实现vector的程序设计技术。我们的一个目标是向你展示一些主要的标准库功能是如何实现的,以及它们如何与硬件相配合。我们坚持认为一个工匠必须了解他的工具,而不是仅仅把工具当作“有魔力的东西”。
对于一个程序员来说,总是会对某些主题比对其他主题更感兴趣。但是,我们建议你不要预先判断你需要什么(你怎么知道你将来会需要什么呢?),至少每一章都要浏览一下。如果你学习本书是作为一门课程的一部分,你的老师会指导你如何选择学习内容。
我们的教学方法可以描述为“深度优先”,同时也是“具体优先”和“基于概念”。首先,我们快速地(好吧,是相对快速地,从第1章到第11章)将一些编写小的实用程序所需的技巧提供给你。在这期间,我们还简明扼要地提出很多工具和技术。我们着重于简单具体的代码实例,因为相对于抽象概念,人们能更快领会具体实例,这就是多数人的学习方法。在最初阶段,你不应期望理解每个小的细节。特别是,你会发现对刚刚还工作得好好的程序稍加改动,便会呈现出“神秘”的效果。尽管如此,你还是要尝试一下!还有,请完成我们提供的简单练习和习题。请记住,在学习初期你只是没有掌握足够的概念和技巧来准确判断什么是简单的,什么是复杂的。请等待一些惊奇的事情发生,并从中学习吧。
我们会快速通过这样一个初始阶段——我们想尽可能快地带你进入编写有趣程序的阶段。有些人可能会质疑,“我们的进展应该慢些、谨慎些,我们应该先学会走,再学跑!”但是你见过小孩学习走路吗?实际上小孩在学会平稳地慢慢走路之前就开始尝试跑了。与之相似,你可以先勇猛向前,偶尔摔一跤,从中获得编程的感觉,然后再慢下来,获得必要的精确控制能力和准确的理解。你必须在学会走之前就开始跑!
你不要投入大量精力试图学习一些语言或技术细节的所有相关内容。例如,你可以熟记所有C++的内置类型及其使用规则。你当然可以这么做,而且这么做会使你觉得自己很博学。但是,这不会使你成为一名程序员。如果你学习中略过一些细节,将来可能偶尔会因为缺少相关知识而被“灼伤”,但这是获取编写好程序所需的完整知识结构的最快途径。注意,我们的这种方法本质上就是小孩学习其母语的方法,也是教授外语的最有效方法。有时你不可避免地被难题困住,我们鼓励你向授课老师、朋友、同事、指导教师等寻求帮助。请放心,在前面这些章节中,所有内容本质上都不困难。但是,很多内容是你所不熟悉的,因此最初可能会感觉有点难。
随后,我们介绍一些入门技巧来拓宽你的知识。我们通过实例和习题来强化你的理解,为你提供一个程序设计的概念基础。
我们非常强调思想和原理。思想能指导你求解实际问题——可以帮助你知道在什么情况下问题求解方案是好的、合理的。你还应该理解这些思想背后的原理,从而理解为什么要接受这些思想,为什么遵循这些思想会对你和使用你的代码的用户有帮助。没有人会满意“因为事情就是如此”这样的解释。更为重要的是,如果真正理解了思想和原理,你就能将自己已知的知识推广到新的情况;就能用新的方法将思想和工具结合来解决新的问题。知其所以然是学会程序设计技巧所必需的。相反,仅仅不求甚解地记住大量规则和语言特性有很大局限,是错误之源,是在浪费时间。我们认为你的时间很珍贵,尽量不要浪费它。
我们把很多C++语言层面的技术细节放在了附录和手册中,你可以随时按需查找。我们假定你有能力查找到需要的信息,你可以借助目录来查找信息。不要忘了编译器和互联网的在线功能。但要记住,要对所有互联网资源保持足够的怀疑,直至你有足够的理由相信它们。因为很多看起来很权威的网站实际上是由程序设计新手或者想要出售什么东西的人建立的。而另外一些网站,其内容都是过时的。我们在支持网站www.stroustrup.com/Programming上列出了一些有用的网站链接和信息。
请不要过于急切地期盼“实际的”例子。我们理想的实例都是能直接说明一种语言特性、一个概念或者一种技术的简短代码。很多现实世界中的实例比我们给出的实例要凌乱很多,而且所能展示的知识也不比我们的实例更多。包含数十万行代码的成功商业程序中所采用的技术,我们用几个50行规模的程序就能展示出来。理解现实世界程序的最快途径是好好研究一些基础的小程序。
另一方面,我们不会用“聪明可爱的风格”来阐述我们的观点。我们假定你的目标是编写供他人使用的实用程序,因此书中给出的实例要么是用来说明语言特性,要么是从实际应用中提取出来的。我们的叙述风格都是用专业人员对(将来的)专业人员的那种口气。
一般方法
本书的内容组织适合从头到尾一章一章地阅读,当然,你也常常要回过头来对某些内容读上第二遍、第三遍。实际上,这是一种明智的方法,因为当遇到还看不出什么门道的地方时,你通常会快速掠过。对于这种情况,你最终还是会再次回到这个地方。然而,这么做要适度,因为除了交叉引用之外,对本书其他部分,你随便翻开一页,就从那里开始学习,并希望成功,是不可能的。本书每一节、每一章的内容安排,都假定你已经理解了之前的内容。
本书的每一章都是一个合理的自包含单元,这意味着应一口气读完(当然这只是理论上,实际上由于学生紧密的学习计划,不总是可行)。这是将内容划分为章的主要标准。其他标准包括:从简单练习和习题的角度,每章是一个合适的单元;每一章提出一些特定的概念、思想或技术。这种标准的多样性使得少数章过长,所以不要教条地遵循“一口气读完”的准则。特别是当你已经考虑了思考题,做了简单练习,并做了一些习题时,你通常会发现你需要回过头去重读一些小节和几天前读过的内容。
“它回答了我想到的所有问题”是对一本教材常见的称赞,这对细节技术问题是很理想的,而早期的读者也发现本书有这样的特性。但是,这不是全部的理想,我们希望提出初学者可能想不到的问题。我们的目标是,回答那些你在编写供他人使用的高质量软件时需要考虑的问题。学习回答好的(通常也是困难的)问题是学习如何像一个程序员那样思考所必需的。只回答那些简单的、浅显的问题会使你感觉良好,但无助于你成长为一名程序员。
我们努力尊重你的智力,珍惜你的时间。在本书中,我们以专业性而不是精明伶俐为目标,宁可有节制地表达一个观点而不大肆渲染它。我们尽力不夸大一种程序设计技术或一个语言特性的重要性,但请不要因此低估“这通常是有用的”这种简单陈述的重要程度。如果我们平静地强调某些内容是重要的,意思是你如果不掌握它,或早或晚都会因此而浪费时间。
我们不会伪称本书中的思想和工具是完美的。实际上没有任何一种工具、库、语言或者技术能够解决程序员所面临的所有难题,至多能帮助你开发、表达你的问题求解方案而已。我们尽量避免“无害的谎言”,也就是说,我们会尽力避免过于简单的解释,虽然这些解释清晰且易理解,但在实际编程和问题求解时却容易弄错。另一方面,本书不是一本参考手册,如果需要C++详细完整的描述,请参考Bjarne Stroustrup的《The C++ Programming Language》第4版(Addison-Wesley出版社,2013年)和ISO的C++标准。