第五章 循环结构_第1页
第五章 循环结构_第2页
第五章 循环结构_第3页
第五章 循环结构_第4页
第五章 循环结构_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第5章 循环结构,本章学习目标 在程序设计中对a于那些需要重复执行的操作应该采用循环结构完成。利用循环结构处理各类重复操作既简单又方便,循环结构又称重复结构。在C语言中有三种可以构成循环的循环语句,本章将一一进行介绍。通过本章的学习,读者应该掌握以下内容: while语句和用while语句构成的循环结构 do-while语句和用do-while语句构成的循环结构 for 语句和用for语句构成的循环结构 循环结构的嵌套 break和continue语句在循环体中的作用,5.1 while语句和用while语句构成的循环结构,5.1.1 相关知识 循环是一种对同一程序段有规律的重复,被重复执行的

2、部分叫循环体。循环的执行要满足一定的条件(循环条件),循环的终止要达到一定的条件(终止条件)。在程序设计中要注意循环不能永远运行,必须能退出循环。循环结构的特点是:循环体执行与否及其执行次数必须视其类型与条件而定,且必须能在适当的时机退出循环。 C语言提供了while 、do-while、for三种语句实现循环,其中while循环是当型循环,先判断循环条件,再根据条件决定是否执行循环体,执行循环体的最少次数为0。,5.1.2 程序范例 1范例一 程序5-1:求1+2+3+100的值。 这是一个求100个数的累加和问题。加数从1变化到100,可以看到加数是有规律变化的,后一个加数比前一个加数增1

3、,第一个加数为1,最后一个加数为100;因此可以在循环体中使用一个整型变量i,每循环一次使i增1,一直循环到i的值超过100,用这个办法就解决了所需的加数问题;但是要特别注意的是变量i需要有一个正确的初值,这里初值应当设为0。 下一个要解决的是求累加和。设用一个变量sum存放这100个数的和值,可以先求0+1,的和并将其放在sum 中,然后把sum中的数加上2再存放在sum中,依次类推,这和人们的心算过程没有什么区别,sum代表着人们脑中累加的那个和数,不同的是心算过程由人们自己控制。在这里,sum累加的过程要放在循环中,由计算机判断所加的数是否已经超过100,加数则放在变量i中,并在循环过程

4、中每一次增1。 以下就是求累加和的典型算法。,main( ) int i,sum ; i=1; sum=0; /*sum的初值为0*/ while(i=100) /*当i小于或等于100时执行循环体*/ sum=sum+i; i+; /*在循环体中累加一次,i增1*/ printf(sum=%dn,sum); ,程序运行后的输出结果: sum =5050 注意: (1)如果在第一次进入循环时,while后圆括号内表达式的值为0,循环一次也不执行。在本程序中,如果i的初值大于100,将使表达式i100时,循环结束。如果没有i+这条语句,则i的值始终不变,循环将无限进行。,(3)在循环体中,语句的

5、先后位置必须符合逻辑,否则将会影响运算结果,例如,若将上例中的while循环体改写成: while (i=100) i+ ; /*先计算i+,后计算sum的值*/ sum=sum+i; 运行后,将输出: sum=5150 运行的过程中,少加了第一项的值1,而多加了最后一项的值101。,2范例二 程序5-2:用/4=1-1/3+1/5-1/7+1/9 -公式求的近似值,直到最后一项的绝对值小于10-4为止。 本题的基本算法也是求累加和,但比例5-1稍为复杂。与例5-1比较,不同的是: (1)用分母来控制循环次数,若用n存放分母的值,则每累加一次n应当增2,每次累加的数不是整数,而是一个实数,因此

