C语言 第5章_循环结构.ppt
1/52第第5章章 循环结构循环结构1.5.1 5.5 2学时2.5.6 2学时2/52问题的提出:对于这样的一类问题:问题1.从键盘输入10个学生的成绩,求总成绩。问题2.求100以内的素数问题3.求1!+2!+3!+10!用前面所学知识来解决这些问题是非常麻烦的对于问题1的一个笨办法:设一个变量,每次输入一个学生成绩,累加后再输入下一个学生成绩,如下:scanf(“%f”,&a);s=s+a;scanf(“%f”,&a);s=s+a;.这样重复10次,然后输出s的值。是否可用一种语句,使这两句话能自动的重复执行10次,以简化书写的麻烦呢?这就是循环语句的任务。3/52u循环结构特点:在给定条件(循环条件)成立时,反复执行某程序段(又称循环体),直到条件不成立为止。uC语言可实现循环的语句:while 语句Dowhile 语句for 语句4/52while(表达式)循环体语句;v执行流程:表达式循环体假(0)真(非0)whilev一般形式:5.1 while循环结构5/52v特点:先判断表达式,后执行循环体v说明:l循环体有可能一次也不执行l循环体可为任意类型语句l下列情况,退出while循环u条件表达式不成立(为零)u循环体内遇break,return,gotol无限循环:while(1)循环体;6/52例例 用用whilewhile循环求循环求#includemain()inti,sum=0;i=1;while(i=100)sum=sum+i;i+;printf(%d,sum);循环初值循环终值循环变量增值循环条件循环体go7/52【例例】问题问题1的解决方法的解决方法1:采用:采用while循环结构循环结构 main()intcount=1,total=0,grade;while(count=10)printf(inputthegrade:);scanf(%d,&grade);total=total+grade;count+;printf(%dn,total);应注意:应注意:1、计数器和累加器的初、计数器和累加器的初值;值;2、一次循环后,循环控、一次循环后,循环控制变量的变化情况。制变量的变化情况。3、跳出循环时循环控制、跳出循环时循环控制变量的值应为多少?如变量的值应为多少?如果果count初值为初值为10,20时时呢?呢?111098765432count10987654321次数次数每次循环后,控制变量每次循环后,控制变量count的变化情况的变化情况8/52例例 显示显示110的平方的平方#includemain()inti=1;while(i=10)printf(%d*%d=%dn,i,i,i*i);i+;运行结果:1*1=12*2=43*3=94*4=165*5=256*6=367*7=498*8=649*9=8110*10=100循环变量初值循环变量初值循环条件循环条件改变循环变量值改变循环变量值9/52注意:循环控制变量值在循环体内必须有所改变。例如:请问下例中循环结束时i值为多少?i=1;while(i=100)putchar(*);i+;这个循环永远不会结束这个循环永远不会结束,因为循环控制变量因为循环控制变量i i没有没有在循环体内被改变,在循环体内被改变,i+;i+;不属于循环语句。不属于循环语句。i+应该在循环体内改变:10/52do循环体语句;while(表达式);v执行流程:do循环体表达式假(0)真(非0)whilev一般形式:5.2 dowhile 循环结构11/52v特点:先执行循环体,后判断表达式v说明:l至少执行一次循环体ldowhile可转化成while结构expr循环体假(0)真(非0)循环体While循环12/52例用dowhile循环求#includemain()inti,sum=0;i=1;dosum+=i;i+;while(i=100);printf(%d,sum);13/52【例例】问题问题1的解决方法的解决方法2:采用:采用do-while循环结构循环结构【源程序】main()int count=1,total=0,grade;do printf(input the grade:);scanf(%d,&grade);total=total+grade;count+;while(count=10);printf(%dn,total);应注意:应注意:1、一次循环后,循环控制、一次循环后,循环控制变量的变化情况。变量的变化情况。2、跳出循环时循环控制变、跳出循环时循环控制变量的值应为多少?如果量的值应为多少?如果count初值为初值为10,20时呢?时呢?111098765432count10987654321次数次数每次循环后,控制变量的变化情况每次循环后,控制变量的变化情况14/52例例 while和和dowhile比较比较#includemain()inti,sum=0;scanf(%d,&i);dosum+=i;i+;while(i=10);printf(%d,sum);#includemain()inti,sum=0;scanf(%d,&i);while(i=10)sum+=i;i+;printf(%d,sum);1、跳出循环时循环控制变量的值应为多少?如果输入值为1,10,20时呢?2、输出结果呢?15/52n1.while结构与do-while循环结构相类似.n2.但要注意区别:n前者:先判断表达式,再执行语句。至少要执行0次n后者:先执行语句,再判断表达式。至少要执行1次。n3.也就是说用两种循环结构处理同一问题时,若二者的循环体部分是一样的,当while后面表达式的第一次的值为“真(非0)”时,两种循环结构得到的结果相同,否则二者的结果不相同。While 与与 do while 循环结构的比较循环结构的比较16/52for(表达式1;表达式2;表达式3)循环体语句;v执行流程:vfor(循环变量赋初值;循环条件;改变循环变量)表达式表达式1表达式表达式2循环体循环体表达式表达式3TFv一般形式:5.3 for循环结构17/52vfor语句一般应用形式:for(循环变量赋初值;循环条件;循环变量增值)循环体语句;v说明:lfor语句中expr1,expr2,expr3类型任意,都可省略,但分号;不可省l无限循环:for(;)lfor语句可以转换成while结构expr1;while(expr2)循环体语句;expr3;例用for循环求#includemain()inti,sum=0;for(i=1;i=100;i+)sum+=i;printf(%d,sum);18/52例:#includemain()inti;for(i=0;i10;i+)putchar(a+i);运行结果:abcdefghij例:#includemain()inti=0;for(;i10;i+)putchar(a+i);例:#includemain()inti=0;for(;i10;)putchar(a+(i+);例:#includemain()inti=0;for(;i10;putchar(a+i),i+);逗号运算符的主要应用在逗号运算符的主要应用在for语句中的表达式语句中的表达式1或表达式或表达式3建议为了增强程序的可读性,尽量不省略for结构中的表达式。19/52main()inti,j,k,s=0;for(i=1,j=100;i=j;i+,j-)k=i+j;s=s+i+j;printf(%d+%d=%dn,i,j,k);printf(%dn,s);#includemain()charc;for(;(c=getchar()!=n;)printf(%c,c);#includemain()inti,c;for(i=0;(c=getchar()!=n;i+=3)printf(%c,i+c);例:双循环变量求 如输入:abc则输出:abc如输入:abc则输出:aei20/525.4 循环结构的嵌套n在循环体语句中又包含另一个完整的循环结构的形式,称为循环结构的嵌套。n嵌套在循环体内的循环体称为内循环,外面的循环体称为外循环。如果内循环中又有嵌套的循环语句,则构成多重循环。while、dowhile、for循环结构既可以自身嵌套又可以相互嵌套。2021/52循环的嵌套v三种循环可互相嵌套,层数不限v外层循环可包含两个以上内循环,但不能相互交叉v嵌套循环的执行流程(1)while()while().(2)do do while();.while();(4)while()do while();.(3)for(;)for(;)v嵌套循环的跳转禁止:从外层跳入内层l 跳入同层的另一循环2122/52*#includemain()inti,j;for(i=1;i=5;i+)/控制行数for(j=1;j=i;j+)/控制每一行中*的个数printf(*);printf(n);22例:编写程序输出如下图形。例:编写程序输出如下图形。*思考:如何输思考:如何输出右侧图形?出右侧图形?for(j=1;j=10-i;j+)/控制每一行中空格的个数printf();23/52例:例:编写程序求解编写程序求解“百钱买百鸡百钱买百鸡”问题。问题。算经算经一书中提一书中提出出“百鸡问题百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、母、雏各几何?钱一。百钱买百鸡,问鸡翁、母、雏各几何?分析:设变量分析:设变量a,b分别代表鸡翁、鸡母的个数,则鸡雏的分别代表鸡翁、鸡母的个数,则鸡雏的个数为个数为100-a-b。通过分析可知,。通过分析可知,a,b可能取值的范围可能取值的范围为:为:a在在019,b在在033。则鸡翁、鸡母、鸡雏可能的。则鸡翁、鸡母、鸡雏可能的组合有组合有2034=680种。对每一种组合都用是否符合百钱种。对每一种组合都用是否符合百钱的条件进行测试,若符合,则该组合就是问题的一个解,的条件进行测试,若符合,则该组合就是问题的一个解,因此解可能不唯一因此解可能不唯一。23#includemain()int a,b,c;for(a=0;a=19;a+)for(b=0;b=33;b+)c=100-a-b;if(5.0*a+3.0*b+c/3.0=100)printf(a=%d,b=%d,c=%dn,a,b,c);24/52 n5.5 辅助控制语句辅助控制语句nbreak语句n功能:在循环语句和switch语句中,终止并跳出循环体或开关体n说明:nbreak只能终止并跳出最近一层的结构nbreak不能用于循环语句和switch语句之外的任何其它语句之中25/52exprbreak;假(0)真(非0)whiledobreak;.expr假(0)真(非0)while26/52expr2break;.假(0)真(非0)forexpr1expr3switchexpr语句组1break;语句组2break;语句组nbreak;语句组break;.const1const2constndefaultcase27/52例例 break举例:输出圆面积,面积大于举例:输出圆面积,面积大于100时停止时停止#definePI3.14159main()intr;floatarea;for(r=1;r100)break;printf(r=%d,area=%.2fn,r,area);28/52例例 break举例:小写字母转换成大写字母举例:小写字母转换成大写字母,直至输入非字母字符直至输入非字母字符#includemain()charc;while(1)c=getchar();if(c=a&c=z)putchar(c-a+A);elsebreak;c-32c-(a-A)29/52例例 判断判断m是否素数是否素数读入mk=mi=2当ikm被i整除真假用break结束循环i=i+1ik+1真假输出:m”是素数”输出:m”不是素数”#include#includemain()intm,i,k;scanf(%d,&m);k=sqrt(m);for(i=2;i=k+1)printf(%disaprimenumbern“,m);elseprintf(%disnotaprimenumbern“,m);30/52例判断m是否素数#include#includemain()intm,i,k;scanf(%d,&m);k=(int)sqrt(m);i=2;while(m%i!=0&i=k)i+;if(i=k+1)printf(“%d是素数n,m);elseprintf(“%d不是素数n,m);除数i的取值范围:优化:2sqrt(m)半优化:2m/2不优化:2m-131/52continue语句v功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断v仅用于循环语句中exprcontinue;假(0)真(非0)while真(非0)docontinue;.expr假(0)whileexpr2continue;.假(0)真(非0)forexpr1expr332/52例例 求输入的十个整数中正数的个数及其平均值求输入的十个整数中正数的个数及其平均值#includemain()inti,num=0,a;floatsum=0;for(i=0;i10;i+)scanf(%d,&a);if(a0)if(grademax)max=grade;if(grademin)min=grade;printf(inputthenextgrade:);scanf(%d,&grade);printf(max=%dmin=%dn,max,min);课堂任务:课堂任务:1.用用dowhile改写改写35/52【源程序源程序】/用用dowhile改写改写,并用了并用了breakmain()intgrade,max=-1,min=1000;/为何这样取初值?doprintf(inputthenextgrade:);scanf(%d,&grade);if(grademax)max=grade;if(grademin)min=grade;while(1);printf(max=%dmin=%dn,max,min);36/52main()intn;longt=1,sum=0;/注意累乘器及累加器的初值for(n=1;n100;n+)t=t*n;if(n%2=0)continue;sum=sum+t;printf(sum=%ldn,sum);次数次数1239899t1!2!3!98!99!sum1!+2!+3!+98!+99!n23499100每次循环后,重要变量的变化情况每次循环后,重要变量的变化情况【例例】计算计算1!+3!+5!+1!+3!+5!+99!+99!。n分析:该题实质上是一个累加求和的问题,而且已知其循环的次数因此分析:该题实质上是一个累加求和的问题,而且已知其循环的次数因此可以用可以用forfor语句来实现;对于累加应有选择地进行,即只对奇数项求和,语句来实现;对于累加应有选择地进行,即只对奇数项求和,可以用可以用ifif语句和语句和continuecontinue语句组合来进行选择性地累加。语句组合来进行选择性地累加。返回37/52【源程序源程序】main()main()intint n=1;n n=1;n while(nwhile(n=10)=10)if(nif(n=6)=6)continue;continue;printf(%4d,n);printf(%4d,n);n+;n+;请问请问:跳出循环时循环控制跳出循环时循环控制变量的值应为多少?运行变量的值应为多少?运行结果呢?该程序有何问题结果呢?该程序有何问题?如果有该如何改正?如果有该如何改正?无限循环无限循环;运行结果:运行结果:1 2 3 4 5666665432n987654321次数次数每次循环后,重要变量的变化情况每次循环后,重要变量的变化情况例例.阅读程序并回答问题阅读程序并回答问题38/52main()longinti,s=0;for(i=10;i=150;i+)if(i%3=0|i%7=0)s=s+i*i;printf(“n%ld”,s);例例.10,150之间,能被之间,能被3或或7整除的数的平方和。整除的数的平方和。分析:用变量s求和,s初值为0。用变量i从10到150循环,如果i能被3或7整除(i%3=0|i%7=0),则s=s+i*i。39/52000102030405101112131415202122232425303132333435404142434445505152535455请写出输出结果:请写出输出结果:例例 执行语句段:执行语句段:for(i=0;i6;i+)for(j=0;j6;j+)printf(“%3d%d”,i,j);putchar(n);外循环外循环内循环内循环i=0 j=0,1,2,3,4,5i=0 j=0,1,2,3,4,5i=1 j=0,1,2,3,4,5i=1 j=0,1,2,3,4,5i=2 j=0,1,2,3,4,5i=2 j=0,1,2,3,4,5i=3 j=0,1,2,3,4,5i=3 j=0,1,2,3,4,5i=0 j=0,1,2,3,4,5i=0 j=0,1,2,3,4,5i=0 j=0,1,2,3,4,5i=0 j=0,1,2,3,4,540/52#includemain()inti,j,sum=0;for(i=0;i=3;i+)for(j=0;j=5;j+);sum=sum+j;printf(sum=%dn,sum);#includemain()inti,j,sum=0;for(i=0;i=3;i+)for(j=0;j=5;j+)sum=sum+j;printf(sum=%dn,sum);sum=6sum=60课堂练习课堂练习41/52#includemain()inti,j,sum=0;for(i=0;i=3;i+)for(j=0;j=i;j+)sum=sum+j;printf(sum=%dn,sum);sum=10课堂练习课堂练习i=0 j=0i=0 j=0i=1 j=0,1i=1 j=0,1i=2 j=0,1,2i=2 j=0,1,2i=3 j=0,1,2,3i=3 j=0,1,2,342/52算法:从i=3开始做分别用2,3,4,i除i,(可参考数论知识)如果i被某个数整除,i是合数。i+;测试下一个i;例例 编程求出编程求出3 3至至10001000内的全部的质数。内的全部的质数。#includemain()inti,j,count=0,flag;/*用flag作标志*/for(i=3;i=1000;i+)flag=0;/*设标志为0*/for(j=2;j=sqrt(i);j+)if(i%j=0)/*测试j能够整数i*/flag=1;break/*能,则不是素数,标志为1*/*i测试完毕*/if(flag=0)/*i是素数,则输出*/printf(“%4d,”,i);count+;if(count%8=0)printf(“n”);/*每行输出8个*/*测试下一个i*/43/52main()longintf1=1,f2=1,f3,n;for(n=3;n=1;a-)s=0;for(i=1;ia;i+)if(a%i=0)s=s+i;if(a=s)break;printf(“n%d”,a);分析:用变量分析:用变量a从从1000到到1循环,如果循环,如果a等于其真因等于其真因子的和,则循环结束。判子的和,则循环结束。判断断a是否等于其真因子的是否等于其真因子的和:用变量和:用变量s求求a的真因子的真因子的和,的和,s初值为初值为0,用变量用变量i从从1到到a-1循环,如果循环,如果a%i=0,则,则s=s+i。得。得出出s值后,若值后,若a=s,则则a为为所求。所求。45/52例例:求求 1/99+2/98+1main()float s=0.0;int i,j;for(i=1,j=99;i2)printf(d,-n);while(n2)n-printf(d,-n);注意:当注意:当while后有后有封号结果不一样!封号结果不一样!47/525.7 本章小结本章小结n本章重点介绍了C语言的三种循环结构:while、do-while、for循环结构。在处理同一问题时,一般情况下三者可以互相替换。三种循环结构还可以互相嵌套,即构成多层循环。对于while和do-while循环结构,循环控制变量初始化的操作应在while和do-while语句之前完成,只在while后面指定循环条件,切记在循环体内要包含使循环趋于结束的语句;for循环结构可以在表达式1中初始化循环控制变量,表达式2指定循环条件,表达式3中包含使循环趋于结束的语句;注意while和for循环结构是先判断表达式,后执行循环体,而do-while循环结构是先执行循环体,后判断表达式。在实际运用中,应根据具体的情况灵活选用这三种循环结构来解决问题。48/52本章附录一本章附录一n程序调试(程序调试(VC+环境)主要介绍:环境)主要介绍:1.如何设置断点如何设置断点2.如何调试运行?如何调试运行?3.如何逐行调试运行?如何逐行调试运行?4.变量的变化情况变量的变化情况49/52单击单击1.如何设置断点如何设置断点1)单击单击“断点设计按断点设计按钮钮”可在当前行设可在当前行设置断点置断点;2)当程序运行到断点当程序运行到断点这一行时会停下来,这一行时会停下来,等待用户干涉。等待用户干涉。50/522.如何调试运行?如何调试运行?单击单击51/523.如何逐行调试运行?如何逐行调试运行?或单击或单击F10可运行黄色箭可运行黄色箭头所在行,并显示变量变头所在行,并显示变量变化情况化情况单击单击52/524.变量的变化情况变量的变化情况