对比教学法在程序设计基础课程中的应用实践研究
作者: 易锋 马慧 何怀文 翁佩纯
摘要:针对目前以C语言为基础的程序设计基础教学中存在的问题,以对比教学法为基础,提出基于C语言和Python语言对比的程序设计基础教学新模式。实践证明:该模式不仅有助于提高学生对C语言基本结构、数据类型和控制流程等语法的掌握,增强学生对编程思想、编程技巧的理解,而且有助于学生熟练使用函数、数组、指针等工具进行编程,最终取得良好的教学效果。
关键词:对比教学法;程序设计基础;教学设计
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2022)20-0155-03
1 引言
目前大多数高校计算机类专业将C语言作为入门的编程语言,开设了以C语言为基础的程序设计基础课程,目的是培养学生程序设计能力和编程思维。程序设计基础是计算机类专业核心基础课程,是数据结构与算法和操作系统等专业课的先修课程。因此程序设计基础的教学对计算机类专业来讲极为重要。
采用C语言的程序设计基础,内容全面、抽象,语法规则繁杂;从程序设计基础到高级应用;知识点丰富、重难点多,跨度极大,学生在学习过程中存在较大困难[1]。这不仅导致学生对基本语法知识掌握较差,而且阻碍对学生程序设计能力训练和编程思维的培养。
针对该问题,有教师从教学内容、教学方法、教学实践等多方面阐述了教改方案,并取得了一定效果[2-3]。但是导致基于C语言的程序设计基础课程学习门槛较高的一个重要原因是学生所处的时代与C语言出现的年代之间的软硬件差异;特别是C语言存在许多对内存的精细管理,导致学生很难理解和掌握相关教学内容 [4]。由于缺乏对C语言出现的历史背景的了解,学生学习中很难知其然,更难达到知其所以然的教学效果。
另外一方面,当前计算机内存并没有成为当前流行编程语言首要考虑的问题。许多大学生在初、高中学习过编程课程,比如应用于科学计算的Python语言已经成为许多初高中编程课程的首选语言[5] 。Python支持“对象型”或者“无类型”的数据,也就是按需分配内存。在Python编程中,所有的变量在使用前并不需要显式定义。编程语言上的差异,教学中如果不加引导和辨析,会导致学生在学习C语言的过程中,充满了疑惑和问题。
实际上,通过对比C和Python差异,能突出两种语言的特点。利用两种语言各自优点,更有利于培养学生计算思维、程序设计思想和编程技能。有分析,才能有比较;有比较,才能有鉴别[6]。利用Python语法简单,上手容易的特点辅助引入问题建模、算法设计等程序设计思想和计算思维[7];继而引入C的实现,这样可以更好地帮助学生掌握C的繁杂语法。有鉴于此,本文在程序设计基础上引入对比教学法,并在2021级计算机和软件工程两个专业班级进行了教学实践,结果表明对课程教学质量的提高有较大的促进作用。
2 对比教学模式设计与实践
20世纪80年代,为了能写出让计算机更快运行的程序,C程序员要学会像计算机一样思考,这使得编程需要耗费大量的时间。吉多·范·罗苏姆(Guido van Rossum) 针对该问题,同时结合了Shell编程的优点,发明了Python语言。可以说Python语言的设计之初就是为了解决C语言学习和使用中的缺点,是天然的适合与C语言组合,作为对比教学设计的语言[8]。在C语言程序设计基础教学过程中,注意C语言某些语法知识出现的历史背景,并有意识地引入Python语言的语法作为对比,这样层层递进,逐步深入、分辨异同,可以帮助学生深入掌握C语言中的重点和难点。下面分为以下七个部分对C语言与Python进行对比教学设计。
2.1 面向过程VS面向对象
从程序设计思想角度,可以将高级编程语言分为面向对象和面向过程两类。面向过程是将要解决的问题自顶向下,按解决步骤把问题逐步细分为更小的问题,然后编写相应的函数解决这些步骤对应的问题,C语言是典型的面向过程的语言。面向过程的编程语言特点是速度快,性能高;缺点是对程序员的要求高,不易维护、复用性差、不易扩展,不适合开发操作系统,硬件驱动。
面向对象是对要解决的问题中涉及的对象进行建模,利用对象描述解决问题中涉及属性、行为,有封装、继承、多态的特性。Python是面向对象的语言,以功能而不是步骤对问题进行划分。优点是易维护,复用性好,易扩展;缺点是性能比面向过程语言的程序低,适合桌面应用、网应用等软件开发。
程序设计基础课程伊始,引导学生建立对面向过程和面向对象语言的正确认识,了解两种不同的程序设计思想,通过对比,为后续的面向对象程序设计课程做铺垫,打基础。
2.2 编译型语言VS解释型语言
使用高级编程语言编写的源程序要在计算机上执行,必须转换为二进制指令,称为编译。根据编译的不同,可将高级编程语言分为编译型语言和解释性语言。编译是将源程序编译成可执行的目标程序,编译和运行是分开的;解释是在执行程序的时候对源代码进行编译和执行,编译和运行合二为一。
C语言是典型的编译型语言,其编译过程如图1所示。
没有编译原理基础的大一新生对上面的编译流程理解存在困难。Python是一种典型的解释性语言。教学中可以以输出“hello world”为例,演示C语言和Python语言的区别。C语言程序首先对源程序进行编码,然后经过编译和链接生成目标可执行程序,然后再执行。Python语言可以直接在环境中调用函数进行输出;或者编写源程序后,调用Python命令来执行源程序,不会生成可执行程序。
2.3 静态弱类型语言VS动态强类型语言
C语言出现在20世纪70年代,当时个人电脑典型的内存为几百KB。为了能写出高效运行的程序,C语言程序员需要对内存进行精确管理与使用。这种考虑,导致C语言是一种静态弱类型语言,定义了超过十种的变量类型。在C语言中,变量必须先定义后使用,每种变量类型有取值范围,而且不同数据类型存在相互的隐式转换和显示转换。学生在学习本知识点时,存在非常大的困难。
而Python出现在20世纪90年代,计算机,包括个人电脑的内存已经大大提高。出现了动态类型、内存自动管理、面向对象中垃圾自动回收等内存自动管理技术。因此,Python将数据类型的指定交给解释器来管理,是动态强类型语言。在Python中,变量使用前不需要先定义变量的类型,解释器会根据变量所赋值自动决定变量的类型;而且一般情况下,可以认为整数类型和浮点类型是没有范围限制的。
教学中以Python变量为切入点,引入变量和变量类型。因为Python中基本类型少,结合使用Python的bin()函数,可以使得学生比较容易理解变量类型与变量在内存中存储的关系。此后,引入C语言出现历史背景,引导学生思考,如何在较小内存前提下,更加高效地存储数据,以此过渡到C语言中的数据类型。在讲授过程中可以以不同类型的溢出为例,帮助学生理解C语言基本变量类型、数据类型的范围及相互间转换的原理。
虽然在变量使用方面,Python比C语言更为简单,但在运行速度方面,前者不及后者。课堂中设计了“1+…+1”的实例演示两种语言运行速度方面的差异。在累加百万次的时候,两者差距不明显;但是当累加十亿次后,两者运行的时间差距达到几十倍。这种运行时间的差距是由编译类型和解释类型,以及Python的内存自动管理等因素造成。解此例可以进一步向学生阐述两种语言的特点和不同的应用领域。
2.4 复杂控制结构VS简单控制结构
C和Python包含顺序结构、选择结构和循环结构三种控制结构。
对于选择结构,C用零表示条件为假,非零表示条件为真;Python则提供用于判断真假的Bool类型,也兼容C语言的条件规则;教学中可以使用bool()函数进行测试举例。C使用&&,||,!的抽象符号表示逻辑与、或、非运算,学生难以记忆;而Python使用英文单词AND、OR和NOT表示,两者对应关系如表1所示。通过对比,学生更容易记住C中抽象符号所表达的含义及运算规则。在实现上,C提供了if、switch和?:运算符等条件控制语句;Python只提供了if条件语句。Python之所以可以简化,因为switch和?:运算符均可以由if语句等价实现。教学中,可以引导学生在C中使用if实现switch和?:控制语句。
对于循环结构,C提供while、do-while和for三种循环控制语句;Python提供while和for循环控制语句。通过对比C和Python的流程控制语句的异同,可以使同学更加深入理解不同控制语句之间的关系;了解不同语言在流程控制语句上的借鉴与发展。
2.5 显式函数VS隐式函数
Python中的函数定义和使用相对简单,没有对函数声明、函数返回值的限定要求。教学中以Python中的简单加法例子为切入点,引入函数,介绍函数的定义、实现过程和调用。以Python的例子为基础,引入C语言的函数定义形式。阐述两者的区别和相同点,加深学生对C语言函数定义的掌握。首先C语言的函数需要有返回值类型;其次C语言的函数体,与Python的缩进定义不同的是由一对{}括起来的语句组成。C语言的语句之后均带有分号;以表示语句的结束,Python的每条语句占一行。根据C语言静态弱类型的特点,指出函数声明的作用。两者定义的函数均需要定义函数名,函数名后为一对圆括号;如果有参数,参数要写在圆括号内;均由return语句指定函数的返回值。参数的传递中,对于简单类型,两者都是值传递,也即形参的更改不会修改实参的值。
2.6 数组VS列表
数组是用一个变量名保存多个相同类型的值。在Python中,一般认为没有内置对数组的支持,可以使用元组或列表代替。相比C语言,Python的列表定义和初始化更为简单[9]。
教学中,首先介绍Python中列表的使用,让学生首先熟悉程序设计中数组的使用方法。然后引入C语言的数组,结合C语言的出现历史背景,指出C语言的数组表示内存中一片连续的存储区。C99之前,为了优化对内存的使用,定义数组时必须指定数组类型和大小,在使用过程中数组大小是不可变的;随着技术进步,C99标准规定了可以使用变长数组。通过对比Python数组定义和初始,加深学生对C语言数组定义和初始化规则的理解和记忆。
此外数组作为实参,是传址方式,即实参和形参共用同一个存储空间。在高级编程语言中,为了实现内存的高效使用,对于数组这种复合数据类型的参数传递,传递的是数组的地址值。通过C语言和Python中参数传递的对比,引导学生理解传值和传地址作为参数的时机选择原理。
2.7 字符串VS字符数组
Python提供了存储字符串的类型——String,及丰富的字符串处理函数。Python中的字符串由一对单引号或一对双引号定义。而在C语言中一对单引号定义的是单个字符,一对双引号定义的是字符串。如果在字符串中出现的单引号或双引号字符,Python的定义可以避免其引起的结束歧义;而在C语言,则需要使用转义字符进行转义。在Python中,字符串也是以列表方式存储,其简单的定义和丰富的函数,可以帮助学生快速掌握字符串的定义和使用。
课堂教学中,首先使用Python引入字符串,然后介绍C语言中的字符串的定义和使用,特别要指出C语言使用字符数组对字符串进行存储和表示,且字符数组的末尾为元素0。根据Python提供的字符串处理函数,以及C语言中字符串存储特点,引导学生实现Python字符串不同处理函数的功能。
3 对比教学法效果分析
本文2021年在程序设计基础中引入对比教学法。通过2019、2020和2021级期末考试成绩分布情况,可以考察对比教学的效果。同时利用超星泛雅平台提供的问卷调查工具,设计了调查问卷了解和分析2021级学生对对比教学模式的反馈。