6、n应当定义成float类型。 (2)可以看成隔一项的加数是负数,若用t来表示相加的每一项,因此,每加一项之后,t的符号应当改变,这可用交替乘1和-1来实现。,3)从以上求的公式来看,不能决定n的最终值应该是多少;但可以用最后一项t(1/n)的绝对值小于10-4来作为循环的结束条件。 程序如下: #include math.h /*调用fabs函数时要求包含 math.h文件*/ main( ) int s;,float n, t, pi; t=1.0; /*t中存放每项的值,初值为1 */ pi=0; /* pi中存放所求的的值,初值为0*/ n=1.0; /*n中存放每项分母*/ s=1.0

7、; /*s中存放每项分子,其值按公式在1和-1之间变化*/ while ( fabs(t)=1e-4) pi=pi+t;,n+=2.0; s= -s; /*改变符号*/ t=s/n; pi=pi*4; printf(pi=%fn,pi); 程序执行后输出以下结果: pi=3.141397,5.1.3 知识归纳 1while循环的一般形式 由while语句构成的循环也称“当”循环,while循环的一般形式如下: while (表达式) 循环体 例如: while (i0)printf(*) ; i+ 说明: (1)while是C语言的关键字。 (2)while后一对圆括号中的表达式,可以是C语,

8、言中任意合法的表达式,由它来控制循环体是否执行。 3)在语法上,要求循环体可以是一条简单可执行语句;若循环体内需要多个语句,应该用大括号括起来,组成复合语句。 2while循环的执行过程 (1)计算while后一对圆括号中表达式的值。当值为非零时,执行步骤(2);当值为零时,执行步骤(4)。 (2)执行循环体中语句。 (3)转去执行步骤(1)。 (4)退出while循环。,由以上叙述可知,while后一对圆括号中表达式的值决定了循环体是否执行,因此,进入while循环后,一定要有能使此表达式的值变为0的操作,否则,循环将会无限制地进行下去。 请注意,不要把由if语句构成的选择结构与由while

9、语句构成的循环结构混同起来。若if后条件表达式的值为非零时,其后的if子句只执行一次;而while语句后条件表达式的值为非零时,其后的循环体中的语句将重复执行,而且在设计循环时,通常应在循环体内改变条件表达式中有关变量的值,使条件表达式的值最终变成0,以便能及时退出循环。,5.1.4 实例验证 程序5-3:求输入的某个数是否为素数。若是,输出YES,若不是,输出NO。 素数是指那些大于1,且除了1和它本身以外不能被其他任何数整除的数。如2、3、5、7、11、都是素数;4、6、8、9、则不是素数。 为了判断某数x是否为素数,最简单的方法是用2、3、4、x-1,这些数逐个去除x,看能否除尽,只要能

10、被其中某一个数除尽,x就不是素数;否则,若不能被任何一个数除尽,x就是素数。,实际上只要试除到,就已经可以说明x是否为素数了。这是因为如果小于等于的数都不能除尽x,则大于的数也不可能除尽x。试除到,可以减少循环次数,提高程序的运行效率。 程序代码如下: #include math.h main( ) int i, x, yes, a; printf(Enter integer number : ); scanf (%d,yes=1; i=2; a=(int)sqrt ( (double) x); while( yes ,当x=2时,因i的初值2大于a,while循环根本不执行,yes仍保持为1

11、,输出的素数2;当x2时,进入循环,若x为素数,yes的值不变,仍为1,若x能被2的某个数整除,则x不是素数,使yes的值变为0,并且立即退出循环。退出循环后,if的语句判断yes的值为1时,输出YES,否则输出NO。,3)利用迭代公式再求出一个新的x1值,也就是用新的x0又求出了一个新的平方根值x1,此值将更趋近真正的平方根值。 (4)比较前后两次所求的平方根值x0和x1,若它们之间的误差小于或等于指定的10-5,则认为x1就是a的平方根值,去执行步骤(5);若它们之间的误差大于10-5,则再转去执行步骤(2),即继续循环进行迭代。 (5)输出a的平方根值,程序如下: #include ma

