C语言是在国内外广泛使用的一种计算机语言。学会使用C语言进行程序设计是计算机工作者的一项基本功。
作者在1991年编著了《C程序设计》一书,由清华大学出版社出版。该书出版后反映很好,许多读者说“C语言原来是比较难学的,但自从《C程序设计》出版后,C语言变得不难学了”。该书被全国大多数高校选为正式教材,许多高校都指定该书为研究生入学考试必读教材。该书已成为国内读者学习C语言的主流用书。20多年来,该书已先后出了4版,重印了100多次,累计发行了1200多万册,是国内外同类书之首。作者到全国各高校和各企事业单位访问时,许多在校师生和已毕业参加了工作的人士都说他们学过这本书,印象很深,作者在内心深切地感受到广大读者的殷切期望。
各校师生普遍认为该书内容系统,讲解详尽,包含了许多其他教材中没有的内容,尤其是针对编程实践中容易出现的问题作了提醒和分析,被认为是学习C语言程序设计的理想教材。同时有的学校提出,由于各校情况不完全相同(例如,学校的类型不同、教学要求不同、安排的学时数不同、学生的基础不同),希望在保持原有的优点的基础上,能提供适用于不同要求的版本。作者和出版社征求了多方面的意见,进行了反复的研究,除了继续出版和完善《C程序设计》以外,还针对学时较少的学校,2007年出版了《C程序设计教程》,该教材以《C程序设计》一书为基础,紧扣最基本的要求,适当减少内容,压缩篇幅,突出重点。出版后受到广泛欢迎,认为内容适当,概念清晰,被教育部评为“十一·五高等学校规划教材”,向全国各高校推荐。
经过6年的教学实践,现在对《C程序设计教程》一书进行修订。在修订的过程中,作者思考了以下几个方面的问题。
1. 程序设计课程的作用与要求
近年来,在讨论C程序设计课程改革时,有的老师主张要学深学透;有的认为不能要求太高,主要是打好基础;有的认为有一些了解、初识即可;有的则认为大学生毕业后由自己编程序的机会不多,因此可不必学,课程可以取消。这些引起人们深入地思考:大学生要不要上程序设计课?程序设计课的目的和作用是什么?学习程序设计课程的要求是什么?程序设计课程的内容应该是什么?
作者认为,学习程序设计能够使大学生更好地理解计算机和应用计算机。
计算机的本质是“程序的机器”,程序和指令的思想是计算机系统中最基本的概念。只有懂得程序设计,懂得计算机是怎样工作的,才能较好地懂得计算机。通过学习程序设计,能使学生学习到用计算机处理问题的方法,培养学生提出问题、分析问题和解决问题的能力,并且具有编制程序的初步能力,能较好地应用计算机。
〖〗〖〗〖〗〖〗〖〗 即使将来不是计算机专业人员,由于学过程序设计,了解软件的特点和生产过程,所以也能与程序开发人员更好地沟通与合作,开展本领域中的计算机应用,开发与本领域有关的应用程序。
如果一般大学生不学程序设计,全国只有计算机专业的学生学习程序设计,将会产生灾难性的后果。无论国内外,IT界中许多优秀人才是从非计算机专业毕业的。在各领域开发应用软件的,也有许多来自非计算机专业的。因此,对我国所有理工类学生都开设程序设计课程,并且把它作为进一步学习与应用计算机的基础,是必要的和正确的。
2. 要不要学习C语言
进行程序设计,必须用计算机语言作为工具,否则只是纸上谈兵。可供选择的语言很多,各有特点。C语言是基础而实用的语言。 并不是每一种语言都具有此特点的,有的语言实用,但不能作为基础语言(如FORTRAN),有的语言可以作为基础,但实际应用不多(如PASCAL)。C语言功能丰富、表达能力强、使用灵活方便、应用面广、目标程序效率高、可移植性好。既具有高级语言的优点,又具有低级语言的许多特点;既适合于编写系统软件,又能方便地用来编写应用软件。是多年来在国内外使用最广泛的语言。国内外许多专家认为,C语言是最基本的通用语言,有了C的基础后,掌握任何一种语言都不困难。C语言被认为是计算机专业人员的基本功。
有人认为有了C++以后,C语言就过时了,这是一种误解。C++是为设计大型程序应运而生的。将来从事系统开发的人员以及计算机专业学生需要学习C++或其他面向对象的语言。面向对象编程使用的是复杂的类层次结构与对象,适于处理大型的模块程序,但是在某些情况下并不比C程序更为有效。C作为传统的面向过程的程序设计语言,更适合于解决某些小型程序的编程。在编写底层的设备驱动程序和内嵌应用程序时,往往是更好的选择。
对复杂的问题,面向对象方法符合人们的思维方式。对简单的问题,面向过程方法符合人们的思维方式,而面向过程是最基本的。对初学者来说,学习C显然比学习C++容易得多,许多学校把C作为大学生的第一门计算机语言,是比较合适的。有了C的基础,学习C++也是很容易的。目前,如果有些非计算机专业学生学习C++,其作用应当是了解面向对象的程序设计方法,为以后需要时进一步学习打下初步基础,要求不宜太高。
本书选择C语言为学习程序设计使用的语言。
3. 程序设计课程的性质和体系,正确处理算法与语法的关系
关于C程序设计课程的性质,应该说,它既有基础的性质(了解计算机处理问题的方式,学习算法),又有应用和工具的性质(掌握语言工具,具有编程的初步能力,能具体应用),二者兼顾。因此,既要注意讲清概念,使学生建立正确的概念,又要培养学生实际处理问题的能力。
程序设计有4个要素: ①算法——程序的灵魂; ②数据结构——加工的对象; ③语言——编程工具(算法要通过语言来实现); ④合适的程序设计方法。程序设计教学是否成功取决于能否将以上4个要素紧密结合。
本教材自始至终把4方面自然地、有机地结合,全面兼顾。不是孤立地介绍语法,也不是全面系统地介绍算法。本书不是根据语言规则的分类和顺序作为教学和教材的章节和顺序,而是从应用的角度出发,以编程为目的和主线,由浅入深地介绍怎样用C语言处理问题。把算法和语法紧密结合,同步展开,步步深入。精心安排顺序,算法的选择由易而难,细心选择例子,使读者容易学习。在此基础上,构造了新的教学和教材体系。具体的做法是:在每一章中,首先举几个简单的例子,引入新的问题,接着介绍怎样利用C语言去解决简单的问题,然后再循序渐进地介绍较深入的算法和程序。使学生在富有创意、引人入胜的编程中,学会了算法,掌握了语法,掌握了程序设计的思想和方法。把枯燥无味的语法规则变成生动活泼的编程应用。多年的实践表明,这种做法是成功的。
建议教师在讲授时,以程序为中心展开,着重讲清解题思路以及怎样用程序去实现它,不要孤立介绍语法规定,教材中叙述的语法规定可以在介绍编写程序的过程中加以说明,或在作简单介绍后请学生自己阅读,并通过上机实践掌握它。
有人提出在程序设计中要“淡化语言”,对此作者不敢苟同。如果不掌握语法规则的应用,连最简单的程序也编写不出来,或者错误百出。问题不是要不要掌握语言,而是通过什么方法去学习和掌握语言的使用。是枯燥地死记语法规则,还是通过实例去掌握语言的使用?只能提“淡化语法的某些细节”,有些细节不必一一讲授,可以让学生自学自查。
4. 在程序设计课程中注意培养计算思维
近年来,国内外有些专家提出要重视和研究计算思维,认为人类认识世界有3种思维:理论思维(以数学学科为代表)、实证思维(以物理学科为代表)和计算思维(以计算机学科为代表)。认为计算思维是运用计算机科学的基础概念去进行问题求解、系统设计和理解人类行为的思维活动。计算思维的本质是抽象和自动化。
应该说,计算思维问题的提出具有积极的意义。人们在学习和应用过程中,已经认识到:计算机不仅是工具,而且是可以启发人们思考问题的科学方法。通过学习和应用计算机,人们改变了旧的思维方式和工作方式,逐步培养了现代的科学思维方式和工作方式,懂得现代社会处理问题的科学方法。这个意义比掌握工具更为深远。计算思维是信息时代中的每个人都应当具备的一种思维方式。要站在计算思维的高度观察和处理问题,有意识地培养计算思维,让思维具有计算的特征。
计算机不仅为不同专业提供了解决专业问题的有效方法和手段,而且提供了一种独特的处理问题的思维方式。把计算机处理问题的方法和技术用于各有关领域,有助于提升各个领域的科学水平,开拓新的领域。积极在计算机的教学中引入跨学科元素,启迪跨学科计算思维,会对各个学科的发展产生深远的影响。
计算思维不是悬空的抽象概念,是体现在各个环节中的。算法思维就是典型的计算思维。学习程序设计就是培养计算思维的有效途径。大学生在学习过程中,学习了算法,学会了处理问题的科学方法,这就培养了计算思维。
计算思维的培养不是孤立进行的,不是依靠另开专门课程讲授的,而是在学习和应用计算机的过程中培养的。多年来,人们在学习和应用计算机过程中不断学习和培养了计算思维。正如学习了数学培养了理论思维,学习了物理培养了实证思维一样。对计算机的学习和应用越深入,对计算思维的认识也越深刻。当然,今后要从不自觉到自觉地培养计算思维。
培养计算思维不是目的。正如同学习哲学不是目的一样。学哲学的目的是认识世界、改造世界。培养计算思维的目的是更好地应用计算技术,推动社会各领域的发展与提高。要正确处理好培养计算思维与计算机应用的关系。
程序设计的各个环节都体现了计算思维。没有必要去声明或争论:这个问题是计算思维,那个问题属于其他什么思维。属于计算思维的就重视,否则就不重视。这是书生气十足的做法。只要有利于培养大学生科学思维的,都应当大力提倡。大学生需要培养多种思维的能力。
本教材注意在教学过程中努力培养学生的科学思维(包括计算思维)。在介绍每一个问题时,都采取以下步骤:提出问题→解题思路→编写程序→运行结果→程序分析→有关说明。在“解题思路”中,分析问题,介绍算法,建立数学模型。使读者首先把注意力放在处理问题的思路和方法上,而不是放在语法细节上。在确定了算法之后,再使用C语言编写程序,就顺理成章了。在“程序分析”中,再进一步分析程序的思路及其实现方法。这样,思路清晰,逻辑性强,有利于形成科学的思维方法。希望读者不仅要注重学习知识,更要注重学习方法,掌握规律,举一反三,形成思维。
5. 从实际出发,区别对待
学习程序设计的人群中,有的是计算机专业学生,有的是非计算机专业的学生;有的是本科生,有的是专科(高职)学生;有的是重点大学的学生,有的是一般大学的学生。情况各异,要求不同,必须从实际出发,制定出切实可行的教学要求和教学方案,对象不同,要求也应不同,并非越多越深越好。切忌脱离实际的一刀切。
例如,对计算机专业学生,应有较高的要求,作为基本功来要求。尤其是对算法的要求应当高一些,需要较系统学习各种算法,不仅会用现成的算法,还应当会设计一般的算法:熟练掌握语言工具;了解软件开发的方法和规范;掌握程序设计的全过程;具有一定的编程实践经验;能够举一反三掌握几种计算机语言。最好能在学完本课程后独立完成一个有一定规模的程序。
对一般大学非计算机专业的学生,多数人将来工作中不一定要求用C编程,本课程的目的不是培养熟练的程序员。学习程序设计的目的是学习计算机处理问题的方法,具有一定的编程知识和应用能力。对非计算机专业的学生,对算法的要求不能太高。算法选择典型的、难度不太大的。只要求掌握基本的算法和设计算法的思路,为以后进一步学习和应用打下初步的基础。没有必要把语言的每一个细节都学透,而是围绕程序设计,使用语言工具中基本的、常用的部分。对初学者不常用的部分可暂时不学。有些部分概念很重要,但难度较大,初学时用得不多,但以后会用到,可作简单介绍,打下基础。在非计算机专业中不要提“学深学透”的要求。要求是相对的,一切以条件为转移。
对高职学生应不同于本科生,更不应搬用重点大学的做法,不宜在算法上要求太高,因为高职不是培养设计算法的人才的,而应培养切实掌握语言工具,具有较强的动手和实践能力,例如编码能力、调试能力。
对基础较好、学生程度较高的学校,可以采取少讲多练,强调自学,有的内容课堂上可以不讲或少讲,指定学生自学。引导学生通过自学和实践掌握知识,尽可能完成一些难度较高的习题。
全国各校的情况不同,学生的基础和学习要求也不尽相同,不可能都采用同一本教材。教材应当服务于教学,满足多层次多样化的要求。许多学校的老师认为《C程序设计》是一本经过长期教学实践检验的优秀教材,其内容与风格已为广大师生所熟悉,希望在《C程序设计》的基础上组织不同层次的教材,供不同对象选用。作者与清华大学出版社决定出版C程序设计的系列教材,目前已出版的有以下3种:
(1) 《C程序设计(第四版)》。该书系统全面,内容深入,讲授详尽,包含了许多其他教材中没有的内容,尤其是针对编程实践中容易出现的问题作了提醒和分析,是学习C语言程序设计的理想教材。适合于程度较高、基础较好的学校和读者使用。
(2) 《C程序设计教程(第2版)》,即本书。2007年出版了《C程序设计教程》的第一版。它是在《C程序设计(第四版)》的基础上改编的,适当减少内容,突出重点,紧扣最基本的要求,适合学时较少的学校使用。该书出版后被教育部评选为“普通高等教育国家级规划教材”,推荐给各校使用。这次对它进行了修订,出版了第二版。
(3) 《C语言程序设计(第2版)》。内容更加精练,要求适当降低,写法上更加通俗易懂,适合于应用型大学和程度较好的高职院校使用。该书亦已被用作“普通高等教育国家级规划教材” 和国家级精品教材。
6. 本次修订的内容
任何工作都要与时俱进,不断完善,追求完美。在本次修订中保持了第一版概念清晰、通俗易懂的特点,并在以下几个方面作了修订。
(1) 按照C99标准进行介绍,以适应C语言的发展,使编写程序更加规范。目前国内许多介绍C语言的教材是按照C89标准介绍的,而国外的同类教材已改为以C99为蓝本。本书按照C99的规定进行介绍,程序符合C99的要求。例如:
① 数据类型介绍中,增加了C99扩充的双长整型(long long int)、复数浮点型(float_complex,double_complex,long long _complex)、布尔型(bool)等,使读者有所了解。
② 根据C99的建议,main函数的类型一律指定为int型,并在函数的末尾加返回语句“return 0;”。
③ C99增加了注释行的新形式——以双斜线“//”开始的内容作为注释行,这本来是C++的注释行形式,现在C99把它扩充进来了,使编程更加方便。同时保留了原来的“/ …… /”形式,以使原来按C89标准编写的程序不加修改仍可使用。本书采用C99的注释新形式,读者使用更方便,而且符合发展需要。因此,本书的程序基本上采用下面的形式:return 0; //如函数正常执行,返回整数0}④ C99增加的其他一些具体内容,会在书中有关章节中专门注明,以提醒读者。
由于C99是在C89的基础上增加或扩充一些功能而成的,因此C89和C99基本上是兼容的。过去用C89编写的程序在C99环境下仍然可以运行。C99所增加的许多新的功能和规则,是在编制比较复杂的程序时为方便使用和提高效率而用的,在初学时可以不涉及,因此本书对目前暂时用不到的内容不作介绍,以免读者分心,增加学习难度。在将来进行深入编程时再逐步了解和学习。
(2) 加强算法,强化解题思路。在各章中由浅入深地结合例题介绍各种典型的算法。对穷举、递推、迭代、递归、排序(包括比较交换法、选择法、起泡法)、矩阵运算、字符处理应用等算法作了详尽的介绍,对难度较大的链表处理算法的思路作了清晰说明。使读者逐步建立算法思维。
介绍例题时,在给出问题后,先是进行问题分析,探讨解题思路,构造算法,然后才根据算法编写程序,而不是先列出程序再解释程序,从中了解算法。这样做,更符合读者认知规律,更容易理解算法,有利于培养计算思维。引导读者在拿到题目后,先考虑算法再编程,而不是坐下来就写程序。培养好的习惯。
(3) 更加通俗易懂,容易学习。作者充分考虑到广大初学者的情况,精心设计体系,适当降低门槛,便于读者入门。尽量少用深奥难懂的专业术语,用通俗易懂的方法和语言阐述清楚复杂的概念,使复杂的问题简单化。没有学过计算机原理和高等数学的读者完全可以掌握本书的内容。
本书采用作者提出的“提出问题→解决问题→归纳分析”的新的教学三部曲,先具体后抽象,先实际后理论,先个别后一般,而不是先抽象后具体,先理论后实际,先一般后个别。实践证明这样做符合读者的认知规律,读者很容易理解。
在介绍每个例题时,都采取以下的步骤: 给出问题→解题思路→编写程序→运行结果→程序分析→有关说明,对一些典型的算法,还有算法分析,使读者更好理解。
把算法与语言二者紧密而自然地结合,而且通过运行程序,看到结果,便于验证算法的正确性。学习时不会觉得抽象,而会觉得算法具体有趣,看得见,摸得着。
本书便于自学。具有高中以上文化水平的人,即使没有教师讲解,也能基本上掌握本书的内容。这样,就有可能做到:教师少讲,提倡自学,上机实践。
(4) 重新组织内容。本书的对象是一般大学的非计算机专业学生,要求应适当。根据近年来各校教学中的实际情况,对本书内容作了以下调整:
① 考虑到绝大多数读者在学习本课程之前未学习过其他计算机语言,缺乏对计算机语言和程序的基本了解,把第一版的第1章“C语言概述”改为“程序设计和C语言”,在这一章中增加了计算机语言和程序的基本知识。
② 取消《C程序设计教程》第一版中的第2章“数据类型、运算符与表达式”。这章内容牵涉到数据在计算机内存中的存储形式,读者感到一开始就接触这些内容比较难学。在第二版中,对这些内容进行精简,不再单独列章,将其中最基本的、必须了解的内容结合在第2章“最简单的C程序设计”中介绍。这样可以降低学习难度,并使读者更早地直接进入程序设计,能提高读者的兴趣。
③ 简化输入输出格式。C语言的输入输出格式比较烦琐复杂,初学者往往感到难以掌握。本次修订时,只介绍最基本的格式(%d,%f,%e,%c,%s),能够进行输入输出就行,其他附表供查用。
④ 在函数一章中,简化一些初学者不常用的内容,如“内部函数和外部函数”,对存储类别的介绍也从简。
⑤ 指针很重要,把重点放在最基本的内容上,主要介绍一级指针。关于二级指针只介绍有关二维数组的内容。对“指向函数的指针”、“返回指针值的函数”、“指针数组和多重指针”、“动态内存分配与指向它的指针变量”等较深入而初学者用得不多的内容不再介绍。
⑥ 只介绍结构体,不介绍共用体。
⑦ 链表处理(链表的建立、插入、删除、输出等)的内容,对于非计算机专业学生来说难度较大,且不必要,因此精简了。只对链表做很简单的介绍,有一定了解即可。
⑧ 文件只作简单介绍,有初步概念即可。
⑨ 由于许多学校把C语言的教学安排在一年级,而学生还未学完高等数学,在本书不包括有关高等数学知识的例题。考虑到有部分读者在学习高等数学后可能对这方面的内容感兴趣,在习题部分列出有关的题目(如用二分法和牛顿迭代法求一元方程的根),并在《C程序设计教程(第2版)学习辅导》中给出介绍和程序,可供自学参考。
⑩ 在章节编排上,作了适当的改变,在叙述概念和解释难点时,采取了更加通俗易懂的方法,使读者更易于理解。
相信经过修改后,本书会更加容易学习,读者的基本功会更扎实,效果会更好。
(5) 为了帮助读者学习本书,作者还编了一本《C程序设计教程(第2版)学习辅导》,提供本书中各章习题的参考答案以及上机实践指导。该书由清华大学出版社于2013年出版。
7. 作者的心中永远要装着读者
作者从1978年开始从事计算机基础教育和计算机普及工作,35年来一直奋斗在这个平凡而重要的岗位上,把自己的后半生贡献给了我国的计算机教育和计算机普及事业,对这个事业有着深厚的感情和深切的体会。我最大的愿望是“把计算机从少数计算机专家手中解放出来,成为广大群众手中的工具”,使广大群众轻松愉快、兴趣盎然地进入计算机的天地。经过30多年的努力,这个愿望正在逐步变成现实。我的心中经常浮现出千万读者殷切期望的目光。
我始终认为,作者心中要永远装着读者,处处为读者着想,和读者将心比心,善于换位思考。我在编写教材时,常常反问自己:“读者读到这里时会提出什么问题?”“怎样讲才能使读者更容易明白?”我常常用这样一句话来鞭策自己:“只有明白不明白的人为什么不明白的人才是明白人。” 写书不仅是简单地把有关的技术内容告诉读者,而且要考虑怎样写才能使读者容易理解。我写书,有一半的时间用来研究和处理技术方面的问题,还有一半时间用来考虑怎样讲才能使学生易于理解。有时为了找到一个好的例子或一个通俗的比喻,往往苦苦思索好几天,每一句话都要反复斟酌推敲。要善于把复杂问题简单化,而不能把简单问题复杂化。写一本书容易,写一本好书不容易,能讲一堂课很容易,要讲好一堂课并不容易,需要下很大的功夫。
这就要求我们(作者和老师)要深入了解自己工作的对象,有的放矢,准确定位;要根据应用的需要,合理取舍,精选内容;要认真研究学习者的认识规律,采用他们容易理解的方法,深入浅出,通俗易懂。清华大学一位已故的院士说得好“什么叫水平高?只有能用通俗易懂的方法和语言阐述清楚复杂概念的人,才是水平高。那些把概念搬来搬去的人,不能算水平高”。
多年来,在广大师生的关心和支持下,我努力去做了,取得一些成绩。有人称我是计算机界的“平民作家”。我乐于接受并很珍惜群众送给我的这一称谓,这是对我的莫大鞭策。希望所有的教师和作者共同努力,把每一本书、每一门课程都做成精品,得到千万学生和读者的肯定和赞扬,这才是对我们辛劳的最高奖赏。
薜淑斌高级工程师和谭亦峰工程师参加了本书的策划、调研、收集资料、研讨以及编写部分程序的工作。
由于作者水平有限,本书肯定会有不少缺点和不足,热切期望得到专家和读者的批评和指正。
谭浩强谨识 2013年3月于清华园