前言
(一)
1979年,Bjarne Stroustrup(C++之父)正在准备他的博士毕业论文,他有机会使用一种称为Simula 的语言。顾名思义,Simula语言主要用于仿真。其Simula 67版被公认是首款支持面向对象的语言。Stroustrup发现面向对象的思想对于软件开发非常有用,但是因Simula语言执行效率低,其实用性不强。于是他决定自行开发一种面向对象的语言,这就是今日的C++。
笔者一直关心TIOBE社区的程序设计语言排行榜,因为它能为开发和教学人员提供一份程序设计语言的行情变化资料。图1为2002年到2017年2月之间主要TIOBE程序设计语言排行的变化情况。在这个排行榜上发生了戏剧性变化的程序设计语言就是C++。其第一次戏剧性的变化发生在2004年,在这一年中它的市场份额急剧下滑。但在之后的10年间基本稳定,一直保持在第三位。本书的第1版就是在这样的情况下编写的。其第二次戏剧性变化是在本书的第1版出版之后,它先在2014年间急剧下跌,又在2015年奇迹般地回归。
图1 2002年到2017年2月TIOBE程序设计语言排行变化情况
C++的这些变化似乎有些莫名其妙,但认真地分析一下,这些变化还是可以解释的:其一是其他新兴语言(主要是C#和Object-C)对于市场份额的分割;其二则是其自身标准变化的影响。下面主要分析第二方面的因素。
C++是Bjarne Stroustrup于1979年准备一个项目时着手开发的一种程序设计语言,1985年被市场化。C++标准委员会于1998年11月推出了其第一个ISO标准(俗称C++98),2003年推出其ISO标准第2版(俗称C++03),C++11则是从2005年就开始提交,到2011年8月才发布的C++标准(俗称C++11,提交时称为C++0x)。从图1可以看出,每个标准出台到影响其市场份额有一个窗口期,这是该标准投石问路的过程。
C++03是C++98的修正版,其初衷是修正C++98的一些不足。但是由于C++脱胎于C,遵循着C是C++子集的原则,同时Bjarne Stroustrup坚持要保持其“适合教学”及既支持面向过程又支持面向对象的多泛型特色,成就了其概念清晰、设计严密、功能强大、效率较高的优点,但也带来过于复杂(如指针)、标准库功能不足,被人称为有精英化倾向的语言。因此它比较受教育界欢迎,而程序员觉得难用。不过,在通过C++03标准之前,人们还没有认识到这些问题,反而降低了效率,加剧了其缺陷的影响,使其在2004年遭受到第一次强力冲击。
2004—2005年间的滑铁卢之惨使C++的设计者和标准制定者开始清醒起来,将指导思想修订如下。
(1)维持与C++98,可能的话还有与C语言之间的兼容性与稳定性。
(2)尽可能通过标准程序库来引进新的特性,而不是扩展核心语言。
(3)能够促进编程技术的变更优先。
(4)改进 C++ 以帮助系统和程序库的设计,而不是引进只对特定应用有用的新特性。
(5)增强类型安全,给现行不安全的技术提供更安全的替代方案。
(6)增强直接与硬件协同工作的性能和能力。
(7)为现实世界中的问题提供适当的解决方案。
(8)实行零负担原则(如果某些功能要求额外支持,那么只有在该功能被用到时这些额外的支持才被用到) 。
(9)使C++易于教学。
简单地说,就是技术优先、安全高效、自由方便。这带给程序员一个全新的面貌,以至于连C++之父都说它像一种新语言。C++11成功了,它使C++摆脱了连续10年的步步下降,造就了TIOBE曲线2015年的戏剧性变化。
如图2所示,C++11已经公布四五年了,新的C++14也已经公布,C++17也在紧锣密鼓地部署之中。但是我国的C++程序设计教学的主流还停留在原始的C++98甚至更旧的版本上。如此严重脱离实际的状况到了该做出改变的时候了。这是笔者对这本C++教材进行改编的动因之一。
图2 近期C++标准修订步伐
不过,世界万物都有惯性。要一下子全部改到C++11上,很多人还是难以接受的,并且笔者自己也还在学习消化之中。在本书中,仅仅给出了C++11的部分新特点的接口,先让大家了解一下这些性能。在适当的时候,再做较全面和深入的介绍。
(二)
撇开C++11和C++14不谈,仅从一般性来讲,目前的C++教学也是不尽如人意的,把C++当作C的教学模式还广泛存在。在本书的第1版中虽然做了不少努力,但还不够。
Bjarne Stroustrup曾经感慨地说:“我不是使用支持工具进行巧妙设计的信徒,但是我强烈支持系统地使用数据抽象、面向对象编程和类属编程。不拥有支持库和模板,不进行事先的总体设计,而是埋头写下一页页的代码,这是在浪费时间,这是在给维护增加困难。”他还认为,“一个人对C 了解得越深,在写C++程序时就越难避免C 的风格,并会因此丢掉C++的某些潜在优势。”为此,他提出了以下几个相关的要点,在这些情况下做同样的事情时,在C++中存在比C中更好的处理方式。
(1)在C++中几乎不需要用宏。用const或enum 定义显式常量,用inline避免函数调用的额外开销,用template去刻画一簇函数或者类型,用namespace 去避免名字冲突。
(2)不用在需要变量之前去声明它,以保证立即对其进行初始化。声明可以出现在能出现语句的所有位置上,可以出现在for语句的初始化部分,也可以出现在条件中。
(3)不要用malloc(),new 运算符能将同样的事情做得更好。对于realloc(),试一试vector()。
(4)试着去避免void*、指针算术、联合和强制,除了在某些函数或类实现的深层之外。在大部分情况下,强制都是设计错误的指示器。如果必须使用某个显式的类型转换,设法用一个“新的强制”,设法写出一个描述自己想做的事情的更精确的语句。
(5)尽量少用数组和C风格的字符串。与传统的C风格相比,使用C++标准库string和vector常常可以简化程序设计。如果要符合C的连接规则,一个C++函数就必须被声明为具有C连接的。
最重要的是,要将程序考虑为一组由类和对象表示的相互作用的概念,而不是一堆数据结构和一些去拨弄数据结构中二进制位的函数。
探索如何彰显C++特色,也是本书改编的重要动因。
(三)
本次修改,将全书划分为4篇。
第1篇:C++面向对象起步。用4个单元帮助初学者建立面向对象的分析问题的思维,掌握相关方法和相关知识,树立面向对象程序设计中“一切皆对象,一切来自类”的意识。
第2篇:C++面向抽象程序设计。用两个单元帮助读者理解如何在一个程序中组织类,以及什么样的类结构才是好的程序结构。
第3篇:C++泛型程序设计。用两个单元介绍多态性和STL。C++的泛型、通用、灵活的特点给读者的学习带来了一定乐趣,也为读者将来从事程序开发工作提供了更多便捷 方法。
第4篇:C++深入编程。用3个单元介绍C++在名字和实体、常量、函数、I/O流等几个方面的细节,让读者在程序开发上能够做到锦上添花。进一步提升读者“程序设计=计算思维+语言艺术”的观念。
此外,本书每个单元都围绕一个主题展开,部分单元还增添了“知识链接”部分,其目的是引申基本内容,或为以后的学习作一些铺垫。
本书的结构体系安排是考虑了以下几个因素和写作思想的结果。
(1)B.S的建议。
(2)重要先学,特色优先。
(3)思维开路,语法补充。
(4)多层次教学需要。
需要说明一点:本书给出的许多示例,虽然有用,但主要用于说明一种语法概念或给出一种编程思路,还不是精益求精的实用程序。
(四)
由J.Piaget、O.Kernberg、R.J.Sternberg、D.Katz、Vogotsgy等人创建的建构主义(constructivism)学习理论认为,知识不是通过教师传授得到的,而是学习者在一定的情境即社会文化背景下借助其他人(包括教师和学习伙伴)的帮助,利用必要的学习资料,通过意义建构的方式而获得的。在信息时代,人们获得知识的途径发生了根本性的变化,教师不再是单一的“传道、授业、解惑”者,帮助学习者构建一个良好的学习环境也成为其一个重要职责。当然,这也是现代教材的责任。本书充分考虑了这些问题。
为了给读者创造一个良好的学习环境,本书的部分单元设置了“知识链接”栏目。这个栏目的设置可以帮助学习者对C++的机制作更深入的了解,也为精力充沛、不够消化者提供一点“加餐”。
除了正文外,在每个单元后面都安排了“概念辨析”“代码分析”“开发实践”和“探索验证”4种自测和训练实践环节,从而建立起一个全面的学习环境。
(1)概念辨析主要提供选择和判断两类自测题目,帮助学习者理解本单元学习过的有关概念,把当前学习内容所反映的事物尽量和自己已经知道的事物相联系,并认真思考这种联系,通过“自我协商”与“相互协商”,形成新知识的同化与顺应。
(2)代码分析。代码阅读是程序设计者所应掌握的基本能力之一。代码分析部分的主要题型是通过阅读程序找出错误或给出程序执行结果。
(3)开发实践。提高程序开发能力是本书的主要目标。本书在绝大多数单元后面都给出了相应的作业题目。但是,完成这些题目并非只是简单地写出其代码,而要将其看作一个“思维+语法+方法”的工程训练。因此,要求每道题的作业都要以文档的形式完成。文档中应包括以下内容。
① 问题分析与建模。
② 源代码设计。
③ 测试用例设计。
④ 程序运行结果分析。
⑤ 编程心得(包括运行中出现的问题与解决方法、对于测试用例的分析、对于运行结果的分析等)。
⑥ 文档的排版也要遵循统一的格式。
(4)探索验证。建构主义提倡,学习者要用探索法和发现法去建构知识的意义。学习者要在意义建构的过程中主动地收集和分析有关的信息资料,对碰到的问题提出各种假设,并努力加以验证。
(五)
笔者从事程序设计教学近30多年。这30多年是在不断探索中走过来的。从20世纪80年代末,笔者就开始探索程序设计课程从语法体系到问题驱动的改革;到了20世纪90年代中期又在此基础上考虑让学生在学习程序设计的同时掌握程序测试技能;2003年开始考虑如何改变学习了C++而设计出的程序却是面向过程的状况。每个阶段的探索都反映在自己不同时期的相关作品中。本书则是自我认识又一次深化的表达。
在这30多年的探索中,笔者越来越感觉到编写教材的责任很大、困难很多。要编写一本好的教材,不仅需要对本课程涉及内容有深刻的了解,还要熟悉相关领域的知识,特别是要不断探讨贯穿其中的教学理念和教育思想。所以,越到后来,就越感到自己知识和能力的不足。可是,作为一项历史性任务的研究,笔者又不愿意将之半途而废,只能硬着头皮写下去。每一次任务的完成,都得益于一些热心者的支持和帮助。在本书的写作过程中,赵忠孝教授、姚威博士、张展为博士以及张秋菊、史林娟、张有明、戴璐、张展赫、董兆军、吴灼伟(插图)等参加了有关部分的写作。在此谨表谢意。同时,一如既往地希望得到读者广泛的批评和建议,以便将这本书改得更好。
本书就要出版了。它的出版,是笔者在这项教学改革工作中跨上的一个新的台阶。笔者衷心希望得到有关专家和读者的批评和建议,也希望能多结交一些志同道合者,把这项教学改革推向更新的境界。
张基温
丁酉秋于穗小海之畔
·I·