第五章循环控制结构1本章知识点:–while语句的一般形式及应用–for语句的一般形式及应用–do...while语句的一般形式及应用–多重循环结构的使用•break语句和continue语句25.1while语句语句的一般形式如下:while(表达式)循环体语句说明:while语句属于“当型”循环。表达式循环体语句假(0)真(非0)图5.1while语句流程图•说明:•(1)while是关键字。while后圆括号内的表达式一般是关系表达式或逻辑表达式,但也可以是C语言中任意合法的表达式。•(2)循环体语句可以是一条语句,也可以是多条语句,如果循环体语句包含多条语句,则需要用一对花括号“{}”把循环体语句括起来,采用复合语句的形式。while(表达式)循环体语句【例5.1】求前100个自然数的和。#includestdio.hintmain(){intn,sum;n=1;sum=0;/*变量赋初值*/while(n=100){sum=sum+n;/*累加求和*/n++;/*修改基本数据项n*/}printf(sum=%d\n,sum);return0;}5•需要注意的几个问题:(1)累加求和算法。这个程序采用的算法思想称为累加求和,即:不断用新累加的值取代变量的旧值,最终得到求和结果,变量sum也叫“累加器”,初值一般为0。(2)必须给变量赋初值。(3)正确判断条件的边界值。(4)避免出现“死循环”。(5)可能出现循环体不执行。(6)while后面圆括号内的表达式一般为关系表达式或逻辑表达式,但也可以是其它类型的表达式,.【例5.2】使用while语句求n!。#includestdio.hintmain(){intn,i=1;doublesum=1;printf(请输入一个正整数:);scanf(%d,&n);while(i=n){sum=sum*i;/*累乘求积*/i++;/*修改基本数据项i*/}printf(%d!=%.0f\n,n,sum);return0;}7•循环三要素之间的关系。循环变量赋初值、判断控制表达式和修改循环变量是所谓的“循环三要素”。一般来说,进入循环之前,应该给循环变量赋初值,确保循环能够正常开始;在控制表达式中判断循环变量是否达到循环的终止值;在循环体中对循环变量进行修改,以使循环正常的趋向终止。在编写程序时要注意他们的位置关系。【例5.3】编写程序,输入一个字符序列,直至换行为止,统计出大写字母、小写字母、数字、空格和其他字符的个数。intmain(){charch;inta,b,c,d,e;a=b=c=d=e=0;while((ch=getchar())!='\n'){if(ch='A'&&ch='Z')a++;/*判断是否为大写字母*/elseif(ch='a'&&ch='z')b++;/*判断是否为小写字母*/elseif(ch='0'&&ch='9')c++;/*判断是否为数字*/elseif(ch=='')d++;elsee++;}printf(%d,%d,%d,%d,%d\n,a,b,c,d,e);return0;}95.2for语句for语句的一般形式如下:for(表达式1;表达式2;表达式3)循环体语句说明:for语句属于“计数”型循环。11循环体语句真(非0)假(0)表达式1表达式2表达式3for语句流程图For语句最常用、最简单的形式•for(循环变量赋初值;循环条件;循环变量增值)12【例5.1】求前100个自然数的和。#includestdio.hintmain(){intn,sum=0;for(n=1;n=100;n++)sum=sum+n;printf(sum=%d\n,sum);return0;}【例5.4】设n=30,编写程序,计算并输出S(n)的值。S(n)=(1*2)/(3*4)-(3*4)/(5*6)+(5*6)/(7*8)+…+(-1)(n-1)*[(2n-1)*2n]/[(2n+1)*(2n+2)]+…#includestdio.h#includemath.hintmain(){intn;floats=0;for(n=1;n=30;n++)s=s+pow((-1),(n-1))*((2*n-1)*2*n)/((2*n+1)*(2*n+2));printf(s(n)=%f,s);return0;}13关于for语句的几点说明:(1)循环体语句可以是简单语句也可以是使用一对花括号括起来的复合语句。如果是一个语句,也可以和for写在一行上,这样使程序看起来更加简洁;如果循环体包含多条语句,最好是另起一行,采用一对花括号括起来的复合语句形式,增加程序的可读性。(2)表达式的省略。for语句中的三个表达式均可以省略,但是两个分号不能省略。for(循环变量赋初值;循环条件;循环变量增值)for(表达式1;表达式2;表达式3)循环体语句【例5.5】编写程序,输出所有的水仙花数。水仙花数是指一个3位数,其各位数字的立方和等于该数本身。例如:153=13+53+33=153,所以153就是水仙花数。intmain(){inta,b,c,i;for(i=100;i=999;i++){a=i/100;b=i/10%10;c=i%10;if(i==a*a*a+b*b*b+c*c*c)printf(%d\n,i);}printf(\n);}15【例5.11】判断m是否为素数。程序分析:所谓素数,就是一个正整数,除了本身和1以外并没有任何其他因子。例如2,3,5,7就是素数。intmain(){intm,i,k,flag;/*定义标志变量*/scanf(%d,&m);flag=1;/*假设m是素数*/for(i=2;im;i++)if(m%i==0){flag=0;/*表示m不是素数*/break;/*跳出循环*/}if(flag==1)printf(%disaprimenumber\n,m);elseprintf(%disnotaprimenumber\n,m);return0;}165.3do…while语句for语句的一般形式如下:do循环体语句While{表达式};说明:dowhile语句属于“直到型”循环。(1)do…while语句中“While{表达式};”后面的分号是不能省略的,这一点是和while语句不一样的。(2)do…while语句是先执行循环体语句,后判断表达式,因此无论条件是否成立,将至少执行一次循环体。而while语句是先判断表达式,后执行循环体语句,因此,如果表达式在第一次判断时就不成立,则循环体一次也不执行。•注意:(1)在计算机解决实际问题时,常常会用到类似本程序的“穷举法”。“穷举法”解决的问题一般具有这种特点:如果问题有解,一组或多组,必定全在某个集合中;如果这个集合内无解,集合外也肯定无解。这样,在解决问题时,就可以将集合中的元素一一列举出来,验证是否为问题的解。本题就是一一验证100~999之间所有的数,最终找出答案。(2)程序中在做是否相等关系判断(“i==a*a*a+b*b*b+c*c*c)使用到了关系运算符“==”,而不是“=”,后者是赋值运算符,在c语言中这两种运算符形式是不一样的,要注意区别。20循环体语句表达式假(0)真(非0)图5.5do…while语句流程图While语句和do…while语句的比较:一般来说,对于同一个问题,使用While语句或do…while语句结果是一样的,但有时并不一样,比较以下两段程序:21#includestdio.hintmain(){intn,sum=0;scanf(%d,&n);while(n=10){sum=sum+n;n++;}printf(sum=%d\n,sum);return0;}#includestdio.hintmain(){intn,sum=0;scanf(%d,&n);do{sum=sum+n;n++;}while(n=10);printf(sum=%d\n,sum);return0;}intmain(){charc;do{c=getchar();}while(c!='A');printf(校验成功\n);return0;}【例5.6】编写程序,实现对用户输入口令的校验。用户输入的口令如果与预设口令不一致,则需要重新输入,直到与预设口令一致为止。voidmain(){doublen=1.0,d=1.0,pi=0.0;intsign=1;do{pi=pi+d;n=n+2;sign=-sign;/*改变数据项的符号*/d=sign/n;/*求出数据项*/}while(fabs(d)=1.0e-6);pi=4.0*pi;printf(pi=%10.7lf\n,pi);}23【例5.7】用公式…求π的近似值,直到71513114最后一项的绝对值小于10-6为止。三种循环的比较:(1)while和do…while语句一般实现标志式循环,即无法预知循环的次数,循环只是在一定条件下进行;而for语句大多实现计数式循环。(2)一般来说,while和do…while语句的循环变量赋初值在循环语句之前,循环结束条件是while后面圆括号内的表达式,循环体中包含循环变量修改语句;一般for循环则是循环三要素集于一行。因此,for循环语句功能更强大,形式更简洁,使用更灵活。(3)while和for是先测试循环条件,后执行循环体语句,循环体可能一次也不执行。而do…while语句是先执行循环体语句,后测试循环条件,所以循环体至少被执行一次。5.4多重循环结构for(;;){……}for(;;){…}for(;;){…}…for(;;){…}for(;;){…for(;;){}…}嵌套循环并列循环交叉循环(错误)循环的嵌套是指一个循环语句的循环体内完整的包含另一个完整的循环结构。前述三种循环结构(while循环、for循环、do-while循环)可以任意组合嵌套。循环的嵌套有双重循环嵌套和多重循环嵌套。但一般使用两重或三重的比较多,若嵌套层数太多,就降低了程序的可读性和执行效率。如果是多重循环,外循环和内循环应选用不同的循环控制变量。26双重循环嵌套:嵌套层次数为2层的循环嵌套执行过程是:首先进行外层循环的条件判断,当外层循环条件成立时顺序执行外层循环体语句,遇到内层循环,则进行内层循环条件判断,并在内层循环条件成立的情况下反复执行内层循环体语句,当内层循环因循环条件不成立而退出后重新返回到外层循环并顺序执行外层循环体的其它语句,外层循环体执行一次后,重新进行下一次的外层循环条件判断,若条件依然成立,则重复上述过程,直到外层循环条件不成立时,退出双重循环嵌套,执行后面其它语句。【例5.8】编写程序,输出1000以内所有的完数。如果一个整数的因子之和等于这个数本身,这个数就被称为完数。例如:1、2、3是6的因子,并且6=1+2+3,所以6是完数。程序分析:此题应该分成两步来做。第一步:判断一个数n是否为完数。可以定义一个变量s作为“累加器”,此问题仍然需要用前面讲过的“穷举法”,从1~n-1逐一去除n,如果能除尽,就说明是n的因子,把它累加到s上。可以选用for循环。第二步:外层循环对1000以内的所有正整数一一进行判断,利用第一步的方法,逐个判断n的因子之和s是否等于n。若相等,则显示输出。同样选用for循环。28#includestdio.hintmain(){inti,n,s;for(n=2;n=1000;n++)/*外循环*/{s=0;for(i=1;in;i++)/*内循环求出n的所有因子之和*/if(n%i==0)s+=i;if(n==s)/*判断a是否等于所有因子之和*/printf(%d\n,n);}return0;【例5.9】打印九九乘法口诀表。程序分析:乘法口诀表的形式如下:1*1=11*2=22*2=41*3=32*3=63*3=91*4=42*4=83*4=124*4=16…1*9=92