前 言
程序设计是这样一门艺术,它将问题解决方案描述成计算机能够执行的形式。程序设计中的大部分工作都在寻找和完善解决方案。通常,只有经历了通过程序设计解决问题的过程,才能完全理解问题。
本书适合那些从未接触过程序设计但愿意努力学习的初学者。它帮助你理解程序设计的原理并掌握使用C++语言的实践技能。本书的目标是让你获得足够的知识和经验,以便使用最新的技术执行简单而实用的程序设计任务。需要多长时间呢?如果作为大学一年级课程的一部分,你可以在一个学期内完成本书的学习(假设你有4门中等难度的课程)。如果自学,不要期望花费更少的时间完成学习(一般是每周15小时,连续14周)。
3个月似乎很长,但有很多东西要学,之后你就可以编写第一个简单的程序了。此外,所有的学习都是循序渐进的:每一章都介绍了有用的新概念,并通过从实际应用中获得启发的例子来说明它们。你用代码表达思想的能力—让计算机做你想让它做的事情—随着你的使用逐渐而稳定地增强。我从来不说:“学一个月的理论知识,然后看看你是否能运用这些理论。”
你为什么要学习程序设计?我们的文明是建立在软件之上的。如果不了解软件,你就只能退化到相信“魔法”,并将无法进入许多最有趣的、最有利可图的、对社会有用的技术领域工作。当我谈到程序设计时,我想到的是计算机程序的整个范围,从带有图形用户界面(GUI)的个人计算机应用程序,到工程计算和嵌入式系统控制应用程序(如数码相机、汽车和手机中的程序),再到在许多人文和商业应用程序中发现的文本操作应用程序。就像数学一样,程序设计—如果做得好—是一种有价值的智力训练,可以提高我们的思考能力。然而,由于计算机能做出反馈,程序设计比大多数形式的数学更具体,因此更容易为多数人所接受。这是一种接触并改变世界的方式—理想情况下是让世界变得更美好。最后,程序设计可以是非常有趣的。
为什么选择C++?你不能脱离程序设计语言学习程序设计,而C++直接支持实际软件中使用的关键概念和技术。C++是使用最广泛的程序设计语言之一,广泛应用于各种应用领域。从大洋深处到火星表面,你可以在各个地方找到C++应用。C++由非专有的国际标准精确定义。在各种计算机上都可以找到高质量、免费的C++实现版本。从C++中学习的大多数程序设计概念可以直接应用于其他语言,如C、C#、Fortran和Java。最后一个原因,我喜欢C++,因为它是一种可编写优雅高效代码的语言。
本书并不是关于初学者程序设计的最简单的书籍,它也不是为了这个目的而写的。我只希望它成为你学习实际程序设计基础的最简单的书籍。这是一个相当雄心勃勃的目标,因为许多现代软件都依赖于几年前被认为先进的技术。
我的基本假设是:你想要编写供他人使用的程序,并负责任地这样做,提供一个合理的系统质量水平;也就是说,假设你想要达到一定的专业水平。因此,我为本书选择的主题涵盖了开始实际程序设计所需的内容,而不仅仅是易于教授和学习的内容。如果你需要某种技术来正确地完成基本工作,我将对其进行描述,演示支持该技术所需的概念和语言工具,为此提供练习,并期望你完成这些练习。如果你只是想了解简单程序,你可以少学很多我所介绍的内容。另一方面,我不会浪费你们的时间在那些没有实际意义的材料上。如果在这里解释一个想法,那是因为你肯定会用到它。
如果你只想要使用别人的代码,而不理解事情是如何完成的,也不想自己大量添加代码,那么这本书不适合你。如果是这样,请考虑选择另一本书和另一种语言或许对你更好。如果这是你对程序设计的大致看法,请考虑一下你是从哪里得到这种观点的,以及它实际上是否足以满足你的需求。人们常常低估程序设计的复杂性及其价值。我不希望你因为所需要的与我所描述的软件现实之间的不匹配而对程序设计产生厌恶。信息技术世界中有许多地方不需要程序设计知识。本书是为那些想要编写或理解重要程序的人服务的。
由于本书的结构和实际目标,它也可以作为那些已经了解一些C++的人的第二本关于程序设计的书籍,或者供使用其他程序设计语言并想学习C++的人使用。如果你属于其中一类人,我就不好猜测你阅读本书需要多长时间,但我建议你完成很多练习。这将帮助你克服一个常见问题,即编写程序时倾向于使用旧的、熟悉的风格,而不是采用更适合的新技术。如果你是通过更传统的方式学习C++的,那么在你进行到第7章学习之前,你会发现一些令人惊讶和有用的内容。除非你的名字是Stroustrup,否则我在这里讨论的内容不是“你父辈的C++”。
程序设计是通过编写程序来学习的。在这一点上,程序设计与其他具有实践内容的工作类似。你不可能仅仅通过读书就学会游泳、演奏乐器或驾驶汽车—你必须练习。如果不阅读和编写大量代码,你也不可能学会程序设计。本书重点介绍与解释性文本和图表密切相关的代码示例。你需要这些知识来理解程序设计的思想、概念和原则,并掌握用于表达它们的语言结构。这是必要的,但仅靠它本身,它不会给你提供实际的程序设计的技能。为此,你需要进行练习,并熟悉编写、编译和运行程序的工具。你需要自己犯错误,并学会改正。编写代码是不可替代的,而且这才是乐趣所在!
另一方面,程序设计远不止遵循一些规则和阅读手册,还有更多的东西。这本书着重强调的不是“C++的语法”。理解基本的思想、原则和技术是一个优秀程序员所必备的。只有设计良好的代码才有可能成为正确、可靠和可维护的系统的一部分。此外,“基本原理”是最持久的:即使今天的语言和工具进化或被取代,它们仍然是必不可少的。
计算机科学、软件工程、信息技术等又怎么样呢?这就是所有的程序设计吗?当然不是!程序设计是所有计算机相关领域的基础主题之一,它在计算机科学的均衡课程中有一个自然的位置。虽然书中简要介绍了算法、数据结构、用户界面、数据处理和软件工程的关键概念和技术,然而,这本书并不能代替对这些主题进行全面和均衡的研究。
代码可以既美观又实用。本书旨在帮助你认识到这一点,理解代码美观的含义,并帮助你掌握创建此类代码的原理和实践技能。祝你在程序设计中顺利!
致学生
到目前为止,我们在得克萨斯农工大学(Texas A&M University)用这本书教过的数千名一年级学生中,大约60%的人以前有过程序设计经历,大约40%的人在生活中从未见过一行代码。大多数人都成功了,所以你也可以做到。
你不必把本书作为课程的一部分来阅读,本书被广泛用于自学。然而,无论你是作为课程的一部分还是独立学习,都要尝试与他人合作。程序设计被认为是一种孤独的活动,这是不公平的评价。大多数人在有共同目标的团队中工作得更好,学习得更快。和朋友一起学习,一起讨论问题不是作弊!这是最有效的,也是最令人愉快的取得进步的方式。如果没有别的,和朋友一起工作可以促使你清楚地表达你的想法,这是测试你的理解力和确保你记住的最有效方法。实际上,你不必亲自去发现每一个晦涩的语言和程序设计环境问题的答案。但请不要欺骗自己,不做练习和大量的习题(即使没有老师强迫你做)。记住:程序设计是一种实践技能,你需要练习才能掌握。如果你不写代码(完成每章的几个练习),那么阅读这本书将是一个毫无意义的理论学习。
大多数学生,尤其是爱思考的好学生,都会面临这样的时刻:怀疑自己的努力是否值得。当这种情况发生在你身上时(不是如果),请休息一下,重新阅读前言,并查看第1章(计算机、人和程序设计)和第22章(理念与历史)。在这两章中,我试图阐明程序设计让我感到兴奋的地方,以及为什么我认为程序设计是能对世界做出积极贡献的重要工具。如果你想知道我的教学理念和一般方法,请参阅引言(“致读者”)。
你可能会担心这本书的厚度,但应该让你放心的是,这本书之所以厚,部分原因是我更喜欢重复解释或添加示例,而不是让你寻找唯一的解释。另一个主要原因是,本书的最后部分是附录和参考文献,只有当你对程序设计的特定领域(如嵌入式系统程序设计、文本分析或数值计算)的更多信息感兴趣时,才会提供给你探索。
请不要太没耐心。学习任何有价值的新技能都需要时间,并且都是值得的。
致教师
本书不是传统的计算机科学导论的书,而是一本关于如何构建工作软件的书。因此,它省略了许多计算机科学系学生传统上接触到的内容(图灵完备性、状态机、离散数学、乔姆斯基语法等)。甚至硬件也被省略了,因为假设学生从幼儿园开始就以各种方式使用计算机了。
本书甚至没有试图提及计算机科学领域最重要的主题。它是关于程序设计(或者更普遍的是关于如何开发软件)的,因此它比许多传统课程更详细,主题更少。它只试图做好一件事,并且计算机科学也不是一门课程能包含的。如果本书/课程被用作计算机科学、计算机工程、电气工程(我们的第一批学生许多是电气工程专业的)、信息科学或任何项目的一部分,我希望它能作为全面介绍的一部分与其他课程一起教授。
请阅读引言(“致读者”),了解我的教学理念、一般方法等。在学习的过程中,请试着把这些观点传达给你的学生。
ISO标准C++
C++是由ISO标准定义的。第一个ISO C++标准于1998年正式通过,因此该版本的C++被称为C++ 98。本书的第一版是我在C++ 11的设计过程中编写的。最令人沮丧的是不能使用新特性(如统一初始化、循环范围、移动语义、lambdas和概念)来简化原则和技术的表示。然而,本书在设计时考虑到了C++ 11,所以相对容易将特性“放入”到它们所属的上下文中。在撰写本文时,当时的标准是2011年的C++ 11,而2014年的ISO标准C++ 14的功能正在寻找进入主流C++实现的方式。本书使用的语言是C++ 11,带有一些C++ 14的特性。例如,如果你的编译器运行下面代码报错:
vector<int> v1;
vector<int> v2 {v1}; // C++14-style copy construction
请使用下面代码代替:
vector<int> v1;
vector<int> v2 = v1; // C++98-style copy construction
如果你的编译器不支持C++ 11,那就换一个新的编译器。优秀的现代C++编译器可以从各种供应商下载;参见www.stroustrup.com/compilers.html。学习使用该语言的早期版本和较少支持的版本进行程序设计可能会遇到不必要的困难。
资源
本书的支持网站www.stroustrup.com/Programming包含了各种支持使用本书进行程序设计教学和学习的材料。材料可能会随着时间的推移不断改进,但对于初学者来说,你可以找到:
基于本书讲义的幻灯片。
讲师指南。
本书使用的库的头文件和实现。
本书中的示例代码。
部分练习题答案。
可能有用的链接。
勘误表。
欢迎随时提出对这些资料的改进建议,本书的参考文献可扫描右侧二维码。
致谢
我特别要感谢已故的同事和合作导师劳伦斯“皮特”彼得森(Lawrence “Pete” Petersen),他在我自己感到自信之前就鼓励我着手完成教授初学者的任务,并向我传授了使课程取得成功的实践教学经验。没有他,这门课程的第一个版本就会失败。我们共同合作开发了这本书所设计课程的第一个版本,并一起多次教授它,从经验中学习,改进了课程和书籍。在本书中,“我们”最初指的是“皮特和我”。
感谢得克萨斯农工大学(Texas A&M University)的ENGR 112、ENGR 113和CSCE 121的学生、助教和同行教师,他们直接和间接地帮助我们构建了这本书,感谢曾教授这门课程的Walter Daugherity、Hyunyoung Lee、Teresa Leyk、Ronnie Ward和Jennifer Welch。还要感谢Damian Dechev、Tracy Hammond、Arne Tolstrup Madsen、Gabriel Dos Reis、Nicholas Stroustrup、J. C. van Winkel、Greg Versoonder、Ronnie Ward和Leor Zolman对本书草稿提出的建设性意见。感谢Mogens Hansen给我解释了有关发动机控制软件的内容。感谢Al Aho、Stephen Edwards、Brian Kernighan和Daisy Nguyen在夏季帮助我远离干扰,专心写作。
感谢Art Werschulz,他在纽约福特汉姆大学课程中使用了本书的第1版,并给出反馈和建设性意见,还要感谢Nick Maclaren,他在剑桥大学课程中使用了本书的第1版,并给出了详细评论,他的学生的背景和职业需求与得克萨斯农工大学的一年级学生有着显著的不同。
感谢Addison-Wesley为我找到的评审人员Richard Enbody、David Gustafson、Ron McCarty和K. Narayanaswamy。他们的评论主要基于在大学教授C++或计算机科学导论课程的经验,对我非常宝贵。还要感谢我的编辑Peter Gordon,他提供了许多有用的评论,也感谢他的耐心。
我非常感谢Addison-Wesley组织的制作团队:Linda Begley(校对员)、Kim Arney(排版师)、Rob Mauhar(插图师)、Julie Nahil(制作编辑)和Barbara Wood(文本编辑),他们为书籍的质量做出了很大的贡献。
感谢第1版的译者们,他们发现了许多问题并帮助澄清了许多观点。特别要感谢Lo c Joly和Michel Michaud对法语翻译进行了全面的技术审查,从而带来了许多改进。
我还要感谢Brian Kernighan和Doug McIlroy,他们在程序设计写作方面定了非常高的标准,以及Dennis Ritchie和Kristen Nygaard为实际语言设计提供的宝贵经验。