12、th.h main( ) float a, x0,x1 ; printf(Input a : ); scanf(%f,x1=(x0+a/x0)/2; do x0=x1; x1=(x0+a/x0)/2; while(fabs(x0-x1)1e-5); printf(sqrt(%f)=%fn,a,x1); 执行以上程序,给a输入2时,将输出以下结果: sqrt(2.000000)= 1.414214,5.2.3 知识归纳 1do-while语句构成的循环结构 do-while循环结构的形式如下: do 循环体 while(表达式); 例如: do i+; s+=i; while (i10);,说明

13、: (1)do是C语言的关键字,必须和while联合使用。 (2)do-while循环由do开始,至while结束;必须注意的是:while(表达式)后的“;”不可丢,它表示do-while语句的结束。 (3)while后一对圆括号中的表达式可以是C语言中任意合法的表达式,由它控制循环是否执行。 (4)按语法,在do和while之间的循环体只能是一条可执行语句;若循环体内需要多个语句,应该用大括号括起来,组成复合语句。,2do-while循环的执行过程 (1)执行do后面循环体中的语句。 (2)计算while后一对圆括号中表达式的值。当值为非零时,转去执行步骤(1);当值为零时,执行步骤(3)

14、。 (3)退出do-while循环。 由do-while构成的循环与while循环十分相似,它们之间的重要区别是:while循环控制出现在循环体之前,只有当while后面表达式的值为非零时,才可能执行循环体;在do-while构成的循环中,总是先执行一次循环体,然后再求表达式的值,因此,无论表达式的值是零还是非零,循环体至少执行一次。,和while循环一样,在do-while循环体中,一定要有能使while后表达式的值变为0的操作,否则,循环将会无限制地进行下去。,5.2.4 实例验证 程序5-5:从输入的若干个大于零的正整数中选出最大值。用-1结束输入。 在程序的第一个do-while循环中

15、,要求输入一个大于零的数或输入一个-1放入x中,不满足此条件时,循环继续不断要求输入一个数,直到满足条件为止。退出do-while循环后,若x中的数为-1,不进入下面的while循环,程序运行结束。若x中的数不是-1,进入下面的while循环。程序中用变量max存放最大值。在while循环中每给变量x读入一个值,就去,断它是否大于0并且大于max,若是,则用新的x值替换max原来的值,否则什么也不做;如此循环,直到读入结束标志(-1)为止。最后输出所求得的最大数。 程序代码如下: main( ) int x , max , i ; printf(Enter x (-1 to end): );

16、do scanf(%d,while(x0 当输入以下数据时: 46812-95612-1 输出结果如下: max=56,5.3 for语句和用for语句构成的循环结构,5.3.1 相关知识 for语句结构简洁,使用方便,由for语句构成的循环按指定的次数执行循环体,它在循环体中使用一个循环变量,每重复一次后,循环变量的值会自动增加或减少。 5.3.2 程序范例 1范例一 程序5-6:请编写一个程序,计算半径为0.5、1.5、2.5、3.5、4.5、5.5mm时的圆面积。 本例要求计算6个不同半径的圆面积,且半径值的变化是有,规律的,从0.5mm开始按增1mm的规律递增,可直接用半径r作为for

17、循环控制变量,每循环一次使r增1,直到r大于5.5为止。程序代码如下: main( ) float r,s; const float Pi=3.14159; for(r=0.5 ; r6.0 ; r+ ) s=Pi*r*r ; printf(r=%f s=%fn,r ,s); ,程序定义了一个不可变的变量Pi,它的值是3.14159;变量r既用作循环控制变量又是半径的值,它的值同0.5变化到5.5,循环体共执行6次,当r增到6.5时,条件表达式r6.0的值为0,从而退出循环。 for循环的循环体是用花括号括起来的复合语句,其中包含两条语句,通过赋值语句把求出的圆面积值放在变量s中,然后输出r和

18、s的值。 2范例二 程序5-7:求n!,即计算123 n的值。,程序代码如下: main() int i ,s ,n ; /*变量s放置连乘的积*/ s=1; /*注意:s的初值为1*/ printf(Enter n : ); scanf(%d, ,以上程序是连乘算法的典型例题,与累加一样,连乘也是程序设计的基本算法之一。程序中i从1变化到n,每次增1。循环体内的表达式s=s*i用来进行连乘。 在连乘算法中,存放连乘积的变量也必须赋初值,显然初值不能用0。在本例中s的初值为1,当i=1时,进行1*1的运算,给s赋1,当i=2时,将进行1*2的运算,重新给s赋2,当i=3时,将进行2*3的运算,

19、重新给s赋6,依次类推,当i=n时,进行s*n的运算,s中最终将存入1*2*3*n的值。,以上程序执行时,若给n输入5,变量i和s中值的变化如表5-1所示。,5.3.3 知识归纳 1for语句构成的循环结构 for语句构成的循环结构通常称为for循环。for循环的一般形式如下: for(表达式1;表达式2;表达式3)循环体 例如: for(k=0; k10; k+) printf(*); 以上for循环在一行上输出10个“*”号。,for是C语言的关键字,其后的一对圆括号中通常含有三个表达式,各表达式之间用“;”隔开。这三个表达式可以是任意形式的表达式,通常主要用于for循环的控制。紧跟在fo

20、r之后的循环体,在语法上要求是一条语句;若在循环体内需要多条语句,应该用大括号括起来组成复合语句。,2for循环的执行过程 (1)计算“表达式1”。 (2)计算“表达式2”;若其值为非零,转步骤(3);若其值为零,转步骤(5)。 (3)执行一次for循环体。 (4)计算“表达式3”;转向步骤(2)。 (5)结束循环,执行for循环之后的语句。,3有关for语句的说明 (1)for语句中的表达式可以部分或全部省略。但两个“;”不可省略,例如: for( ; ; ) printf(*); 三个表达式均省略,但因缺少条件判断,循环将会无限制地执行,而形成无限循环(通常称为死循环)。 (2)for后括

21、号中的表达式可以是任意有效的C语言表达式。例如: for(sum=0,i=1; i=100; sum=sum+i,i+) 表达式1和表达式3都是一个逗号表达式。,C语言中的for语句书写灵活,功能较强。在for后的一对圆括号中,允许出现各种形式的与循环控制无关的表达式,虽然这在语法上是合法的,但这样会降低程序的可读性。建议初学者在编写程序时,在for后面的一对圆括号内仅含有能对循环进行控制的表达式,其他的操作尽量放在循环体内完成。,5.3.4 实例验证 程序5-8:斐波那契数列的前几项是:1、1、2、3、5、8、13、21、34。编程输出该数列的前13项。每行输出5个数。 由以上给出的数列可以

22、看到,此数列的变化规律是:第一项和第二项为1,从第三项开始,每一项的值是前两项的和;在这里,可以用递推算法来求出斐波那契数列中每项的值。 图5-1中,用变量f1、f2和f3来形象地表示递推过程,给变量f1和f2最初分别置数列,中第一项和第二项的值1和1,进行输出;然后进入循环,执行语句f3=f1+f2;将所得和值存入f3中,这就是数列中的第三项,输出后,把f2的值移入f1中,将f3的值移入f2中,为求数列的下一项作好准备;接着进入下一次循环,通过语句f3=f1+f2求得数列的第四项;不断重复以上步骤,每重复一次就依次求得数列的下一项。因为要求输出数列的前13项,在进入for循环前已输出了第一项

23、和第二项的值,因此for循环只需循环11次。,位置号:1 2 3 4 5 6 7 数列: 1 1 2 3 5 8 13 f1+f2-f3 f1+f2-f3 f1+f2-f3 f1+f2-f3 图5-1 for循环运算过程,按照以上算法可写出如下程序: #include #define N 13 main( ) int i, f1, f2, f3, n; f1=1; f2=1; /*第1、第2项*/ printf(n%d %d ,f1,f2); n=2; /*n统计输出个数*/,for(i=1; i=N-2; i+ ) if(n%5 = 0) printf(n); /*输出5项后换行*/ f3=

24、f1+f2; printf(%d ,f3); n+; f1=f2; f2=f3; 程序执行后输出结果如下: 11235 813213455 89144233,5.4 循环结构的嵌套,5.4.1 相关知识 在一个循环体内又完整地包含了另一个循环,称为循环嵌套。 5.4.2 程序范例 程序5-9:使用双层for循环打印下面的图形(见图5-2)。 * * * 图5-2 打印图形,程序代码如下: main( ) int k, i, j; for(i=0;i=2; i+ ) for(k=1;k=i;k+) printf(); for(j=0;j=3;j+) printf(*); printf(n); ,

25、以上程序由i控制的for循环中内嵌了两个平行的for循环。由k控制的for循环体只有一个语句,用来输出一个空格。由j控制的for循环体也只有一个语句,用来输出一个“*”号。 当i等于0时,由k控制的for循环,因为k的值为1,表达式k=i的值为0,循环体一次也不执行,接着执行由j控制的for循环,连续输出四个“*”号;当i等于1时,由k控制for循环体执行一次,输出一个空格,这就使得接着输出的四个“*”号右移一个字符位置;其他依次类推。,请注意,以上内嵌的第一个for循环的结束条件和循环的控制变量i有关,而第二个for循环结束条件是固定不变的。表5-2中列出了以上双重循环中i,k和j值的变化规

26、律。,5.4.3 知识归纳 前面介绍的三种类型的循环都可以互相嵌套,循环的嵌套可以多层,但每一层循环在逻辑上必须是完整的。 在编写程序时,嵌套循环的书写要采用缩进形式,如例题程序中所示,内循环中的语句应该比外循环中的语句有规律地向右缩进24列,这样的程序层次分明,易于阅读。,5.4.4 实例验证 程序5-10:输入6名学生5门课程的成绩,分别统计出每个学生5门课程的平均成绩。 程序需要用双重循环来处理。外层循环每循环一次输入一名学生的数据并求出该学生的平均分,然后输出该学生的全部数据。循环6次,可处理6名学生的数据。内层循环中读入第i位学生5门课程的成绩,并进行累加。 程序代码如下: #def

27、ine N 6 #define M 5 main( ),int i, j; float g , sum , ave ; for (i=1; i=N; i+ ) /*用i表示序号*/ sum=0; /*sum存放每位学生成绩总和,初值为0*/ /*内循环体执行6次,读入一名学生的五门课程的成绩*/ for(j=1; j=M; j+ ),scanf(%f,/*输出序号和对应的平均分*/ ,以上程序的开始定义了两个符号常量N和M,如果处理的学生人数或课程门数有所改变,只需改变define行中与N和M对应的值而不必改动程序的其他部分。程序中内循环各外循环体都由大括号括起来组成复合语句。注意:sum=0

28、;赋初值语句不能放在外循环外,如: sum=0 ;,for(i=1 ; i=N ; i+ ) . . . 请读者分析这将导致什么结果。 程序执行时按以下形式输入数据:(注意:实型变量可以接受整型数,每行输入的最后按下Enter键),60708090100 65758595100 66768696100 67778797100 68788898100 69798999100 运行结果如下: No.1 ave=80.00 No.2 ave=84.00 No.3 ave=84.80 No.4 ave=85.60 No.5 ave=86.40 No.6 ave=87.20,5.5 break和cont

29、inue语句在循环体中的作用,5.5.1 相关知识 为使循环控制更加灵活,C语言提供了break语句和continue语句,break语句是完全从循环中跳出,continue语句只结束本次循环。 5.5.2 程序范例 程序5-11: main() int i, s ; s=0; for(i=1;i=10;i+) s=s+i;,if ( s 5 ) break; printf(s=%dn,s); 程序的输出结果如下: s=1 s=3 上例中,如果没有break语句,程序将进行10次循环;但当i=3时,s的值为6,if语句 中的表达式s5的值为1,于是执行break语句,跳出for循环,从而提前终

30、止循环。,5.5.3 知识归纳 1break语句 已经介绍过用break语句可以使流程跳出switch语句体。 break语句的使用说明: (1)只能在循环体内和switch语句体使用break语句。 (2)当break出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。当break出现在循环体中,但并不在switch语句体内时,则在执行break后,跳出本层循环体。,2continue语句 continue语句的一般形式为: continue; 其作用是结束本次循环,即跳过本次循环体中余下尚未执行的语句,接着再一次进行循环的条件判定。注意:执行continue语句并没

31、有使整个循环终止。 在while和do-while循环中,continue语句使得流程直接跳到循环控制条件的测试部分,然后决定循环是否继续进行。在for循环中,遇到continue后,跳过循环体中余下的语句,而去对for语句中的“表达式3”求值,然后进行“表达式2”的条件测试,最后根据“表达式2”的值来决定for循环是否执行。在循环体内,不论continue是作为何种语句中的语句成分,都将按上述功能执行,这点与break有所不同。,5.5.4 实例验证 程序5-12: main( ) int k=0, s=0, i ; for (i=1; i5) printf(*i=%d,s=%d,k=%dn

32、,i, s,k); /*1#输出语句*/ continue; ,+s; printf(i=%d,s=%d,k=%dn,i,s,k); /*2#输出语句*/ 运行结果如下: i=1,s=1,k=1 i=2,s=3,k=4 *i=3,s=6,k=4 *i=4,s=10,k=4 *i=5,s=15,k=4,程序运行时,当i为1和2时,并不执行if子句,仅执行k=k+s;和2#输出语句;执行第三次循环时,s的值已是6,这时表达式s5的值为1,因此执行if分支中的1#输出语句和continue语句,并跳过k=k+s;语句和2#输出语句;接着执行for后面括号中的i+,继续执行下一次循环。由输出结果可见,

33、后面三次循环中的k值没有改变。,习 题,一、选择题 5.1 以下程序段的输出结果是 。 A)9B)1C)11D)10 int k, j, s; for( k=2; k6; k+,k+) s=1; for(j=k; j6; j+) s+=j; printf(%dn,s);,5.2 以下程序段的输出结果是 。 A)12B)15C)20D)25 int i, j , m=0; for(i=1; i=15; i+=4) for(j=3; j=19; j+=4) m+; printf(%dn, m);,5.3 以下程序段的输出结果是 。 A)10B)9C)10D)9 9898 8787 76 int n

