宋建萍
【摘 要】C语言语法丰富、结构灵活、功能强大,应用领域较为广泛。但也因为较为抽象,对初学者来说,难以透彻理解和掌握,导致不能达到学以致用的目的。本文以“循环结构程序设计”教学内容为例,选用适合的教学方法,对较为抽象的知识点,采用趣味形象的案例进行导入,易于被学生理解和接受,也调动了学生的学习兴趣;由浅入深,循序渐进,启发和培养学生的计算思维,帮助学生理清编程思路,快速入门和提高,从而有效地提高C语言课堂的教学效率。
【关键词】C语言;循环结构程序设计;案例;计算思维
0 引言
C语言作为一门计算机编程语言,自1978年面世至今,仍非常流行,这源于它“语法简洁、数据类型及运算符丰富、结构表现力好、能面向底层系统开发和上层应用”等诸多优点。因此,不同高校的许多非计算机专业,特别是理工类专业,都把C语言作为一门必修的计算机公共基础课程来开设;在全国计算机等级考试的二级科目中,“C语言程序设计”也是报考人数较多的考试项目。
C语言如此热门,但对于对非计算机专业的学生而言,想学好这门编程语言,也非易事。究其原因,主要源于以下方面:
(1)课程学时压缩,教师的课堂授课容量有限,而课程内容多、难点多,学生仅靠有限学时,难以达到系统学习的目的。
(2)课程中许多内容较为抽象,理解起来有一定难度,教师授课中能否做到形象生动、深入浅出,也会影响学生的学习兴趣和吸收效率。
(3)对语句及程序结构、执行流程缺乏细致理解,对问题的抽象计算思维能力难以形成,从而导致编程解题困难,导致对该门语言的学习流于“皮毛”而无法学以致用。
以上种种原因,都影响着C语言课程的教学效果。在教学中常常出现的现象是:多数学生刚开始学习的时候热情挺高,当遇上“循环”、“数组”、“指针”等一些较为抽象的难点,就像遇到了难以跨越的高门槛,逐渐产生的畏难情绪导致中途放弃,能够以较大的学习热情坚持到课程结束、且掌握及运用情况较好的学生比例并不多。因此,在教师的教学中,将课程的学习特点与学生的认知规律有效结合,调动学生的学习积极性,针对教学中学生普遍认为的难点内容,灵活运用多种教学方法,启发学生的思维,让学生在C语言的学习过程中体会到学习的目标性、求解问题的兴趣感和能解决问题带来的成就感,保持学习的动力和热情,避免“教”与“学”脱节变成两张皮,才能有效地保障C语言课程的教学效果。
1 C语言难点及教法分析,以循环为例
C语言学习过程中,学生的疑难知识点较多,在结构化程序设计部分,“循环结构”相较“顺序结构”和“分支结构”而言,较为抽象,虽然语句简洁,但运用灵活,需要加强理解并进行问题抽象和算法设计思维训练。学生学习的过程中,容易在这一关上卡住。因此,循环结构也被视为学习C语言的第一道门槛。那么,教师作为学生学习的引导者,如何进行知识的导入,才能让“循环”从抽象变为形象,从而更容易被学生理解和接收呢?
(1)欲用循环进行编程,概念理解应先行。
“循环结构”学习之初,“循环”的概念需要温习。生活中常见的循环的例子有很多,比如,每年春夏秋冬四季的轮回、每天的日出日落、大自然中水的循环、早晨我们围着操场转圈跑步,等等。教师着重通过这些例子,引导学生认识到循环的本质,即:循环表达的是一组重复进行的过程;这组过程的重复,往往是有条件、可终止的。用C语言编程来表达一组重复过程的进行,有专门的循环语句,也是针对有条件、能够终止的循环。
(2)语句的理解是运用之本,注重其结构与流程。
循环语句的学习,以“while语句、do-while语句、for语句”这三种基本语句为主。其中,while语句称为“当型”循环,最符合学生的认知规律;do-while语句同while语句相近,但执行流程略有不同;for语句最为灵活而学生应用最易出错。因此在循环语句的教学上,若从while语句的学习和运用开始,引入一些趣味性的编程示例,能够帮助学生快速理解和领会循环语句的基本用法。
例如,经过前面课程内容的学习,学生对输出“Hello,world!”的程序已经非常熟悉,换一种情境,假如一个男孩要向心爱的女孩表白,羞于开口,借程序表达。则对程序语句稍作变换,输出“I love you, girl!”。基础程序如程序1所示。
程序1:
#include
void main()
{
printf(“I love you, girl!\n”);
}
学生已非常清楚程序的输出是“I love you, girl!”。一句表白不足以表达爱慕的心意,因此男孩又对程序1作了修改,如程序2所示。
程序2:
#include
void main()
{
while( 1 )
{
printf(“I love you, girl! \n”);
}
}
仅仅加了while(1)这个部分,程序的输出结果令学生大感意外和惊叹,学生通过此例,感受到了循环语句的强大表现力。由此引出while语句的语法结构,介绍“当型”循环的特点,指出“循环条件”和“循环体”这两个关键组成部分,及语句的执行流程。程序2的输出是无限次的,若要限制输出的次数,则可引入一个控制次数的变量,因此再次修改程序,引入一个能够控制循环次数的变量,变化如程序3所示。
程序3:
#include
void main()
{ int i = 1;
while( i <= 10 )
{
printf(“I love you, girl! \n”);
i = i + 1;
}
}
则程序3的输出得到了有限次的控制。在这个程序中,注意引导学生分析变量i的相关部分:i的起始值设置、i值满足的条件以及i的值是如何变化。i的取值决定着循环能否执行下去,因此它可视为循环的控制变量。
(3)循环过程需抽象,计算思维应强化。
前面例举的编程问题,因为重复执行的过程简单直接,较易被学生认识和接受。但在实际编程问题中,其求解过程能否用循环语句来表达,需要结合问题中数据的处理要求,仔细分析求解过程是否具备可重复计算处理的规律,若有,则可进一步提炼出重复的过程有哪些操作、重复的条件是什么,找出这两个关键的要素,再使用循环语句表达,并结合重复过程前的数据状态给出循环前的初始状态表示。这个问题分析和数据处理的计算过程的抽象,就是对学生的计算思维进行训练和强化运用的过程。
以计算1+2+3+…+100为例,这个问题如何抽象成一组可重复进行的计算过程?若结合学生日常生活中存钱的例子,则抽象过程会变得比较生动有趣、易于理解。假设某学生要攒钱买电脑,制定了一个100天攒钱行动的计划并坚持实施,分析其实施过程:
储钱罐s,初始为空,即s=0;
第1天,往储钱罐中投1元钱,则s中的变化为:0+1=1,即s=s+1;
第2天,往储钱罐中投2元钱,则s中的变化为:1+2=3,即s=s+2;
第3天,往储钱罐中投3元钱,则s中的变化为:3+3=6,即s=s+3;
……
第i天,往储钱罐中投i元钱,则s中的变化为:s=s+i;
……
第100天,往储钱罐中投100元钱,则s中的变化为s=s+100;
第101天,计划完成,收手。砸破储钱罐数钱,则s里的总钱数就是1+2+3+…+100的和,已能买到一部性价比不错的电脑。
分析此实施过程,就是在重复地往储钱罐投钱。试着让学生提炼重复的操作,很显然有:s=s+i;,而i也在变化,是怎么变化的?经过观察,每一天里,i的值都是在前一天i值的基础上增加1,则可表示为:i=i+1;。每一天的过程里,都是这两条:s=s+i; i=i+1;,从而形成重复的过程。重复的条件是什么?根据计划制定和实施的天数是100天,超出100天则停止。因此可根据i的取值来定重复的条件i<=100。则用循环语句可表示为:
while( i <= 100 )
{ s = s + i ; i = i + 1; }
分析s和i的初始状态,可在while循环之前加上:s=0; i=1;。则完整的程序表达,即为程序4。
程序4:
#include
void main()
{ int s = 0, i = 1;
while( i <= 100 )
{
s = s + i; i = i+1;
}
}
1+2+3+…+100的计算过程抽象,是一个颇具代表性的例子。以这类问题的抽象过程为基础,另有如:1~100的偶数和、1+1/2+1/3+…+1/100计算、以及格里高利公式求解圆周率等类似的一些迭加计算的问题,可在此基础上加强分析过程的训练,促使学生建立起数据分析和抽象、及抽象求解过程的计算思维能力,形成对一类问题求解方法的认知,并强化编程表达;然后逐步扩展、加入其他抽象类问题,再进行抽象分析的思维训练并强化编程。抽象思维分析训练和编程强化语言运用双重过程相结合,反复进行,从而加强学生运用循环结构进行程序设计的能力训练。此外,教师结合课堂内容,设计适量的课下编程练习并及时监督和检验学生的学习效果,加强学习方法沟通和交流,也是十分必要的。
(4)循环有终止和中止,需要分清楚。
循环的终止和循环条件相关,若循环条件不成立,则循环终止。而循环的中止,是指循环的循环体正在执行过程中,因其他条件不成立而中途停止。中止分两种情况:一种是停止后不再回来执行循环,用break;,一种是停止当前一次循环后再进行下一次循环,用coninue;。具体运用,也可结合日常生活中的例子进行举例。
例如:班上某同学某学期上课,正常情况下,从1周上到19周,但第8周时因生病请假,第9周继续回来上课,此时就可表达为:
i = 1;
while( i <= 19 )
{
printf( “第%d周,正常上课”, i );
if( i == 8 ) { printf(“第%d周,病假”, i); continue; }
i++;
}
若该同学的病需要长期住院,导致从第8周开始的课全部请假,则需用break;,语句表达为:
i = 1;
while( i <= 19 )
{
printf( “第%d周,正常上课”, i );
if( i >= 8 ) { printf(“第%d周后,长期病假”, i); break; }
i++;
}
简单的示例有助于帮助学生快速理解相关语句的用法,加深对语句功能印象,再结合其他编程实例进一步加强对这些语句的运用,起到融会贯通的效果。
另外,嵌套循环的流程理解对学生来说,也是一个难点。在充分理解了单层循环并能熟练运用的基础上,也可引入贴近生活实际的形象例子,将双重嵌套的循环运用起来,结合实际过程,理解嵌套循环的流程,结合典型的编程问题,将嵌套循环运用于求解过程表达,加强编程应用。
2 小结
在教学过程中,学生的“学”是过程,“学好”是结果,“学好”的标准是什么?对于一门编程语言来讲,则是能理解和掌握语言本身的表达方式和方法,进而能灵活自如地运用这个语言工具来“表情达意”——即求解实际问题,能够表达该问题的具体求解过程。在具体问题的编程上,仅掌握语法的表达是不够的,许多较为抽象的问题,还需运用抽象思维分析和设计问题的求解过程。因此,在教的过程中,针对不同的学习内容,选择适合的教学法,帮助学生化解疑难点,注重从计算思维上对学生进行启发训练,发现和总结问题求解的规律,设计正确有效的求解算法,加强编程实践,才能促使教学相长,让学生真正掌握和运用好这门编程语言。
【参考文献】
[1]谭浩强.C程序设计(第4版)[M].清华大学出版社,2010,6.
[2]刘永春.C语言教学中的难点分析与多种教学方法的应用[J].教育教学论坛, 2012,10.
[3]孙丽君,杨志强,高枚.围绕计算思维培养的程序设计课程改革[J].计算机教育,2013,5.
[4]黎昂,曾力军,李泽军.高校非计算机专业C语言程序设计教学方法探索[J]. 课程教学研究,2012,7.
[责任编辑:杨玉洁]