程起才+周天彤+王军+王洪元+潘操
摘要:从循环结构的特点出发分析连加连积类问题,总结出数列中数据的构造规律,给出该类问题的编程模板,列举实例进一步验证该类问题的编程方法。该教学设计在我校C语言教学中,效果非常明显。
关键词:C语言;程序设计;连加;连积;模板
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)10-0069-03
C语言是目前使用最广泛的高级程序设计语言之一。C语言表达能力强、使用方便灵活,目标程序执行效率高、可移植性好,既可用于编写系统软件,也可用于编写应用软件[1-2]。因此很多高校把C语言作为理工类专业的计算机程序设计的入门语言。C语言包含了三种基本结构:顺序结构、选择结构和循环结构,其中循环结构的程序设计是最难的部分。笔者在讲解时,通常把问题进行分类,如连加和连积类、穷举类、迭代类、图案打印类等等。其中,连加和连积类是最基本的,也是学生必须掌握的基本编程技巧。但是,学生们在听老师讲课的时候基本上能够理解,但是自己动手编程实现时,往往就不能得到正确结果,有的问题甚至无从下手。究其原因,笔者认为主要是学生们没有真正理解循环结构的本质以及连加和连积类问题的特点。本文从循环结构的特点出发,多角度分析连加连积类问题,给出这类问题的编程模板,让读者能够准确快速地编程实现该类问题。
1 连加与连积类问题分析
连加与连积类问题核心是如何通过已知条件去构造数列中第[n]个数[Jn,1≤n]。如果每个数都能构造出来,那么把这个数进行连加和连乘就变得相当简单。已知条件通常是[Jn]的位序[n]以及[Jn]之前的数列[Jk,1≤k 1)[Jn]仅仅与其位序[n]有关,即[Jn=f(n)]。 2)[Jn]仅仅通过前面已经得到的序列[Jk]构造,即[Jn=f(Jk),1≤k 3)[Jn]不仅与其位序[n]有关,而且还与前面已经得到的序列[Jk]有关,[Jn=f(n,Jk)]。 4)[Jn]不能由上述三个式子构造出来,但是[Jn]中的一部分[J'n]却可以,而且[J'n]一旦得到,那么[Jn]也就得到了。 2 连加与连积类问题模板代码设计 当把数列的[Jn]项是如何构造的分析出来之后,接下来就可以设计模板代码了。 首先以连加类问题为例分析编码步骤: 2.1连加类问题模板代码设计步骤 1)定义三个变量[i,j,sum]。其中[i]表示位序,即当前进行累加的数是数列中第几项,[j]表示参加累加的数,[sum]是累加器。根据具体题目,为[i,j,sum]选择合适的数据类型,并对其进行如下初始化:[i=1],[ j=]数列中的首项,[sum=0]。 2)建立循环条件表达式。根据题目,判断循环是基于“次数”已知的循环,还是基于“一直连加,直到某一项满足某个条件就停止”的循环。对于“次数”已知的循环,则其循环条件表达式写成[i≤=次数];对于“一直连加,直到某一项满足某个条件就停止”的循环,则其循环条件表达式写成“[j]满足的条件”。 3)写模板代码。 这段模板代码中,最核心的是“如何构造下一次运算的[j]”。 2.2连积类问题模板代码设计 连积类问题与连加类问题很相似,主要是把连加类问题的步骤(1)的[sum]改成[sum=1],把步骤(3)的[sum+=j]改成[sum*=j]。另外,因为连乘容易导致[sum]值超出int类型范围,所以在连加类问题中定义成int类型的问题,在连乘类问题里,可能要改成double范围。 3 案例验证 为了让读者更好地理解上述方法,本节列举多个实例进行讲解。 例1:求下列数列前10项和。 分析:从题目中可以看出:[Jn=f(n)=Jn-1*10+a];因为是求前10个数之和,即循环次数是已知的,所以循环条件表达式写成[i≤=10]。定义三个整型变量并且初始化[i,j,sum],依据模板代码,本题的代码如下: int i=1,j=2/*数列的首项是2*/,sum=0; [a+aa+…+a…a] 分析:从题目中可以看出:[Jn=fn=Jn-1*10+a];因为是求前n个数之和,即循环次数是已知的,所以循环条件表达式写成[i≤=n]。定义三个整型变量并且初始化[i,j,sum],依据模板代码,本题的代码如下: 对于模板代码中的核心j=j*10+a,读者要清楚=右边的j是当前参加运算的j,即它的位序是i,它与sum+=j的j一样,=左边的j是下一次参加运算的j,即它的位序是i+1。这个式子可以简单表述为后一次的j等于前一次的j乘以10加首项。 例3:求下列数列前n项和。 [s=1+11+2+…+11+2+3+…+n] 分析:从题目中可以看出[Jn]既不是n的函数,也不是[Jk]的函数,但是[Jn]的分母[Jn]=[Jn-1]的分母[Jn-1]+[Jn]的位序n。因为是求前n个数之和,即循环次数是已知的,所以循环条件表达式写成[i≤=n]。定义三个变量并且初始化[i,j,sum],依据模板代码,本题的代码如下: 例4:求[π ]的展开式,直到某一项小于0.0005时停止。 [π2=1+13+1*23*5+…+1*2*…*n3*5*…*(2n+1)]
分析:从通项公式[1*2*…*n3*5*…*(2n+1)]得出,当n=1时,结果是[13],当n=2时,结果是[1*23*5]。即[π2]展开式中,首项1不满足通项公式的规律。所以若数列中首项或者前几项不满足整个数列的规律,可以将这些无规律项事先初始化到累加器里。很明显[Jn=Jn-1*n2n+1],循环次数是未知的,所以循环条件表达式写成[j≥0.0005]。定义三个变量[i,j,sum],并且初始化i=1,j初始化为有规律数列的首项,本题j=1.0/3,sum初始化为无规律项的和,本题sum=1。依据模板代码,本题的代码如下:
例5:求下列数列前n项之积。
[1!*2!*…*n!]
分析:很明显[Jn=Jn-1*n],循环次数是已知的,所以循环条件表达式写成[i≤n]。定义三个变量[i,j,sum],并且初始化i=1,j=1,因为是连乘,所以 sum初始化=1,考虑到阶乘和连乘的结果容易超出整数范围,对j和sum都定义成double类型。依据模板代码,本题的代码如下:
例6:求下列数列前10项和。
[2-4+6-…+2n]
分析:本题与例1很相似,仅仅需要考虑正负号处理。正负号处理通常有两种方式:(1)定义整型变量f,视第一项是正数还是负数将f初始化为f=1,或f=-1,然后把sum+=j改成sum+=f*j,把sum*=j改为sum*=f*j;最后在循环体里加入一条f=-f。(2)若第一项是正数,将sum+=j改为sum+=[-(-1)i*j],sum*=j改为sum*=[-(-1)i*j],若第一项是负数,将sum+=j改为sum+=[(-1)i*j],sum*=j改为sum*=[(-1)i*j]。本题两种解法的代码如表1所示:
4结束语
连加和连积类是最基本的,也是学生必须掌握的基本编程技巧。本文从循环结构的特点出发,多角度分析连加连积类问题,给出这类问题的编程模板,让读者能够准确快速地编程实现该类问题,该方法在我校C语言教学中效果非常明显。
参考文献:
[1]谭浩强.C语言程序设计[M].3版.北京:清华大学出版社,2005.
[2]程起才,王洪元,向艳,等.C语言教学改革与教学心得[J].电脑知识与技术,2011(7):1694-1695.