34、=10; while( n7 ) n-; printf(%dn, n); ,5.4 以下程序段的输出结果是 。 A)1 B)3 0 C)1 -2 D)死循环 int x=3; do printf(%3d, x-=2); while (! (-x) );,5.5 以下程序段的输出结果是 。 A)15 B)14 C)不确定 D)0 main() int i,sum; for (i=1; i6; i+ ) sum+=sum; printf(%dn,sum); ,5.6 以下程序段的输出结果是 。 A)741 B)852 C)963 D)875421 main() int y=10; for( ; y

35、0; y-) if(y%3=0) printf (%d,-y); continue; ,5.7 若x是int型变量,以下程序段的输出结果是 。 A)*3 B)#3C)#3D)*3#4 #4*4*4#5*5 *5#5 for(x=3; x6; x+) printf ( (x%2)?(*%d):(#%dn), x );,5.8 以下程序段的输出结果是 。 A)*#*#*#$ B)#*#*#$ C)*#*#$ D)#*#*$ main() int i; for(i=1; i=5; i+ ) if (i%2) printf(*); else continue; printf(#); printf($n); ,5.9 以下叙述正确的是 。 A)do-while语句构成的循环不能用其他语句构成的循环来代替。 B)do-while语句构成的循环只能用break语句退出。 C)用do-while语句

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论