资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,C,程序设计(第二版),-,教学,课件,制作人:黄 荧,制作人单位:河师大数学与信息科学学院,第六章 循环,控制,本章主要内容,:,1,三种循环语句:,for,、,while,、,do-while,(,重点,!),2,两种中断语句:,break,、,continue,3,几种关于循环的经典算法,(,重点,!),6.1,概述,1,什么是循环结构,?,根据,条件,P,成立与否,,,决定,是否,重复执行,某一操作,2,循环结构的程序设计能解决什么样的实际问题,?,用来解决包含,有重复操作,的实际问题,.,如,求和,:1+2+3+4+100,输入全班同学的成绩,等等,3,循环结构的问题要素,:,1,)哪一部分操作在重复,-,循环体,2,)循环哪时候,结束,-,循环控制条件,!,(,循环控制条件,不成立,的时候,结束,),4,实现循环结构的四种方法:,1,),goto,-if,语句(不提倡),2,),while,语句,(主要实现当型循环),3,),dowhile,语句,(,主要实现直到型循环,),4,),for,语句(多功能),表达式,语句,非,0,0,6.2,goto,-if,语句实现的循环。,1,无条件转移语句:,一般格式:,goto,标号;,语句标号,必须是标识符,不能用整数!,格式,1,标号,:,if(,表达式,),goto,标号,;,2,实现循环的格式:,格式,2,标号:,if(,表达式,),goto,标号,;,例,6.1,求,=1+2+3+4+100,#include,void main(),int,sum=0,i=1;,loop:,/*,标号*,/,if(,i,=100,),sum=,sum+i,;,i+;,goto,loop;,printf(sum,=%,dn,sum,);,6.3,while,语句(主要用于实现当型循环,),当满足条件表达式,P,时,A,块,一般格式:,while,(,表达式,),语句,表达式,语句,非,0,0,执行过程,一般格式:,while,(,表达式,),语句,例,6.2,求 (,用,while,语句,),#include,void main(),int,sum=0,i=1;,while(,i=100,),sum=,sum+i,;,i+;,printf(sum,=%,dn,sum,);,表达式,语句,非,0,0,执行过程,思考:sum不赋初值行不行?sum赋成1行不行?,去掉 i+;行不行?去掉了会发生什么情况?,6.4,do-while,语句,(,主要用实现直到型循环,),一般格式:,do,语句,while,(,表达式,),;,表达式,语句,非,0,0,执行过程,A,块,直到条件,P,为假时停止,例,6.3,求 (,用,do-while,语句,),一般格式:,do,语句,while,(,表达式,),;,#include,void main(),int,sum=0,i=1;,do,sum+=i;,i+;,while(,i,=100,);,printf(sum,=%,dn,sum,);,表达式,语句,非,0,0,执行过程,分析两程序作用是否相同,?,为什么,?,程序,1,:,#include,void main(),int,sum=0,i=11,;,while(,i,=10,),sum=sum+i;,i+;,printf(sum,=%,dn,sum,);,程序,2,:,#include,void main(),int,sum=0,i=11,;,do,sum=sum+i;,i+;,while(,i,=10,);,printf(sum,=%,dn,sum,);,输出结果:,sum=11,输出结果:,sum=0,6.5,for,语句,一般格式:,for(,表达式,1;,表达式,2,;,表达式,3),语句,执行过程,:,表达式,2,语句,非,0,0,求解,表达式,1,求解,表达式,3,语句,求解表达式,3,表达式,2,为真,求解表达式,1,例,6.4,求,(用,for,语句,),#include,void main(),int,sum,i;,sum=0;,for(i,=1;,i=100,;i+),sum=,sum+i,;,printf(sum,=%,dn,sum,);,考虑:,求,100,!,S=5+10+15+200,一般格式:,for(,表达式,1;,表达式,2,;,表达式,3),语句,例,6.4a,求 (用,for,语句可以代替,while,),#include,void,main(),int,sum,i;,sum=0;,for(i,=0;,i=100,;i+),sum=sum+i;,printf(sum,=%,dn,sum,);,i=0;,while(i=100),sum=sum+i;,i+;,一般地,对一般格式:,for(,表达式,1;,表达式,2,;,表达式,3),语句,表达式,1;,while(,表达式,2,),语句,表达式,3;,表达式,2,语句,非,0,0,求解,表达式,1,求解,表达式,3,注意,到:,for,语句中的三个表达式都是可以省略,的。,如:,for(i=1;i100)break;,sum=sum+i;,i=1;,for(;i=100;i+),sum=sum+i;,for(i=1;i100)break;,sum=sum+i;,i+;,6.6,循环的,嵌套,P113.,1)while(),while(),2)do,do,while();,while();,3)for(;),for(;),4)while(),for(;),注意:内循环只是外循环的,循环体内的一个语句!,6.8 break,语句,和,continue,语句,1)break,:,跳出循环体,提前结束循环语句。,2)continue,:,结束本次循环,提前进入下一轮循环。,(执行一次循环体,叫做一轮循环。),例 从,1,开始累加自然数,直到和超过,8,为止,.,#include,void main(),int,i,sum,=0;,printf(i,sumn);/*,表头*,/,for(i,=1;,i8),break;,printf(%d,%,dn,i,sum,);,一,break,语句:,读程序,说出程序的功能和运行结果,.,break,:跳出循环体,提前结束循环语句。,二,continue,语句,例,6.5,输出,100200,之间不能被,3,整除的数。,#include,void,main(),int,n;,for(n=100;n=200;n+),if(n%3=0),continue;,printf(%-4d,n);,printf(n,);,读程序,说出程序的功能,.,continue,:结束本次循环,提前进入下一轮循环。,例,6.5,输出,100200,之间不能被,3,整除的数。,(,另法。,),#include,void,main(),int,n;,for(n,=100;n=200;n+),if(n%3!=0)printf(%-4d,n);,printf(n,);,回顾,:,三种,循环,语句,do,语句,while,(,表达式,),;,for(,表达式,1;,表达式,2,;,表达式,3),语句,while,(,表达式,),语句,6.9,常用循环算法举例,一 求序列的前,n,项或求级数的部分和,算法思路,:,求序列的前,n,项:求一项,输出一项,.(,利用前一项求下一项,),求级数的部分和:求一项,加一项,.(,利用前一项求下一项,),当序列或级数的,项,比较复杂的时候,可以分成,分子,、,分母,、,符号,三部分,分别计算,。,#include,void main(),float,sum=0,t,i;,for(,i,=1,t=1,;,i=20,;i+),t=t*i;,sum+=t;,printf(sum,=%,en,sum,);,Ex6.4,求,1!,+2!+3!+20!,的值,.,例,6.6,求,的近似值,直到最后一项的,绝对值,小于,10,-6,为止。利用公式:,/4=1,-,1/3+1/5,-,1/7+,#include,#include,void main(),float,s,n,t,pi,;,t=1;pi=0;n=1;s=1;,while(,fabs(t,)=1e-6,),pi=pi+t;,n=n+2;,/,分母,s=-s;,/,符号,t=,s/n,;,/,下一项,pi=pi*4;,printf(pi,=%f,n,pi,);,pi=3.141597,例,6.7,求,Fibonacci,数列,1,1,2,3,5,8,的前,40,项。其通项公式为:,农场里有一对兔子,,1,)从出生后第,3,个月起每个月都生一对小兔子,(,包括出生的这个月,),,,2,)而生出的每一对小兔子,也是从出生后,第,3,个月,起,每个月都生一对小兔子,,(,所有兔子永远不死,),则:每月的兔子数,为一个,Fibonacci,数列。,背景介绍,:,f,n,=,1 n=1,2,f,n-1,+f,n-2,n,3,题意分析:,通项公式:,f,n,=,1 n=1,2,f,n-1,+f,n-2,n3,1,)上个月原有的兔子数:,f,n-1,对。,2,),其中,上上个月已有的兔子(,f,n-2,对),,上上个月已有的兔子,本月,已成为老兔子,,,每对生出一对,。,即,这个月的新生兔子数为,f,n-2,对,!,3,)从而,上个月原有的兔子数:(,f,n-1,对),加上,这个月的新生兔子数(,f,n-2,对),即为本月的兔子总数。,例,6.7,求,Fibonacci,数列,1,1,2,3,5,8,的前,40,项。其通项公式为:,f,n,=,1 n=1,2,f,n-1,+f,n-2,n,3,f1=1,f2=1,for i=1 to,20,输出,f1,f2,f1=f1+f2,f2=f2+f1,#include,void main(),long,f1,f2;,int,i;,f1=1;f2=1;,for(i=1;,i=20,;i+),printf(%12,ld,%12,ld,f1,f2);,if(i%2=0),printf(n,);,f1=,f1,+f2;,f2=f2+,f1,;,二 筛选具有某性质的数,算法思路,:,判定数,m,是否具有此性质(,对于,复杂的性质,往往需要用,一段程序代码,来判定,),如果具有此性质输出,m.,例,6.5,输出,100-200,之间,不能被,3,整除,的数。,(,另法。,),#include,void,main(),int,n;,for(n,=100;n=200;n+),if(,n%3!=0,)printf(%-4d,n);,printf(n,);,二 筛选具有某性质的数,例,6.8,判断,m,是否为素数。,题意分析:,素数,m,:即除了自身,m,及,1,外没有真因子的自然数,2,m-1,中没有,m,的因子,(m=a*b,则,a,b,中至少有一个是不大于,m,的平方根的,),2,中没有,m,的因子,输出,m,不是素数,输出,m,是素数,k=,sqrt(m,),i=k+1,真 假,break,m%i,=0,真 假,for i=2 to k,输入整数,m,算法思路,:,判定数,m,是否具有此性质(,对于,复杂的性质,往往需要用,一段程序代码,来判定,),如果具有此性质输出,m.,算法分析,:,检验从,2,每一个数,i,都不是,m,的因子,.,例,6.8,判断,m,是否为素数。,P118,输出,m,不是素数,输出,m,是素数,k=,sqrt(m,),i=k+1,真 假,break,m%i,=0,真 假,for i=2 to k,输入整数,m,#include,#include,void main(),int,m,i,k,;,printf,(,输入整数,m(m,1):,),;,scanf(%d,&,m,);,k=,sqrt(m,);,for(i,=2;i=,k;i,+),if(m%i,=0)break;,if(i,=k+1),printf(%d,是素数,.,n,m,);,else,printf(%d,不是素数,.,n,m,);,例,6.9,求,100200,之间的全部素数。,算法分析:,显然只需把上题中的,m,从,100,取到,200,就可以了。,break,m%i,=0,真 假,for i=2 to k,输出,m,i=k+1,真 假,k=,sqrt(m,),for m=100 to 200,#include,#include,void main(),int,m,k,i,n=0;,for(m,=101;,m200,;,m=m+2,),k=,sqrt(m,);,for(i,=2;,i=k,;i+),if(m%i,=0)break;,if(,i,=k+1,),n+;,printf(%5d,m);,if(n%10=0)printf(n);,printf(n100200,之间共有,%d,个素数。,n,n,);,for m=101 to 200;m=m+2,ex6.7,一个数恰好等于它的因子和,则称它为完数:如,,6=1+2+3,。求,1-1000,之间的完数。输出格式为,:6 its factors are 1,2,3,#include,void main(),int,m,s,i,n,=0;,for(m,=1;m=1000;m+),s=0;,/,准备验证的条件开始,:,求因子和,for(i,=1;,i,m,;i,+),if(m%i,=0)s=,s+i,;,/,准备条件结束,if(,m,=s,),n+;,printf(%d,的因子是,:,m);,for(i,=1;,i,i=0;,while(,(,c,=,getchar,(),)!=n,),i+=c;,算法思路,:,获取,一个字符,处理一个字符,利用循环反复执行,.,关键问题,:,用什么函数,获取,一个字符,?,利用,(,c=,getchar,(),)!=n,作为,循环控制条件,可以,逐个获取,所输入字符串中的每个字符,再做相应处理。,例,6.10,译密码。,题意分析:,编密码规则:,A V,和,a v,的转换规则是,:c,对应,c+4,W X Y Z,和,w x y z,的转换规则是,:c,对应,c+4-26,输出字符,c,c=c-26;,是由,W-Z,或,w-z,转换的吗?,真 假,c=c+4;,c,是英文字母吗?,真 假,(c=,getchar,(),!=,n,UVWXYZABCDEFGHIJKLMNOPQRST,#include,void main(),char c;,while(,(c,=,getchar,()!=n,),if(c,=,a&c,=,A&c,Z&c,z),c=c-26;,printf(%c,c,);,printf(n,);,China!,Glmre,!,四 穷举法算法思路:利用循环将,所有可能情况,一一检验,挑出所有满足要求的情况。,例(百钱买百鸡),百钱买百鸡。鸡翁,1,钱值,5;,鸡母,1,钱值,3;,鸡雏,3,钱值,1;,何以百钱买百鸡,?,算法分析:,用穷举法检验所有可能情况:,公:,x,母:,y,小:,z,0 100 0,0 99 1,0 98 2 ,再进一步:,x,:,0-20 (5,元一只,最多买,20,只,),。,y,:,0-33,(,3,元一只,100,元最多买,33,只)。,z,:,z=100-x-y,(,z,由,x,y,所决定)。,输出,:(,x,y,z,),(5*x+3*y+z/3,=,100)&(z%3=0),真 假,z=100-x-y,for y=0 to 33,for x=0 to 20,例 程序:(百钱买,百鸡),#include,void main(),int,x,y,z;,printf,(,公鸡 母鸡 小鸡,n);,for(x,=0;x20;x+),for(y,=0;y33;y+),z=100-x-y;,if(x,*5+y*3+z/3=100&z%3=0),printf(%-6d%-6d%-6dn,x,y,z);,输出,:(,x,y,z,),(5*x+3*y+z/3,=,100)&(z%3=0),真 假,z=100-x-y,for y=0 to 33,for x=0 to 20,五,其他算法实例,Ex6.1,输入两个整数,m,和,n,,求其最大公约数和最小公倍数。,问题分析:,最小公倍数,q=m*n/,最大公约数,关键:求最大公约数,p=,(,m,n,),输入,m,n,m0=m,n0=n,将大数放在,m,中,n0,r=,m%n,;m=,n;n,=r;,输出最大公约数:,m,输出最小公倍数:,m0*n0/m,如,:(,64,,,24,),=,(,24,,,16,),=,(,16,,,8,),=,(,8,,,0,),=8,即,:,8,为,64,和,24,的最大公约数。,辗转相除法,求最大公约数:,(,m,n,)=m,当,n=0,=(,n,r,),当,n,0,其中,r=,m%n,(余数),Ex6.1,输入两个整数,m,和,n,,求其最大公约数和最小公倍数。,输入,m,n,m0=m,n0=n,将大数放在,m,中,n 0,r=,m%n,;m=,n;n,=r;,输出最大公约数:,m,输出最小公倍数:,m0*n0/m,#include,void main(),int,m,n,r,m0,n0;,printf(Enter,m,n(m0,n0):);,scanf(%d%d,&m,&n,);,m0=m;n0=n;,if(n,m)r,=m;m=n;n=r;,while(n,!=0)r=,m%n;m,=,n;n,=r;,printf(%d,和,%d,的最大公约数为:,%dn,m0,n0,m);,printf,(,最小公倍数为:,%dn,m0*n0/m);,辗转相除法,:,(,m,n,)=m,当,n=0,=(,n,r,),当,n,0,其中,r=,m%n,(余数),作业,:P129,Ex 6.2 6.3 6.5 6.6 6.10 6.11 6.15,五 显示有规律的由字符(如,星号)组成的图形算法思路:通常是用循环的嵌套。外循环控制星号的行数,在它的循环体内完成一排星号的打印。,*,*,例:写一个程序打印下列图形,for i=1 to N0,输出,D0-i,个空格,打印,2i-1,个星号,换行,#define N0 4,#define D0 30,#include,void main(),int,i,j,;,for(i,=1;i=,N0,;i+),for(j,=1;j=,D0-i,;j+)printf();,for(j=1;j=,2*i-1,;j+)printf(*);,printf(n,);,四 穷举法,例,2,谁做的好事?,师大,附中有四位同学中的一位做了好事,不留名,表扬信来了之后,校长问这四位是谁做的好事。,A说:不是我。,B说:是C。C说:是D。D说:他胡说。,已知三个人说的是真话,一个人说的是假话。现在要根据这些信息,找出做了好事的人。,分析,:m,代表做好事的人,A说:不是我。写成关系表达式为(,m,!=A),B说:是C。写成关系表达式为(,m,=C),C说:是D。写成关系表达式为(,m,=D),D说:他胡说。写成关系表达式为(,m,!=D),已知三个人说的是真话,:,即,上面,4,个表达式有三个是真的,!,用穷举法,:,对所有可能做好事的人,(m),一个一个检验:,A,B,C,D,,是否满足,4,个表达式有三个是真的,的条件,满足条件者是做好事的人,.,四 穷举法,例,2,谁做的好事?,(流程图),for m=A to D,输出,m,sum=,=3,sum=(,m,!=A)+/A的话是否为真,(,m,=C)+/B的话是否为真,(,m,=D)+/C的话是否为真,(,m,!=D);/D的话是否为真,A说:不是我。写成关系表达式为(,m,!=A),B说:是C。写成关系表达式为(,m,=C),C说:是D。写成关系表达式为(,m,=D),D说:他胡说。写成关系表达式为(,m,!=D),对所有可能做好事的人,(m),一个一个检验:,A,B,C,D,,是否满足,4,句话有三句是真的,的条件,满足条件者是做好事的人,.,例,2,程序,#include,void main(),char,m,;,/,放代表做好事的人的字符,int sum,g;,for(,m,=A;,m,=1,A、E、F三人中至少有两人参与作案;,A+E+F=2,A、D不可能是同案犯;,A+D=1,B、C或同时作案,或与本案无关;,(B+C=2)|(B+C=0),C、D中有且仅有一人作案;,C+D=1,如果D没有参与作案,则E也不可能参与作案。,!D&!E|D,例,3,程序,#include,void main(),int A,B,C,D,E,F;,/=0 没作案,=1 作案,int FLAG;,for(A=0;A=1;A+)for(B=0;B=1;B+),for(C=0;C=1;C+)for(D=0;D=1;D+),for(E=0;E=1;E+)for(F=0;F=1);,/A、B至少有一人作案,FLAG=FLAG,/A、E、F三人中至少有两人参与作案;,FLAG=FLAG,/A、D不可能是同案犯;,FLAG=FLAG,/B、C或同时作案,或与本案无关;,FLAG=FLAG,/C、D中有且仅有一人作案;,FLAG=FLAG,/如果D没有参与作案,则E也不可能参与作案,if(FLAG)printf(作案者是:n);,if(A=1)printf(A );if(B=1)printf(B );,if(C=1)printf(C );if(D=1)printf(D );,if(E=1)printf(E );if(F=1)printf(F );,printf(n);,例 由迭代法求立平方根,求,a,的近似立方根的迭代公式为:,x,n+1,=2/3(x,n,+a/3x,n,2,),要求前后两次求出的,近似立方根,xn,的差的绝对值小于,10,-5,。,输入,a,x=a /,初始根,x0=x,x,=,2/3(x0+a/3x0,2,),当,|x0-x|10,-5,为假时停止,输出近似根,x,#include,#include,void main(),float a,x0,x;,printf(Enter,a:);,scanf(%f,&a,);,x=a;,do,x0=x;,x=2.0/3.0*(x0+a/(3*x0*,x0,);,while(fabs(x-x0)=1e-5);,printf(%.2f,的近似立方根为,%.2fn,a,x);,例 由迭代法求立平方根,输出前面的所有近似根,.,#include,#include,void main(),float a,x0,x;int n=1;,printf(Enter,a:);,scanf(%f,&a,);,x=a;,printf(%.2f,的,%d,次近似根为,%.2fn,a,n,x);,do,x0=x;,x=2.0/3.0*(x0+a/(3*x0*,x0,);,n+;,printf(%.2f,的,%d,次近似根为,%.2fn,a,n,x);,while(fabs(x-x0)=1e-5);,#include,#include,void main(),float a,x0,x;,printf(Enter,a:);,scanf(%f,&a,);,x=a;,do,x0=x;,x=2.0/3.0*(x0+a/(3*x0*,x0,);,while(fabs(x-x0)=1e-5);,printf(%.2f,的近似立方根为,%.2fn,a,x,);,
展开阅读全文