张连堂,林树青
(广州商学院,广州511363)
信息技术飞速发展,计算机语言层出不穷,但是C语言的地位一直无法撼动,它非常接近于机器语言,编译质量、运行效率很高,任何其他高级语言无法比拟,所以不管用其他任何高级语言开发软件,在核心的地方都会想到嫁接C 来“帮忙”。在大部分高等院校计算机相关专业的课程体系中,C 语言的身影一直存在。C语言的教学效果也一直备受关注,为了能使得刚刚踏入大学的学生对C 语言的学习取得更好的收获,我们尝试打破教科书的束缚,采取项目驱动教学法,具体做法如下。
作为大学第一门计算机语言课程,讲授伊始,必须首先让学生理解语言和程序的本质。好比导演引导演员入戏一样,教师必须引导学生尽快进入“计算机语言”。
语言是不同客体之间信息交流的工具。自然语言是人与人之间的交流工具;计算机语言是人和计算机之间的交流工具。一切语言的共性是传递信息,让对方了解自己的意图,不同语言的区别仅在于:单词、语法、句型不同而已。由单词按照一定的语法、句型所写成的文章,用于处理实际问题的具体策略、方法步骤、实现过程等,实则程序,如表1 所示。
表1 自然语言和计算机语言对照表
不难看出,其实计算机语言并没有什么新奇之处,自然语言的文章中每个段落讲述一层意思,计算机语言的程序中每个函数实现一个运算、描述处理一个具体问题的方法步骤;一篇文章完成一个整体问题的描述,一个计算机语言程序完成解决一个工程问题的全部描述。
理解了语言和程序,接下来要让学生学会在程序中如何处理实际问题。
(1)算法:一个程序实现的工程中涉及到很多具体的子工程,不能像写继续文一样全部混合在一起设计,为了纠错、维护(调试)方便,为了参与开发设计人员的分工、合作方便,很自然地把整个工程分解成为若干个具体问题,分而治之,程序员设计出的处理每一个具体问题的方法步骤叫做算法。
在此,要让学生清晰的认识到算法已经不再是一个数学表达式,而是处理实际问题的方法步骤。不同的程序员面对同一个实际问题,所构思的算法可能截然不同,要让学生认识到,日后的学习过程,以及未来工作中对算法的学习研究是非常重要的。
(2)运算:必须向学生阐明,运算已经不再狭义的指加减乘除等,对实际问题的每一步处理或者每一个操作,例如数据输入、输出、修改、插入、删除、排序、查找等,都叫运算。同时,讲授过程中必须澄清“运算”和“算法”的本质不同,运算是对数据的操作,算法是实现运算的方法步骤。
C 语言作为大学计算机相关专业的入门语言,教学实践告诉我们,其重要目的不在于让学生学会用C语言设计一些简单的程序。而是借助于C 语言的学习,教会学生学会编写程序的方法和技巧。让学生明确,所有计算机语言编写程序的方法完全相同,只是语法、标识符存在差异,写程序的策略不同。例如面向过程的程序设计语言和面向对象的程序设计语言。
同时,通过C 语言的教学过程,要教会学生如何触类别通、举一反三,对比C 语言,自己学习其他计算机语言。
实践告诉我们,只要学过一门计算机语言,掌握了计算机的本质和程序设计的方法,其他语言就不必在专门研究。工程上,面对所开发软件的特点,选定恰当的语言,研究该语言的基本功能和特点,即可在计算机上用该语言进行编程,遇到问题,在相关资料上去查解决办法,这样边用边学,很快就能对新的语言运用自如。
为了能真正实现通过C 语言教学,教会学生程序设计的方法,作者建议尝试用项目驱动法组织教学,具体做法是:
紧扣C 语言教学内容,以结构式程序设计方法为框架,设计出几个功能基本齐全、容易实现的模拟项目课题,如《学籍管理》、《图书管理》、《车票订购系统》等。并且写出详尽的“项目指导书”,包括项目的意义、实施方法、过程、目的、最终达到的目标效果等;可划分为项目的需求分析、可行性分析,可操作性强的实施方案、实施日历、项目效果评估等部分。实施方案部分是其重点,应由浅入深、由易到繁,清晰的分解出与C 语言程序设计知识内容体系逐步深入相对应的程序模块。例如可按照功能分解为“输入”、“输出”、“修改”、“插入”、“删除”、“查找”、“排序”等模块。详尽的写出每一个模块所对应的C 语言知识内容,对应用到的程序设计方法,实现技巧等。该“项目指导书”可作为学生们在学习C 语言知识的同时,实验、实践内容的指导性材料。讲授课程之前先让学生分组自主选择“项目指导书”中所列项目中的任一个,形成多个项目开发实践学习小组,伴随C 语言知识的学习,以其作为实践标的设计程序,课程结束,所做项目程序设计完毕,以期达到预期学习效果。
为了让教学内容与项目程序设计的进度同步推进,我们把C 语言的教学内容分解成如下几个部分。
(1)C 语言程序设计的基本知识
基本知识的讲课,绝对不能在语法和规则上浪费时间,要明确的告知学生,绝对不能死记硬背语法规则,不能只在书本上研究计算机语言,要在计算机上边实践边学习,最好的方法是,整个教学过程离开讲台在计算机旁进行。让学生明白:计算机语言不是读书学会的,是在编程实践中练会的,书本知识参考资料,是在编程序过程中备查的,不是用来研学的。只读书、不实践,理论知识倒背如流亦不会写程序,这一点正是目前不少学生学始终学不会编程的根本问题。只有在计算机上的实际编程、调试、纠错、修改、升级等一系列的实战训练。才能真正领悟用计算语言编写程序的方法。才能做到在编程过程中面对实际问题,灵活运用计算机语言,写出相应的处理程序段。
课程伊始,主要概述C 语言的总体内容,以及C 语言的特点、C 语言程序设计的最基本的方法等[1]。同时对照、结合“项目指导书”向学生阐明如何结合C 语言知识的学习过程逐步完成项目的软件开发。
接下来在讲授“顺序结构”、“分支结构”、“循环结构”等基本程序设计方法的过程中,每讲授一部分内容,就让学生以小组为单位对其所选项目由浅入深的进行编程实践。例如,学完当前知识,就可用少量模拟数据实现所选项目中的“输入”、“输出”、“修改”、“插入”、“删除”等简单功能。
(2)数组和字符串
前面的教学和实践,明显发现所处理的数据量极其有限,明确告诉学生,面对大批量数据,设计变量一一对应极不现实,力不从心,继而引入数组的概念,结合循环结构用数组作为数据的宿主,轻松实现批量数据的处理;至此,学生们很快就能把先前所设计的程序扩展为批量数据处理。同时,顺理成章的可让学生设计相应的算法完成对应项目程序中的“查找”、“排序”功能。
这部分内容,要让学生理解数组的本质是顺序存储结构,逻辑上相邻的数据元素(例如学籍表中不同学生同一门课的成绩),在计算机内存储器中的存放位置也是相邻的,先后关系由数组的下标来决定,只要给定一个下标位置,就能很容易的找到对应的数据。优点是查找、输入输出方便,缺点是插入、删除时需要移动数据,安全性差。字符串实质上是元素都是字符的特殊的数组,学生接受很容易,在此不再赘述。
(3)函数
函数是包括C 语言在内所有语言学习的重中之重。结合课题项目,从结构上剖析前面所设计程序的缺点:实现方法简单、不能分解问题、思路不清晰。继而引入,可以用函数的方法,把复杂问题分解成一个个小的具体过程,每一个过程写成一个函数,由主函数统一调度协调,实现结构化程序设计,让后续的维护变得轻松而容易。
函数的讲授重点在于参数的本质意义,及其数据传递方式方法,只有让学生真正掌握“形式参数”、“实在参数”、“数值引用”、“地址引用”等概念[2],才能恰当选用参数、自如的设计函数,让程序中函数间的数据传递有条不紊,最大限度的减少数据冗余、减少程序代码冗余,设计出时间效率和空间效率双优的程序。
任何函数都只有的“数值引用形式参数”、“地址引用形式参数”两类,是函数内部与外部数据传递的接口,在语言的学习中,它显得很抽象,可以用实例形象讲授:一个函数“首部”好比一个公司的“大门”,参数表的变量如同“门卫”人员,公司可设置了两类“门卫”,一类“门卫”等候接受外来的材料(数据),材料可以是外人送来的,也可以是没人送而邮寄来的,“门卫”人员带上外部材料进入公司内参与处理,哇哎不即使有人来业拿不走内部材料,这些数据“有来无回”,这就是参数表中的“数值引用形式参数”;另一类“门卫”不是真正守候在此的“人员”,只是把“工作服”放在那里,等候“外来人员”穿上这些工作服,进入公司内部参与各种活动,最后他们走时自然可以把内部数据带走,数据“有来有回”,这类“门卫”等同于函数的“地址引用形式参数”。这样的比喻可让学生非常轻松的掌握抽象的“参数”概念。
学完函数,鼓励学生彻底修改自己所做的项目程序,把每一个功能模块写成一个独立的函数,让学生自然而然的学会结构化程序设计的方法。
(4)指针、结构体和共同体
在设计程序的过程中,学生们一定非常困惑一个数组中的数据必须是同构的,很难实现对于学籍表、图书信息,等工程实践中的数据。因为,每个数据中的各个成分不是同构的,诸如姓名、编号、日期等等,迫切的想学会解决方法,结构体的学习让学生们眼前一亮。
讲授指针,要让学生清晰的了解,指针变量保存的是存储器的地址,通过记忆地址,能够让逻辑上相邻的数据元素在计算机内存储器中位置任意,数据元素之间的关系由直接先驱数据记忆其直接后继的地址来确定。不仅仅可以克服用数组顺序存储批量数据时,插入、删除运算移动数据,效率低、安全性差的缺陷。同时,通过指针实现的数据动态存储还能自然达到数据加密的效果。
需要强调的是,对于结构体和指针的教授绝对不能轻描淡写,要结合计算机硬件,从物理意义上讲授;结合项目课题从实际意义上讲授,让学生真正掌握其本质,在实践中灵活运用。同时为后继知识的学习打下扎实的理论基础。例如,学不会指针和结构体,诸如数据结构之类课程的教学就寸步难行[3]。
至此,借助于C 语言面向过程的结构化程序设计知识已经基本学完,可综合起来,让学生对自己所设计项目程序中的数据用结构体和指针进行完善定义,逐步改进其功能。
(5)位运算和文件
不少人认为,位运算以及文件都可以省略不讲,我们认为不尽然。对于偏硬的计算机相关专业,文件部分可以省略,但是必须让学生学会位运算,因为用C 语言代替汇编语言对芯片编程时,位运算极其重要。对于偏软的计算机相关专业,位运算可以省略,但是文件不能不讲,例如,我们项目驱动教学法中的程序设计,如果不把数据通过文件保存到外存中,所有处理都是无效的,因为离开文件,所有对数据的处理都是在内存中进行的,程序之行结束,一切数据全部消失,这一点必须向学生明确阐述。
我们建议,文件部分着重讲授二进制文件和文本文件的处理方法,其他可以略去,其一,无论什么性质的文件都是以二进制形式正在外存中保存;其二,很多便于阅读的数据都是以文本文件格式实现的。
基于项目驱动法的特点,学生在学习C 语言程序设计知识的过程中,步步实践,课程结束,项目程序也相继完成。第一,让学生在平时设计程序的过程中,写出每一环节的开发文档,期末以其所设计项目程序的水平和所写开发文档的质量作为考核内容给出恰当的评价,远比闭卷书面考试为主的考核方法更为有效。
项目驱动法组织C 语言教学,变实验为实践,有的放矢,学生们的学习目标明确,每学完一部分语言知识,立即结合项目程序的设计进行应用体验,成就感会使他们受到极大地鼓舞,可最大限度的调动其学习的积极性和主动性,很容易把刚进大学的新生引入程序设计的“趣味天堂”,使他们深深体会到学习程序设计的乐趣和重要性。彻底克服以往C 语言的教学中,讲完理论,做验证性实验,学生学无目的、迷茫,教学效果很不理想。以至于不少学生刚进大学,就因为C 语言的学习混沌,丧失对程序设计的信心。
笔者认为,C 程序设计课程在整个计算机相关专业教学过程中,起着关键性作用。它的成败,很大程度上影响到学生的学业成败,这就叫“成也萧何败也萧何”。这就是我们探究彻底改革其教学方法的目的所在。