《第6章循环结构程序设计.ppt》由会员分享,可在线阅读,更多相关《第6章循环结构程序设计.ppt(35页珍藏版)》请在三一办公上搜索。
1、第6章 循环结构程序设计,循环结构可以完成重复性、规律性的操作.在人们所需处理的运算任务中,常常需要用到循环,例如:1100的累加和等。在语言中有三种循环语句:while、dowhile、for。用goto语句和if语句也能构成循环。6.1 goto语句goto语句 为无条件转向语句。格式:goto;功能:程序执行到goto语句时,转到语句标号指定的语句去执行。,说明:(1)语句标号必须用标识符表示,不能整数作为标号。(2)与if语句一起构成循环结构。例题6.1 求s=1+2+3+100main()int i=1,s=0;loop:if(i=100)/*loop是一个语句标号*/s=s+i;i
2、+;goto loop;printf(“s=%dn”,s);,6.2 for语句,注意:结构化程序设计方法,主张限制使用goto语句。因为滥用goto语句,将会导致程序结构无规律、可读性差。6.2 for语句1for语句的一般格式 for(变量赋初值;循环继续条件;循环变量增值)循环体语句组;,2for语句的执行过程,(1)求解“变量赋初值”表达式。(2)求解“循环继续条件”表达式。如果其值非0,执(3);否则,转至(5)。(3)执行循环体语句组,(4)求解“循环变量增值”表达式,然后转向(2)。(5)执行for语句的下一条语句。例如:for(n=1;n=20;n+)s=s+n;,for语句执
3、行过程图,3说明,(1)“变量赋初值”、“循环继续条件”和“循环变量增值”部分均可缺省,甚至全部缺省,但其间的分号不能省略。i=1;for(;i=100;i+)s=s+i;for中缺省变量赋初值,但是在for前面要有i=1;for(i=1;i+)s=s+i;for中缺省“循环继续条件”,相当于条件永远为真,无限循环。for(;)语句;全部缺省即不设初值,不判断条件,循环变量不增值。无终止地执行循环体。,3说明,(2)当循环体语句组仅由一条语句构成时,可以不使用 号括,但是当循环体语句组由多条语句构成时必须用 号括起来。(3)“循环变量赋初值”表达式,既可以是给循环变量赋初值的赋值表达式,也可以
4、是与此无关的其它表达式(如逗号表达式)。例如:for(sum=0,i=1;i=100;i+)sum+=i;(4)“循环继续条件”部分是一个逻辑量,除一般的关系表达式(如 n=20)或逻辑表达式(ab&xy)外,也允许是数值(或字符)表达式,只要其值为非0(真),就执行循环体。,3说明,例如:for(n=0;(c=getchar()!=n;n+=c);在循环继续条件中先从键盘接收一个字符给c,然后判断值是否不等于n(换行符),如果不等于,就执行循环体,此语句最后有“;”说明循环体为空语句,所以执行n+=c即把字符的ASCII码累加存入n变量。此语句的作用是:不断输入字符,将它们的码相加,直到输入
5、一个“换行”符为止,例题,例题6.2 求1100的累计和。/*程序功能:求1100的累计和*/main()int i,sum=0;/*将累加器sum初始化为0*/for(i=1;i=100;i+)sum+=i;/*实现累加*/printf(sum=%dn,sum);,程序运行情况如下:sum=5050,例题,例题6.3 求t=1*2*3*4*5*nmain()int n,i;double t=1.0;/*所求累乘值很大,所以用double型且初始化为1*/printf(“input n:”);scanf(“%d”,/*用指数形式输出双精度类型的t变量的值*/,运行结果:input n:5t=1
6、.200000e+02 此程序t 放的是n!,当n较大时阶乘数会很大,所以定义为double型。,例题,例6.4 求s=1+1/2+1/3+1/nmain()int i,n;float s=1;printf(“input n:”);scanf(“%d”,此程序注意求1/2、1/3时,如果两个操作数都是int型,完成的是整除得0,则最后s的是1,这是错误的。应使除数和被除数其中有一个为实型才可以,如:s=s+1.0/i;或i定义为float,则 s=s+1/i。,运行结果:input n:4s=2.083333,6.3 while语句,(1)一般格式 while(循环继续条件)循环体语句组;(2
7、)执行过程,例题,例题6.5用while语句求1100的累计和。main()int i=1,sum=0;/*初始化循环控制变量i和累计器sum*/while(i=100)sum+=i;/*实现累加*/i+;/*循环控制变量i增1*/printf(“sum=%dn”,sum);,此程序while 语句的循环体有两个语句sum+=i;i+;所以要用 号括起来以复合语句形式出现。,程序运行情况如下:sum=5050,6.4 do while 语句,1一般格式 do 循环体语句组;while(循环继续条件);/*本行的分号不能缺省*/,例题,例题6.6 用do-while语句求解1100的累计和。ma
8、in()int i=1,sum=0;/*定义并初始化循环控制变量i,以及累计器sum*/do sum+=i;/*累加*/i+;while(i=100);/*循环继续条件:i=100*/printf(“sum=%dn”,sum);,程序运行情况如下:sum=5050,例题,例题6.7统计从键盘上输入整数的个数(输入0时结束,0不计在内)main()int n,x=0;do scanf(“%d”,运行结果及分析,运行情况:2 4 6 34 0 x=4此程序用do while语句一开始不做判断进入循环,用scanf()输入整数,输入一个整数,x加一次1,然后判断是否输入的是表示结束的0,一直重复直到
9、输入0停止循环。由于do while语句是后判断循环继续条件,最后输入的0也计算在个数内,所以输出时,要输出x-1的值。,例题,例题 6.8 while和 dowhile循环的比较(1)(2)main()main()int s=0,i;int s=0,i;scanf(“%d”,运行情况:运行情况:1 1s=55 s=55 再运行一次 再运行一次 11 11s=0 s=11,例6.8解析,可以看到:当输入i的值小于或等于10时,二者得到结果相同。而当i10时,二者结果就不同了。这是因为此时对while 循环来说,一次也不执行循环体,而对dowhile循环语句来说则要执行一次循环体。while 循
10、环是前判断,而dowhile循环是后判断。,6.5 循环的嵌套,3种循环(while、dowhile、for)可以互相嵌套。(1)while()(2)while()do while()while();(3)do(4)for(;)do while()while();while();,6.5 循环的嵌套,(5)for(;)(6)do for(;)for(;)while();,双重循环,2两层for组成的双循环的执行过程:当外循环控制变量每确定一个值时,内循环的控制变量就要从头至尾的循环一遍。例题6.9 双循环程序举例。main()int x,y;for(x=1;x=2;x+)for(y=1;y=3
11、;y+)printf(“x=%d,y=%dn”,x,y);,运行结果:x=1,y=1x=1,y=2x=1,y=3x=2,y=1x=2,y=2x=2,y=3,例题,例题6.10下面程序的输出结果是什么?(训练阅读程序能力)main()int k=0,m=0;int x,y;for(x=0;x2;x+)for(y=0;y3;y+)k+;k-=y;m=x+y;printf(“k=%d,m=%dn”,k,m);,运行结果:k=0,m=5,本程序是双循环嵌套,注意内循环体只有 一个语句k+;因为没有大花括号。不要将 k-=y;语句也认为是内循环体语句。当x=0时,内循环执行3次(y=0,1,2)k+执行
12、3次故循环结束时k=3。注意当内循环结束 时循环控制变量y的值是3,接着执行 k-=y;语句,即k=k-y=3-3=0。当x=1时,内循环仍执行原操作。使y=3,k=0。当x=2外循环结束,执行m=x+y=2+3=5。所以输出结果为k=0,m=5。,6.6 break语句和continue语句,为了使循环控制更加灵活,语言提供了break语句和continue语句。1 break语句一般格式:break;(本语句必须在循环中使用)功能:在循环中当满足特定条件时,使用break语句强行结束循环,转向执行循环语句的下一条语句。,例题,例题6.11 break语句应用main()int r;floa
13、t pi=3.14159,s;for(r=1;r100)break;printf(“r=%d,s=%fn”,r,s);,运行结果:r=1,s=3.141590r=2,s=12.566360r=3,s=28.274311r=4,s=50.265442r=5,s=78.539749,continue语句:,2continue语句:功能:对于for循环,跳过循环体其余语句,转向循环变量增量表达式的计算;对于while和do-while循环,跳过循环体其余语句,但转向循环继续条件的判定。例题6.12将100200之间的不能被3整除的数输出。(continue应用举例。)main()int n;for(
14、n=100;n=200;n+)if(n%3=0)continue;printf(“%d”,n);,例题,当n能被3整除时,执行contonue语句,结束本次循环,向前转到for执行n+,进行下一次循环,当n不能被3整除时才执行printf函数输出n的值后,再进行下一次循环,直到n200停止循环。例题6.13分析下面程序的运行结果。(continue应用举例。)/*例题源代码文件名:LT6_13.C*/main()int i=0,s=0;,例题,do if(i%2)i+;continue;i+;s+=i;while(i7);printf(“s=%dn”,s);分析:当i%2为0时,表示假跳过 i
15、+;continue;语句,执行i+;s+=i;当i%2为1时,表示真执行 i+;continue;语句,所以本程序s的和是1+3+5+7。,运行结果:s=16,6.7 循环程序举例,例题6.14 输出10100之间的全部素数。所谓素数n是指,除1和n之外,不能被2(n-1)之间的任何整数整除。算法设计要点:(1)显然,只要设计出判断某数n是否是素数的算法,外面再套一个for循环即可。(2)判断某数n是否是素数的算法:根据素数的定义,用2(n-1)之间的每一个数去整除n,如果都不能被整除,则表示该数是一个素数。判断一个数是否能被另一个数整除,可通过判断它们整除的余数是否为0来实现。,参考源程序
16、:,main()int i=11,j,counter=0;for(;i=i)/*整数i是素数:输出,计数器加1*/printf(“%6d”,i);counter+;,运行结果:11 13 17 19 23 29 31 37 41 4347 53 59 61 67 71 73 79 83 8997,循环程序举例,例题6.15相传古代印度国王舍罕要褒奖他的聪明能干的宰相达依尔(国际象棋发明者),问他需要什么,达依尔回答说:“国王只要在国际象棋的棋盘上第一个格子放1粒麦子,第二个格子放2粒麦子,第三个格子放4粒麦子,以此类推,每一格加一倍,一直放到64格,我就感恩不尽了,”。国王答应了,结果全印度的
17、粮食用完还不够。国王很纳闷,怎么也算不清这笔账。现在用C语言编程来算一下。计算s=1+2+2+2+2算出小麦的颗粒数。1立方米小麦大约1.42*10,参考源程序:,main()int n;double v,sum=0.0,t=1.0;for(n=0;n64;n+)sum+=t;/*做累加各项*/t*=2;/*做累乘求2各项*/printf(“sum=%en”,sum);v=sum/1.42e+8;printf(“v=%e”,v);,运行结果:sum=1.84467e+19v=1.29907+11,6.8阅读程序训练,例题6.16以下程序的输出结果是什么?/*例题源代码文件名:LT6_16.C*
18、/main()int x=3;doprintf(“%d”,x-=2);while(!(-x);,运行结果:1 2,解析:,以上程序包含一个do-while循环。循环体只有一个printf语句,输出项为表达式:x-=2,切每次输出比换行。当while的循环继续条件表达式!(-x)的值为0时就退出循环。但do-while循环的特点是一开始前面不做条件判断,由do直接进入循环,即不管循环继续条件表达式的值是否为0,至少要执行一次循环体。以上程序进入循环前x=3,执行x-=2后,x的值变为1,输出该值;在while的循环继续条件表达式!(-x)中,x的值先减1,变为0,再进行“逻辑非”运算,!0的值为1,(此处1表示真)循环继续。因x的值已是0,第二次执行x-=2后,x的值变为-2,再次输出。在while控制表达式!(-x)中,x的值先减1,变为-3,再进行“逻辑非”运算,!(-3)的值为0,退出循环。,例题6.17下面循环次数是多少?main()int k=2;while(k=0)printf(“%d”,k);k-;printf(“n”);,答:0次。解析:回答本题需要注意表达式k=0是赋值表达式,而不是关系表达式,故不论k为何值,表达式k=0使k为0,且此表达式的值也为0,此处0表示假,故不进入循环。所以循环次数是0。,