C语言第六章课件.ppt
第六章 循环控制,了解goto语句和if 语句构成的循环。熟练掌握for语句、while语句和do-while语 句,及其break语句、continue语句的使用。熟练掌握循环结构程序设计的概念及其程 序编制技术。,main()int i=1;long int sum=1;while(i=10)sum=sum*i;i+;printf(“10!=%ldn”,sum);,sum=1*2*3*4*5*6*7*8*9*10;,sum,循环结构的特点是:程序的流程是在给定条件时,反复执行,某个程序段。,语言中可以用以下语句来实现循环:用goto语句和 if 语句构成循环;用while语句;用do_while语句;用for语句。,6.2 goto语句和goto语句构成的循环,一、goto 语句,goto 语句为无条件转向语句,其作用为:使程序的执行无条件地转移到指定处。,如:goto label_1;goto 123;,执行过程:执行语句时,程序转移到以标号 为前缀的语句处继续执行。,如:p1:x+;.goto p1;,说明:,goto语句是一种非结构化语句,结构化程序设计方法不提倡使用goto语句,因为滥用goto语句将使程序流程无规律,可读性差。但也不是绝对禁止使用,只有在能够大大提高程序效率时才使用。,且记:不要从循环体外跳到循环体内!,二、用goto语句和 if 语句构成循环,例:计算10!并输出结果。,main()int i=1,sum=1;loop:if(i=10)sum=sum*i;i+;goto loop;printf(“10!=%dn”,sum);,运行结果:10!=24320,本应是:10!=3628800,main()int i=1;long sum=1;loop:if(i=10)sum=sum*i;i+;goto loop;printf(“10!=%ldn”,sum);,6.3 while 语句,例:将上面计算10!并输出结果的程序用 while语句写出:,main()int i=1;long int sum=1;while(i=10)sum=sum*i;i+;printf(“10!=%ldn”,sum);,main()int i=1;long int sum=1;loop:if(i=10)sum=sum*i;i+;goto loop;printf(“10!=%ldn”,sum);,循环结构的术语,1.循环条件:是循环结构中的测试表达式。,如:while(i=10),2.循环体:是在每个循环周期均要执行一次的语 句。语句可以是任何语句,简单语句、复合语句、空语句均可以。,如:上例while语句中用花括号括起来的复合语句。,3.循环控制变量:是在循环条件中控制条件是真 是假的变量。,如:上例while语句中使用的变量 i。,注意:循环条件中的表达式一般是逻辑表达式和关系表达式,也可以是算数表达式(非0为真,0为假)。一般表达式中应含有循环控制变量。while(3)和while(0)虽然从程序设计的角度上说是不合理的,但是合法的。,while(3)语句 表示无限循环while(0)语句 表示不进入循环体,要写出一个正确的循环结构,对控制变量要做三方面工作:控制变量赋初值;把控制变量写入正确的循环条件;控制变量的更新、调整。,6.4 do-while 语句,分号不能少,例:将上面计算10!并输出结果的程序用 do-while语句写出:,main()int i=1;long int sum=1;while(i=10)sum=sum*i;i+;printf(“10!=%ldn”,sum);,main()int i=1;long int sum=1;do sum=sum*i;i+;while(i=10);printf(“10!=%ldn”,sum);,我们将while和do-while循环做一下比较:,main()int i;long sum=1;scanf(“%d”,main()int i;long sum=1;scanf(“%d”,输入:9输出:90,输入:11输出:1,输入:9输出:90,输入:11输出:11,比较上面两个程序,虽然结构是相同的,在输入值为有效值时结果相同,但当输入无效值时输出结果是不同的。为什么?,while与do-while的主要区别:,6.5 for语 句,表达式1:一组初始化表达式。表达式2:循环控制条件。表达式3:在执行完循环体语句之后执行的表达式。,我们前面已经说明,要正确表达循环结构应注意三方面的问题:控制变量的初始化,循环的条件和控制变量的更新。for语句在书写形式上正好体现了这种紧密的逻辑关系。,执行过程:,例:将上面计算10!的程序用 for语句写出:,main()int i;long sum;for(i=1,sum=1;i=10;i+)sum=sum*i;printf(“10!=%ldn”,sum);,main()int i;long sum;for(i=1,sum=1;i=10;sum=sum*i,i+);printf(“10!=%ldn”,sum);,空语句,说明:,表达式1:用于进入循环体之前给某些变量赋初值。若省略,可在for语句前给变量赋初值。,main()int i=1;long sum=1;for(;i=10;i+)sum=sum*i;printf(“10!=%ldn”,sum);,for 循环的三个表达式起着不同的作用,根据需要可以省略。,表达式2:决定循环的条件,若省略,则为无限 循环。,表达式3:用于循环一次后对某些变量进行修改。若省略,可在循环体内对变量进行修改。,main()int i;long sum=1;for(i=1;i=10;)sum=sum*i;i+;printf(“10!=%ldn”,sum);,for 语句最为灵活,它完全可以代替的while语句。,如:i=1;while(i=10)sum=sum*i;i+;,等效于,for(i=1;i=10;i+)sum=sum*i;,for语句功能很强,其中表达式1和表达式3可以是逗号表达式,但为增强程序的可读性,一般不要把与循环无关的东西放到for语句中。,如:sum=1;for(i=1;i=10;i+)sum=sum*i;,6.6 三种循环语句的总结,三种循环语句共同的特点是:当循环控制条件非零时,执行循环体语句,否则终止循环。,语句可以是任何语句,简单语句、复合语句、空语句均可以。,while和for语句先判断循环控制条件,do-while语句后判断循环控制条件,所以,while和for语句的循环体可能一次也不执行,而do-while语句的循环体至少也要执行一次。,在循环体内或循环条件中必须有使循环趋于结束的语句,否则会出现死循环等异常情况。,三种循环可以处理同一问题,一般情况可以互相代替。但在实际应用中,我们要根据具体情况来选用不同的循环语句。选用的一般原则如下:,如果循环次数在执行循环体之前就已确定,一般用for语句;如果循环次数是根据循环体的执行情况确定的,一般用while语句或者do-while语句。,(循环次数确定例)int i;long sum=1;for(i=1;i=10;i+)sum=sum*i;,(循环次数不确定例)char cdo c=getchar();printf(“%c”,c);while(c!=q|c!=Q);,当循环体至少执行一次时,用do-while语句;反之,如果循环体可能一次也不执行时,用while语句。,(循环体至少执行一次)/*只有当用户键入q或Q,才结束循环*/char cdo c=getchar();printf(“%c”,c);while(c!=q|c!=Q);,(循环体可能一次不执行)/*只有不是q或Q的字符才被打印*/char c;c=getchar();while(c!=q|c!=Q);printf(“%c”,c);c=getchar();,6.7 循环的嵌套,例:在屏幕上打印一个8行7列的星号矩阵。,#include main()int i;for(i=0;i7;i+)printf(*);/*打印第1行星号*/printf(n);for(i=0;i7;i+)printf(*);/*打印第2行星号*/printf(n);for(i=0;i7;i+)printf(“*”);/*打印第8行星号*/,什么叫循环嵌套?,一个循环的循环体中套有另一个循环叫循环嵌套。这种嵌套过程可以一直重复下去。,一个循环外面包围一层循环称为二重循环。一个循环外面包围二层循环称为三重循环。一个循环外面包围多层循环称为多重循环。,while、do-while、for可以互相嵌套自由组合。,例:将上例(打印8行7列的星号矩形)用二重循环实现。,#include main()int i,k;for(i=0;i8;i+)for(k=0;k7;k+)printf(*);printf(n);,6.8 break 和continue语句,一、break 语句,功能:结束当前的一层循环。,解释:break 语句一般用在循环体的条件语 句中,其作用是当某个条件成立时用 break语句退出循环,不再继续执行其余的几次循环。,例:打印半径为110的圆的面积,如果面积超过100,则不再打印。,#include#define PI 3.14159main()int r;float area;for(r=1;r100.0)break;printf(area=%fn,area);printf(now,r=%dn,r);,注意:在嵌套循环中使用break语句,它只影响包含它的最内层循环,即程序仅跳出包围该break的那层循环。,例:编写程序,输出三角乘法表。main()int i,j;for(i=1;ii)break;printf(“%3d”,i*j);printf(“n”);,运行结果:1 2 4 3 6 9 4 8 12 165 10 15 20 256 12 18 24 30 367 14 21 28 35 42 498 16 24 32 40 48 56 649 18 27 36 45 54 63 72 81,功能:结束循环体,进入下一个循环周期。,解释:一旦执行了continue语句,程序就跳 过循环体中位于该语句后的所有语句,提前结束本次循环周期并开始下一个 循环周期。,二、continue语句,例:计算用户输入的所有正整数的和,用户输入 0 时结束。,#include main()long data,sum;sum=0;do printf(“Please input:data=”);scanf(%ld,6.9 程序举例,例6.6 用/41-1/3+1/5-1/7+1/9 求近似的值。直到最后一项的绝对值小于10-6为止。,#include math.hmain()int s;float n,t,sum,pi;t=1;sum=0;n=1;s=1;while(fabs(t)=.000001)sum=sum+t;n=n+2;s=-s;t=s/n;pi=sum*4;printf(pi=%fn,pi);,运行结果:=3.141594,第几个月 小兔子对数 中兔子对数 老兔子对数 总数 1 1 0 0 1 2 0 1 0 1 3 1 0 1 2 4 1 1 1 3 5 2 1 2 5.,例6.7 斐波纳契数列:1,1,2,3,5,8,例6.7 求斐波纳契数列:1,1,2,3,5,8 的前20个数。,(该数列特点:第1、2两个数是1、1,从第3个数 开始,该数是其前两个数之和。),main()int f1=1,f2=1,i;for(i=1;i=10;i+)printf(%6d%6dn,f1,f2);f1=f1+f2;f2=f1+f2;,运行结果:1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765,例6.7 求斐波纳契数列:1,1,2,3,5,8 的前40个数。,main()long int f1=1,f2=1,i;for(i=1;i=20;i+)printf(%12ld%12ld,f1,f2);if(i%2=0)printf(“n”);f1=f1+f2;f2=f1+f2;,运行结果:1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 2584 4181 6765,例6.8 判断M是否为素数。,#includemain()int m,i,k;scanf(%d,素数的定义:只能被1和它他本身整除的正整数。,例6.9 求出100200以内的所有素数。,main()int m,k,i,n=0;for(m=101;m=k+1)printf(%d,m);n=n+1;if(n%10=0)printf(n);printf(“n”);,例6.10 译密码。密码规律为每个字母用其后 第四个字母代替,26个字母循环排列。,#include stdio.hmain()char c,c1;while(c=getchar()!=n)if(c=a,China!,Glmre!,ABCDEFGVWXYZ,习题6.3(看书P120),已知:一位数码a 和要组成的最大重码数tn的位数n。求:各重码数的累加和sn。,算法:对给定的a和n,从i=1 n 依次作:求第i个重码数tntn*10+a。(其中tn的初值应是0)求累加和 snsn+tn。,main()int sn,a,n,i,tn;long sn,tn;printf(na,n=);scanf(%d%d,for(tn=0,sn=0,i=1;i=n;i+)tn=tn*10+a;sn+=tn;printf(na+aa+.=%ld,sn);,习题6.7(看书P120),已知:正整数 1n1000 求:其中的“完数”,即一个数的所有因子之和等 于该数本身的数。,算法:对于n=21000的每一个数,进行:求出该数的所有因子并累加于sum(不保 留其中的因子)。(一个数n的所有因子的求法:只需用2n/2 的所有数去除n,能整除的就是其因子。)当能满足完数条件时(sum=n),重新求 出该数的所有因子并打印。,main()int sum,n,i;for(n=2;n=1000;n+)sum=0;for(i=1;i=n/2;i+)if(n%i=0)sum+=i;if(sum=n)printf(“n%d:,n);for(i=1;i=n/2;i+)if(n%i=0)printf(%d,i);,习题6.11(看书P120P121),已知:正数a和求a的算术平方根x的公式。求:a的算术平方根x。,算法:从键盘上输入a,并假设a的根为x=a;误差标志变量dx。重复做:记下上一个根 x0=x。按公式求下一个根 x。求两个根的误差绝对值dx=fabs(x-x0)。当两次求得的根之差的绝对值 dx=0.00001时停止。x既为所求平方根。,#include“math.h”main()float a,x,x0,dx;printf(n a=);scanf(%f,本章作业:,编写6.1、6.2、6.10题的对应程序。要求:6.1题用for循环 6.2题用do-while循环 6.10题用while循环或for循环2.上机调试作业题,写出总结报告。3.预习书中第七章内容(数组)。,