樊新华 林天亮
关键词:程序设计;案例设计;算法表示;编程风格;程序调试
0 引言
程序设计是非计算机专业大学生必修且实践性强的课程。在程序设计教学中,实践教学具有非常重要的作用,也是掌握编程技能的主要途径。因此,要进一步强化实践教学环节和改革实践教学方法,制订实践教学的标准,增加实践教学比重,在教学中推行基于项目、基于案例的教学等方法[1]。
在实践教学中,根据学生存在的问题,进行了一系列改进实践教学的探索。潘丽丽等使用激发学生学习兴趣、合理安排实验教学内容的教学思路[2]。徐一秋等将PBL教学法应用于程序设计实验教学中,强调以“问题”为中心,以学生自学为主教学改革[3]。刘群等主要应用分层次实验教学、调整教学内容、多样化的实验教学方法、分组实验活动、严格的考核制度和辅助的实验教学等方法[4]。陈婷使用“阶梯式”“案例式”方法进行课堂教学,“项目驱动式”方法进行实践教学,并搭建多种自主学习平台 [5]。
这一系列程序设计实践教学改革,对学生提高实践教学效果,加快掌握知识和技能,提高编程能力起到了一定促进作用。但是在运用所学知识解决实际问题中,通常学生还会遇到分析问题能力差、编程风格不规范、调试程序出现的错误不知如何解决等诸如此类的问题。
1 指导思维
在现实中,学生掌握了程序设计的基本知识,并不能熟练掌握编程。因此在实践教学中,要以贴合实际生活案例、项目开发为目标,对容易忽视的薄弱环节进行刻意训练,主要着眼于下面几个方面:
1) 根据实验的知识点、语法,设计相应案例,其难度呈现阶梯式递增,更利于学生进行训练;
2) 根据所给问题进行分析、设计算法,通过标准的图示或语言工具展示分析的结果;
3) 根据所设计的算法进行编程,一定遵循编程规范的书写风格;
4) 根据程序运行结果,进行相关的分析;对出现的错误分析,学会程序调试的技能。
另外,在实验考核过程中,要求按统一的规范描述每个实验题目算法,并在代码中带有注释,尤其是综合项目的注释及说明文档更必不可少;加强学生测试、调试程序能力的训练。对于高质量圆满完成设计开发型和研究创新型实验的学生可予以适当加分,调动学生参与每个实验的积极性。
2 具体实施方法
计算机程序解决问题的过程:分析问题、设计算法、编写程序、调试运行和检测结果。在实验教学中,依照这个过程对常被忽视的一些重要知识或技能,必须进行刻意训练。
2.1 案例设计
在有限的实验课时掌握更多的知识和技巧,需要精心设计实验题目。根据实验性质和目的,可采用“阶梯式”设计实验题目,实验题目分为基础验证型、设计开发型和研究创新型三个类型,要求熟练掌握基础验证型实验,基本掌握设计开发型实验,鼓励掌握研究创新型实验[4-5]。
在设计实验题目时,结合学生所学的专业,内容具有趣味性、实用性,同时依照阶梯式思路,一步一步地提出相关编程要求,并引导学生独立思考和分析问题。问题前后相互联系,功能进一步完善,以培养学生逻辑思维能力,引导学会如何解决实际问题。
以文献[4]中的“猜数游戏”、文献[6]中的“素数探索”为基础,参考文献[7]的实验案例设计方法,设计“掷骰子游戏”的实验案例,具体内容如下:每个骰子是一个正方体有6面上面标有1、2、3、4、5、6个圆点。掷骰子停止时,骰子朝上的点数就是该骰子的点数。
问题(1) :模拟掷骰子游戏1 000次,编程统计并输出骰子的6个面各自出现的次数。
问题(2) :每次掷两个骰子,计算点数之和。如果所得的和为7、11赢;和为2、3或12那么游戏者输掉;并模拟1000次掷骰子的结果。
问题(3) :每次掷两个骰子,计算点数之和。如果第一次投的点数和为7或11,则游戏者获胜;如果第一次投的点数和为2、3或12,则游戏者输;如果第一次投的点数和为4、5、6、8、9或10,则将这个和作为游戏者获胜需要掷出的点数,继续投骰子,直到赚到该点数时算是游戏者获胜。如果投掷7次仍未赚到该点数,则游戏者输。
问题(4) :每次掷三个骰子,计算点数之和。让用户押大小,并告诉用户押大小的结果,每局游戏结束时,程序询问用户是否再玩一次,如果用户输入的回答不是y或Y,程序会显示胜败的次数然后终止。其中“ 大”的点数范围是[11,18],“ 小”的点数范围是[3,10]。
问题(5) :每次掷三个骰子,计算点数之和。用户押大小,并下注金额和赔率。具体规则如下:
①初始金额为1 000元;
②金额为0时游戏结束;
③默认赔率为1时,也就是说押对了能得相应金额,押错了会输掉相应金额。
这些问题由易到难,符合认知规律。通过此案例可以帮助学生熟练掌握控制语句、函数、数组、随机函数等相关知识,同时能训练灵活应用所学知识解决实际问题的能力,以提高计算思维能力。
遵循软件工程的“高内聚低耦合”原则,让学生进一步明白模块的作用,并在编程实践过程中,通过具体案例体验函数的好处,以掌握划分模块基本技能[8]。要求将一些常见的功能做成函数,形成自己的解题方法,以备在以后开发中可以复用。
在学完课程后,可以设计一些常用的小项目(如通讯录管理、学生成绩管理等),要求学生分组完成,一方面培养学生的分析问题的能力,另一方面培养团队合作能力。
2.2 算法描述
“程序=算法+数据结构”公式,说明算法在程序设计的核心位置。描述算法的方法有自然语言、结构化流程图、伪代码和PAD图等[8-9]。在高中数学和信息技术中,学过用流程图表示解决问题的方法、思路或算法,但学生还不习惯或不能熟练使用流程图工具。
在描述算法时,利用更“有序”的思维去想问题,采用“自顶向下,逐步求精”方法。只要逻辑正确,人们都能看得懂就可以了,一般是由上而下按执行顺序画出来的。
在学习编程过程中,学生经常是看到题目,就直接编写程序并上机调试;写实验报告时,会根据源程序画出流程图,这个过程完全是本末倒置,不利于学生分析问题,也不利于开发效率提高。所以,应要求学生做实验,使用流程图进行分析实验题目,依据流程图编程,在报告中画出相应的流程图。
记住一个道理,会写代码的不一定会流程图,会流程图的一定会写代码。描述算法是编程的一项基本功,务必让学生掌握!
2.3 规范化编程
代码风格不只是一种良好的习惯,同时反映出一个编程人员的素养。在编程过程中,不仅要实现所要求的功能,而且代码必须能让自己或别人读懂、理解。尤其是在实际项目开发中,面临开发周期长、逻辑复杂情况,开发团队一定要保持良好且一致的代码风格,才能最大化地提高开发效率[10-12]。
在实验教学中,通过上网查阅Google、大厂(如:阿里巴巴、华为等)的编程规范,制定简化版的编程规范,让学生遵循编程规范进行编码。通过每次实验循序渐进地编程训练,培养学生养成良好的编程风格,做到标识符要始终保持一致且应有意义、代码的缩进编排、注释的表达应该简洁而准确。
2.3.1 命名
好的标识符命名实际是一件困难的事情。标识符对程序而言并不是“成败攸关”的事,但会影响程序的可读性、可懂性。目前,业界提供四种命名规则:驼峰命名法、匈牙利命名法、帕斯卡命名法和下划线命名法。每种命名规则可对不同类别的标识符进行命名,使编程人员可以一目了然。
在实验教学中,参照业界命名法则,制定一种简化版的命名规则。要求标识符的命名规则要始终保持一致,且尽量能达到“见名思义”“见名知类型”的作用。标识符也应既简短又具有描述性。例如变量名name 比 n 好,student_name 比 s_n 好,name_length 比length_of_persons_name 好。
可以看到遵循良好的命名规则和约定,以增强代码的可读性和可维护性。在实际编程中,应该培养学生养成良好的标识符命名习惯,以提高代码的质量和效率。
2.3.2 缩进
程序代码格式混乱,没有缩进或乱缩进,或空行间隔,严重影响程序的可读性和可维护性。因此,编写代码时要合理使用缩进,使代码清晰易读、层次清楚。同时,还要注重功能块的划分,把不同的功能块之间用一个空行隔开,就更能使程序清楚、整洁。
在遇到有关类、结构、函数或过程以及枚举等复杂程序结构的定义的时候,通常需要将它的内容缩进一层。在 C/C++/C#/Java 语言中,大括号是一个非常明显的标志,凡是遇到大括号,都应该直接联想到缩进,也会减少“{”与“}”不匹配的错误。
在指导实验时,经常会有学生说:这个代码怎么不能编译?通过代码整理,发现有一个函数里少了半个大括号。要求学生正确地做到了缩进,类似这种大括号忘写或者不配套的情况就不可能发生,也便于后期的维护与修改工作。现在的开发工具都支持“自动缩进”,根据用户代码的输入,智能判定应该缩进还是反缩进,替用户完成调整缩进的工作。可以利用此功能,保持代码的缩进,可以避免不必要错误的出现。
2.3.3 注释
现实中,许多程序员不重视注释,也很少有写注释的习惯。注释写起来很痛苦, 但对保证代码可读性至关重要。对于学生更是如此,程序一旦出现问题,要找到问题出错之处必须从头阅读程序,对一个比较大代码更是困难,且费时费力。
注释应该书写规范且有意义的,让代码更有可读性,能有效地帮助自己或别人理清思路、程序逻辑及查看代码。在团队开发工作中,注释是代码的一个重要组成部分,采用标准化的注释尤为重要,便于程序员之间沟通。
按照编程规范的注释类型,对代码中的函数、重要变量、文件、主要功能等方面要求写出相应注释。
在实验教学中,要求学生在代码的合适位置,加上适当的注释。尽量做到先写注释,再写代码,更有利于理清头绪。
注释固然很重要,但最好的代码应当本身就是文档,有意义的类型名和变量名,要远胜过要用注释解释的含糊不清的名字。
2.4 调试训练
调试贯穿于程序的整个开发过程,学会程序调试是每个编程人员必须掌握的一项技能。通过调试,可以发现代码中隐藏的问题或缺陷,使写出的程序更健壮和稳定。在实验过程中,程序运行出现错误,部分学生会顿感茫然,并不会判断错误类型或位置,也不尝试使用调试工具,只是一味举手请老师帮着调试或修改。因此,应该加强学生程序调试能力训练,具体方法如下:
首先,对初学者的易犯的错误进行归类总结,通过实例讲解程序错误的原因及修改方法,包括错误实例、错误描述、错误类型[11,13]。在每次实验中,专门设计错误程序的题目进行针对性的训练;还可以将学生作业、实验过程中的易犯错误,进行一起分享、分析和总结,以免学生再次犯错。
其次,在程序中设置显示语句来显示变量的值,了解程序的动态运行信息,可以查看并比较不同点的信息。这样就可确定出错误位置并改正错误后,就可去掉调试语句。
最后,利用编译器提供的调试工具。单步调试是最基本、最重要的调试手段,主要涉及设置断点、单步跟踪、变量观察等相关技术。通过单步调试技术,运行到断点处查看运行状态,并根据运行状态分析错误,找到错误位置、修改错误。
让学生综合应用这几种方法进行程序调试。另外,为了提高调试程序的效率,将“试错说”理论应用到调试工作中,使用“理性创造错误”方法[14]进行实验教学。
3 结束语
程序设计类课程是大学计算机基础教学的核心课程,也是后续课程的基础。在程序设计教学中,问题分析、算法表示、编程风格、程序调试等是非常重要的内容,但因为不会影响程序运行结果,也是经常被学生忽视的知识点。在实践教学中,对学生这几方面的进行针对性训练,以提高学生分析问题和解决问题的能力,培养良好的编程风格。因此,要达到良好的教学效果,真正培养出有编程能力的学生,实验教学环节一定要得到应有的重视。事实表明,学生养成良好的程序设计的习惯,是学生程序设计素养的要求,对提高学生的分析和解决问题的能力有很大的帮助,同时也对未来职业发展有着重要意义。