C特色知识点的教学方法探索与实践
2011-01-24王岳斌
李 毅 , 廖 军, 王岳斌
(湖南理工学院 计算机学院, 湖南 岳阳 414006)
引言
非计算机专业的计算机公共课教学随着社会的需求发展, 由早期的普及WPS、五笔字型等计算机基本技能为主上升到当前以熟练掌握计算机应用技术为主的一个全新高度[1,2]. 从而许多高校将程序设计课程作为非计算机专业的核心公共基础课程. 该课程的知识技能对于非计算机专业学生运用计算机解决今后的专业领域问题有着重要作用. 然而, 由于C语言具有低级语言的特点, 又容忍非常灵活的表达方式[3].对于学生来说, 这无疑增加了学习该种语言的难度. 如何在有限的教学时数内让学生学会C语言并把握该语言的精髓, 无疑只能从教学方法中寻找出路. 个人认为, 找出C语言的特色知识点, 并与专业、学习兴趣结合起来, 能起到事半功倍的效果. 因此, 本文结合笔者对本校数学与应用数学、信息与计算科学专业学生近三年的教学实践与体会, 总结出了若干特色知识点的教学方法, 望能抛砖引玉, 并对其它专业的C程序设计教学起到一点参考促进作用.
1 特色知识点
1.1 关键字学习: 记单词
关键字是程序设计语言的一个普遍特色, 也是一个基本要求. 而进入C语言学习的第一道坎就是学生不知道关键字为何物, 有何用, 面对32个关键字无从下手. 本人在教学过程中采用记单词的形式引导学生理解. 由于上此课程的学生都是一年级学生, 都有英语过四、六级的要求和愿望, 因此将关键字的学习与英语单词学习相联系, 掌握32个关键字的用法也就相当于掌握了C语言的一些基本要求, 这样学生对在程序设计课中学英语单词感到好奇又有趣, 这样既活跃了课堂气氛, 又加深了理解.
在关键字中依据教学需要可先讲解int(单词: integer)、float/double、char(单词: character)等三种基本的数据类型. 数学与应用数学、信息与计算科学专业(以下称“两专业”)的学生因其数学基础好, 对数学相关的问题理解能力相比其它专业来说要强很多, 所以在讲解数学相关的知识点时, 能比较快的接受新知识.但也对比方整型中有: 短整型(short)、整型(int)、长整型(long int)、无符号短整型(unsigned short)、无符号整型(unsigned int)、无符号长整型(unsigned long)等多种划分不理解, 这就要求教学时能根据不同知识点、不同专业的学生设计不同的教学方法. 本人对这三种数据类型的教学都采用如下三步:
1)记关键字, 了解该数据类型表示的基本要求;
2)掌握该数据类型的表示范围. 从存储字节数入手分析, 解决学生对取值范围划分的疑问;
3)特例(特殊情况). 如整型中的十进制数、八进制数、十六进制数的表示, 实型中的科学记数法, 字符型中的转义字符等.
在讲解整型数据的表示范围时, 学生对存储字节、十进制数和二进制数的互相转换等相关知识点理解掌握不到位. 可设计一些有趣味并容易掌握的方法进行讲解, 如学生用短除法进行十进制数转换时基本都会, 但出错很多, 作者依据其原理采用如下方法(见表1).
表1 制数转换简略表
如表1, 用要转换的十进制数(如221)减去能减的最大数(128), 所得余数重复前一步, 并在已经减去的数下标1, 未减的数下标0, 最后可得到表2的结果. 从而得到(221)10=(11011101)2. 同理, 将二进制数转换为十进制数时, 只需将二进制数右对齐、按位对齐写入表中取值位, 然后再将有1的对应位相加, 即可得到对应的十进制数. 这样就可以通过转换运算, 而理解这几种类型的取值范围.
通过对部分关键字的讲解, 便可使学生清楚地区分关键字、标识符及C语言字符集等相关概念. 这样学生学习C语言时很容易迈过入门的坎.
表2 十进制数221转换表
1.2 表达式、运算符、结合性、优先级
C语言是一种表达式语言[4], 其任何语句都可以被当作是表达式语句, 而C中表达式的灵活性又是其特色之一. 从而, 熟练掌握各类表达式的正确求值规则和顺序, 且能准确地确定表达式的最终值, 是保证所设计的程序能正确实现预期结果的前提[1], 也是基础. 与求解表达式密切相关的是运算符及其结合性.C语言的运算符虽然非常丰富, 对所教两个专业的学生而言, 理解与掌握运算符不难, 但对运算符结合性的掌握有难度. 可采用实例教学法, 对特殊的运算符(如右结合性的运算符)进行实例讲解.
举例来说, 如: 设x、a、b、c 的值分别为4、3、2、1, 求if(x=a>b?a+++b:b>c?b:c ). 求解时常见的错误: 认为只要x目前的值与右边a>b?a+++b:b>c?b:c的值相等则条件为“真”. 在C中此括号中部分被称为赋值表达式, 既然是表达式, 它就有一个值, 于是就应该弄清楚它的值是按什么规则来确定的. 在此可先按运算符的优先级推定先作自增运算、再作条件运算、最后作赋值运算, 那么正确判定 if 语句的条件是否为“真”, 取决于x 的最终所赋值是否为非零, 而与x的原值没有关系. 此时如果能牢牢地意识到这里的条件是括号中的赋值表达式的话, 则问题简单多了. 运算符的结合性对单目算符和多目算符有不同的作用. 对于单目算符而言, 在某些情况下它决定该算符应该与左边或右边的数结合, 如果运算符的结合性是从右至左(即为右结合性), 则单目算符应该与其左边的数结合, 反之亦然. “a+++b”的值是 5 而不是 6.“+++”中一定是有一个单目算符“++”和一个双目算符“+”(不是“正”是“加”), 由于单目算符“++”是具有右结合性的, 所以 “++” 应该是与其左边的数结合, 故 a+++b相当于(a++)+b(此处括号可省略), 而不是a+(++b). 表达式(a++)+b的值是a的原值3加b的原值2, 而表达式a+(++b)的值是a的原值3加b的终值3. 对于双目或三目算符而言, 当连续有两个以上的多目算符出现在表达式中时, 结合性决定着哪边的运算符应该先运算. 如上例中求包含两个连续出现三目条件算符的表达式值 a>b?a+++b:b>c?b:c, 由于三目条件算符(?:)的结合性是从右至左的(右结合性), 所以是先计算右边部分的条件表达式 b>c?b:c, 结果为 2,然后再计算左边的条件表达式a>b?5:2, 最终结果为5(取a+++b的值). 则if(x=a>b?a+++b:b>c?b:c )变成if(x=5), 问题得解.
由此可见, 表达式在C中是非常重要的, 一开始就要使学生树立起牢固的表达式意识. 只有把握了运算符的结合性、优先级, 才能正确确定一个表达式的值. C中的大多数算符都是左结合的, 从其优先级表中可知, 只有第2、13、14级是右结合性. 如: 自增、自减、条件算符、赋值等是少数几个为右结合性的运算符.
1.3 此函数非彼函数
C语言程序是由函数构成. 其从main()函数开始, main()函数中结束, 在main()内引用其它的函数来辅助实现相关功能, 进而满足程序设计的需要. 函数也是C语言的一大特色. 两专业的学生因其数学基础好,对数学中的函数有深入的理解, 而C语言中的函数与数学中的函数又有差异, 此函数非彼函数, 所以难以转变思维方式, 也就难以掌握C中与函数的相关知识点. 在教学中总结出“四对应, 一单向”法则, 即实在参数与形式参数中: 数据类型要对应、位置要对应、个数要对应、函数的返回值与函数的数据类型要对应;实在参数到形式参数是单向值传送. 如下函数:
则在调用 function()函数时, 如 int b;b=function(10,’A’,6.0), 三个实在参数“10,’A’,6.0”与三个形式参数“int i,char c,double x”在数据类型、参数个数、位置上都是一一对应的, 其返回值的数据类型(a为int)与函数的数据类型(int)对应, 即四个对应.
两专业的学生在理解“实在参数到形式参数是单向值传送”时受数学上的函数知识的影响而存在偏差,总认为参数就是变量, 有几个参数就有几个变量, 就可返回几个值, 而且值都可存储在变量中. 在教学上可引导学生理解定义的函数中的形式参数只是一个符号, 如果没有换成实际的值, 那么函数本身就没有实际的应用价值. 而在调用时传的实在参数, 则是给形式参数赋值, 相当于赋值语句, 而赋值是一个单向的运算, 则可以知道实在参数到形式参数是单向值传送.
1.4 C最大特色——指针
C中特色最鲜明的数据类型就是指针, 也是公认的一个难点[6]. 依据全国计算机等级考试大纲的要求,指针部分需要掌握: 与指针相关的运算符、各种类型的指针定义与引用、作函数参数及二级指针等. 从考试大纲及我校教学大纲要求分析, 需从以下三个方面突破.
首先, 理解指针数据类型. 它是一种特殊类型, 是内存单元地址的编号, 不能进行普通的算术运算(如张三家的地址加上李四家的地址是多少, 不能理解), 只能对其所指对象进行运算, 可以理解为地址即编号, 编号即指针. 其运算符&(取地址)与*(取内容), 可理解为一对相反的运算符, 一个指外, 一个指内. 还需要强调指针变量不能随便赋普通的数字值, 而只能赋地址值.
其次, 不同类型的指针指向的对象类型不同, 其对象在内存中的表现不同, 所占的内存单元多少也不相同, 但它们在指针变量的定义形式上非常相似, 很容易混淆. 可在讲授一种新的指针类型时, 都与已学过的相似指针类型进行对比, 找出它们之间的区别, 最后将所有指针类型的定义进行集中对比.
第三, 掌握一维、二维指针. 可将一维指针对应一维数组和字符串, 二维指针对应二维数组进行讲授.而一维数组的指针表示法实际上是利用数组名或指向某个数组元素的指针按数组在内存中顺序存放的规则表示的. 二维数组的表示方法与一维数组的表示法相似, 可将二维数组理解成一个一维数组, 只不过这个一维数组的每个元素又是一个一维数组. 数组名即是首地址, 一维数组名是一维地址, 含义和简单变量指针相同, 其指针作“自增”运算时指向数组的下一个元素. 二维数组名是二维数组中的第一行的行地址,含义与前不同, 作“自增”运算时指向数组的下一行. 例如, 有如下二维数组定义:
int c[5]={2,4,6,8,10}, a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
其一维指针如图1所示, 二维指针示意如图2所示.
图1中, 因数组名即为首地址, 则其它元素的地址可在首地址的基础上加上i, 即c+i, 则第i个元素的值可用*(c+i)表示.
图2中, 因是二维数组, 在维数上的变化, 导致有了行和列的区别,其指针表示法和一维数组不同. 要想得到某个元素的地址, 需先指向行,再指向这行的某一列, 才能得到该元素的地址. 一般地, a+i是指向行号为i 的行指针(二维指针), 加*后的*(a+i)是转化得到的与a+i 地址等值的元素指针(一维指针); 因此由数组名a得到a[i][j]元素的地址表达式为*(a+i)+j; 再由一维地址*(a+i)+j得到该元素值的表达式就是*(*(a+i)+j), 这是a[i][j]值的等价表示. 从而*(a+i)+j可以作为二维数组中求某个元素的地址的通用表达式, 其中的i为第i行, j为第i行的第j列, 与&a[i][j]等价, *(*(a+i)+j)与a[i][j]等价.当j=0时, *(a+i)+j 变为*(a+i), 即为行地址, 可得到第i行的首地址.
由于本课程总学时数少, 为了能在较短的时间内突破这个教学难点、重点, 教师须对学生作适当的引导, 对知识做简明有效的归纳、对比. 在课堂教学中进行随堂实训, 在上课时, 抽出1~2名学生将一个简单题目的程序编写到黑板上, 其他学生写到纸上, 要求在 3~5分钟内完成. 然后让学生自愿改正代码中的错误, 这样不仅可提高学生的编程能力, 还可提高学生调试程序的能力, 同时也活跃了课堂气氛, 提高了教学效果[5]. 在实验教学中采用任务驱动法进行, 设置比课堂教学中相对较深一点的题目, 让学生在实践中学习, 使所学知识技能能够及时得到应用, 并在上机过程中使知识得到及时印证、体会和巩固. 同时又能使学生对没有理解的内容产生再认识的渴望, 进一步激发了学生的兴趣.
图1 一维数组指针表示
图2 二维数组指针表示
2 总结
如何教好C语言程序设计这门课, 还需要广大的C语言教师逐步的探索, 在教学实践中注意观察, 不断总结经验, 要依据不同专业设计不同的教学进度, 对不同的教学对象, 依据教学计划将教学内容进行具体的设计, 以满足学生学习的需要. 笔者依据C特色知识点与专业相关的教学方法, 对两专业的学生进行了三个年级的教学实践与探索, 摸索出一套适合的方法, 让学生在有限的课时内快速掌握C语言, 并使得计算机过级率稳步提高. 尤其是更能激发一些优秀学生学习程序设计的兴趣和创造性, 能更好地培养学生的创新思维.
[1]朱从旭. C++程序设计特色知识点的教学方法[J]. 计算机教育, 2010(8): 108~111
[2]郭 敏, 王四万, 田娅薇, 等. 改革计算机公共课教学的几点思考[J]. 中国现代教育装备, 2005(1)
[3]杨路明. C语言程序设计教程[M]. 北京: 北京邮电大学出版社, 2005
[4]陈莲君, 朱晴婷. 培养能力为主线的C语言程序设计教学研究[J]. 计算机教育, 2011(14): 102~105
[5]刘小燕, 申艳梅. “C语言程序设计”教学方法探析[J]. 计算机教育, 2010(6): 94~96
[6]王丕景. C语言“指针”教学经验谈[J]. 太原理工大学学报(社会科学版), 2001(6): 42~44