1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第四章 循环结构,第一节 循环语句(,FOR,语句),第二节 当语句(,WHILE,语句),第三节 直到循环(,REPEAT,语句),第四节 多重循环结构,1,在实际应用中,会经常遇到许多有规律性的重复运算,这就需要掌握本章所介绍的循环结构程序设计。在,Pascal,语言中,循环结构程序通常由三种的循环语句来实现。它们分别为,FOR,循环,、,当循环,和,直到循环,。通常将一组重复执行的语句称为循环体,而控制重复执行或终止执行由重复终止条件决定。重复语句是由循环体及重复终止条件两部分组成。,2,第一节 循
2、环语句(,FOR,语句),3,for,语句的一般格式,for:=to do,;/,递增型循环,for:=downto do ;/,递减型循环,其中,for,、,to,、,downto,和,do,是,Pascal,保留字。表达式,1,与表达式,2,的值称为初值和终值。,循环的语句格式:,FOR,变量名,:=,初值,TO,终值,DO,语句;,求,1+2+3+N,的和。如何编程呢?,【,例,】,S,:,=0,;,FOR I,:,=1 TO 10 DO S,:,=S+I,;,Writeln,(,S=,,,S,);,4,For,语句执行过程,先将初值赋给左边的变量(称为循环变量);,判断循环变量的值是否
3、等于”终值,如已等于终值,则下次不再执行(本次是最后一次执行,循环变量的值也不更改),则跳到步骤;,如果小于等于终值,则执行,do,后面的那个语句(称为循环体);,循环变量递增(对,to,)或递减(对,downto),;,返回步骤;,循环结束,执行,for,循环下面的一个语句。,5,说明,循环变量必须是顺序类型。可以是整型、字符型、枚举型等,但不能为实型。,循环变量的值递增或递减的规律是:选用,to,则为递增;选用,downto,则递减。,循环体可以是一个基本语句,也可以是一个复合语句。,循环变量的初值和终值一经确定,循环次数就确定了。但是在循环体内对循环变量的值进行修改,常常会使得循环提前
4、结束或进入死环。所以禁止在循环体中随意修改控制变量的值。如:,for i:=1 to 10 do,begin,i:=2*i+1;/,禁止类似的修改,,Free Pascal,中会提示语法错误,writeln(i);,end;,以上,for,循环是一个死循环,,i,永远等于,2,,不可能达到终止值,10,。,for,语句中的初值、终值都可以是顺序类型的常量、变量、表达式。,6,应用举例,例,4.1,输出,1,100,之间的所有偶数。,程序如下:,Program ex4_1;,var,i:integer;,begin,for i:=1 to 100 do,if i mod 2=0 then wri
5、te(i:5);,end.,7,例,4.2,编程计算,1,到,100,的累加和:,s=1+2+3+100,。,【,分析,】,设,i,为循环控制变量,累加和放在,s,中,利用循环变量,i,的值从,1,变化到,100,的规律,不需要另外引进从,1,变化到,100,的其它变量,程序的流程图如,4-2,所示。,程序如下:,Program ex4_2;,var,s,i:integer;,begin,s:=0;,for i:=1 to 100 do,s:=s+i;,writeln(s);,end.,运行结果:,5050,只要对程序稍加修改就可以计算出以下算式的值:,s=1+1/2+1/3+1/100,s=
6、12+22+32+1002,s=2+4+6+100,等等。,8,例,4.3,将顺序打印出,26,个小写英文字母,:abczzcba,。,程序如下:,Program ex4_3;,var,k:char;,begin,for k:=a to z do,write(k);,for k:=z downto a do,write(k);,writeln;,end.,9,例,4.4,N,的阶乘是指,1,到,N,的累乘,即,N,!,=1*2*3*N,,输入一个数,求这个数的阶乘?,程序如下,:,Program ex4_4;,var,n,i:integer,;,/i,为循环变量,s:longint;/s,存放
7、阶乘的结果,类型为长整,型,防止结果太大,begin,readln(n);,s:=1;/,这条语句少了,选手们思考一,下,会出现什么现象,?,for i:=2 to n do /,从,2,到,n,累乘到,s,中,s:=s*i;,writeln(s);/,输出,n!,的值,end.,虽然,s,定义成,longint,,但输入,12,以上的数时,还是会出现错误的结果,说明结果超出了,longint,能够储存的范围,这时需要定义更大的类型,如,int64,,或干脆定义成实型变量用科学计数法来近似表示这个数,如,real,、,extended,。,10,上例中用到了“递推”算法。所谓递推算法是指在一个
8、数的序列值中,下一项的值在前一项的值的基础上推算出来的,即下一项对前一项有某种依赖关系。例如,为求,5!,,应先知道,4!,的值,然后再乘以,5,;为求,6!,必先求出,5,!。也就是说,从,1,!可以推出,2,!,从,2,!可以推出,3,!,从,3,!可以推出,4,!,以此类推。求,n!,的递推公式为:,a,1,=1(n=1),a,n,=n*a,n-1,(n1),a,1,=1,是“初始条件”或“边界条件”。只要找出递推关系,就可以由循环来处理,一项一项地推算出来以后各项。在程序中用同一个变量,s,来存储每一次推出来的值,由前一个,s,推出后一个,s,是递推。,11,例,4.5,已知一对兔子,
9、每个月可以生一对小兔,而小兔经过一个月生长后也可每月生一对小兔。即兔子的对数是:第一个月,1,对,第二个月,2,对,第三个月,3,对,第四个月,5,对,,,假设兔子的生育期是,12,个月,并且不死,问一年后,这对兔子有多少对活着的后代?,【,分析,】,根据题目给出的条件,得到算法:设当前月兔子有,x,对,它的前一个月有,lastx,对,前二个月有,prevx,对,明显存在一个递推关系,即,x=lastx+prevx,。,Program ex4_5;,Var i,lastx,prevx,x:integer;,begin,prevx:=1;,lastx:=2;,for i:=3 to 12 do,
10、begin,x:=lastx+prevx;,prevx:=lastx;,lastx:=x;,end;,writeln(x);,end.,运行结果:,233,12,例,4.6,一个两位数,x,,将它的个位数字与十位数字对调后得到一个新数,y,,此时,y,恰好比,x,大,36,,请编程求出所有这样的两位数。,【,分析,】,用,for,循环列举出所有的两位数,,x,为循环变量;,用公式,a:=x div 10,分离出,x,的十位数字;,用公式,b:=x mod 10,分离出,x,的个位数字;,用公式,y:=b*10+a,合成新数,y,;,用式子,y-x=36,筛选出符合条件的数,x,并输出。,Pro
11、gram ex4_6;,var a,b,x,y:integer;,begin,for x:=10 to 99 do,begin,a:=x div 10;,b:=x mod 10;,y:=b*10+a;,if y-x=36 then writeln(x);,end;,readln;,end.,13,例,4.7,把整数,3025,从中剪开分为,30,和,25,两个数,此时再将这两数之和平方,,(30+25)2=3025,计算结果又等于原数。求所有符合这样条件的四位数。,【,分析,】,设符合条件的四位数为,N,,它应当是一个完全平方数,用,(a*a),表示。,为了确保,N=(a*a),在四位数(,1
12、000,9999,)范围内,可确定,a,在,32,99,循环;,计算,N=a*a,;将四位数,N,拆分为两个数,n1,和,n2,;,若满足条件,(n1+n2)*(n1+n2),N,就输出,N,。,Program ex4_8,;,Var n,a,x,n1,n2:integer,;,begin,for a:=32 to 99 do,begin,n:=a*a,;,n1:=n div 100,;,/,拆取四位数的前两位数,n2:=n-n1*100,;,/,拆取四位数的后两位数,x:=n1+n2,;,if x*x=N then writeln(N),;,end,;,readln,end.,14,例,4.
13、9,根据公式,2/6=1+1/22+1/32+1/n2,,计算圆周率的,pai,值。,【,分析,】,此题是上例的一个变例,关键在于求出右边的累加和,变量,n,由键盘输入,,n,越大,圆周率的,pai,值就越精确。但是,,i,作为循环控制变量参加循环体的运算,它是整型数,那么当,i=182,时,,i*i,已经超过了正整数,32767,的范围,在,Pascal,系统里就把它变为,-65536+i*i,的整型数进行处理,当,i=256,时,,-65536+i*i,正好等于零,从面产生以零作除数的编译错误,所以我们在程序里应该把,i,定义为长整型,这样可以输入更大的,n(,不能大于,46341,,等于
14、65536,时,也会同样出现被,0,除的溢出错误,),。,Program ex4_9;,var i,n:integer;/,应该为,longint(,长整型,),pai,s:real;,begin,readln(n);,s:=0;,for i:=1 to n do,s:=s+1/(i*i),pai:=sqrt(6*s);,writeln(pai:8:6);,end.,运行结果:,输入:,1000,输出:,3.132077,输入:,10000,输出:,3.141497,15,【,上机练习,4.1】,1,、求,12+22+32+1002,2,、求,s=1+1/2+1/3+1/100,3,、计算,
15、100,之内所有的奇数之和。,4,、计算,n,!,其中,n,由键盘输入。,5,、求,10,个数中的最大值和最小值。,6,、按字母表的顺序,从字母,A,到,Z,顺序打印输出。,7,、求菲波拉契数列,a0,a1,a2,a20,。,a0=0,,,a1=1,,,a2=a1+a0,,,a3=a2+a1,,,,,an=an-1+an-2,;如,0,1,1,2,3,5,8,13,21,16,第二节 当语句(,WHILE,语句),17,WHILE,循环,对于,for,循环有时也称为计数循环,当循环次数未知,只能根据某一条件来决定是否进行循环时,用,while,语句或,repeat,语句实现循环要更方便。,wh
16、ile,语句的形式为:,while do,;,其意义为:当布尔表达式的值为,true,时,执行,do,后面的语句。,18,while,语句的执行过程为:,判断布尔表达式的值,如果其值为真,执行步骤,2,否则执行步骤,4;,执行循环体语句,(do,后面的语句,);,返回步骤,1;,结束循环,执行,while,的下一个语句。,说明:,这里,while,和,do,为保留字。当布尔表达式成立时,执行,do,后面的语句,(,循环体,),,当布尔表达式的值为,false,时,才结束循环,转去执行,while,语句的下一条语句,故又称此语句为“当”语句或“当型循环”。,while,语句的特点是:先判断,后执
17、行,。,19,例,4.10,求恰好使,s=1+1/2+1/3+1/n,的值大于,10,时,n,的值。,【,分析,】,恰好使,s,的值大于,10,意思是当表达式,s,的前,n-1,项的和小于或等于,10,,而加上了第,n,项后,s,的值大于,10,。从数学角度,我们很难计算这个,n,的值。故从第一项开始,当,s,的值小于或等于,10,时,就继续将下一项值累加起来。当,s,的值超过,10,时,最后一项的项数即为要求的,n,。,程序如下,:,Program ex4_10,;,Var s :real;,n :integer;/n,表示项数,begin,s:=0.0;,n:=0;,while s=1e-
18、6 do,begin,pai:=pai+t;,n:=n+2;,f:=-f;,t:=f/n;,end;,pai:=pai*4;,writeln(pai:10:8);,end.,运行程序会发现没有结果,为什么?因为布尔表达式,abs(t)=1e-6,,即,1/n=1e-6,,而程序的说明部分,n,是整型数,它的范围是,-32768,32767,,条件永远成立,所以形成死循环,从而没有运行结果。,while,循环不需要用顺序型数据来控制循环的次数,改程序的说明部分中的,n,为实型数或说明为长整型即可,,请同学们自己修正,,以后要对变量的取值范围引起重视。,22,【,上机练习,4.2】,1,、用,WH
19、ILE,循环完成如下,3,题:,求,s=1+2+3+4+10,求,s=1+1/2+1/3+1/100,计算,n,!,其中,n,由键盘输入。,2,、输入任一的自然数,A,B,求,A,B,的最小公倍数。,3,、小球从,100,高处自由落下,着地后又弹回高度的一,半再落下。求第,20,次着地时,小球共通过多少路程,?,4,、,Faibonacci,数列前几项为,:0,1,1,2,3,5,8,其规,律是从第三项起,每项均等于前两项之和。求前,30,项,并以每行,5,个数的格式输出。,5,、鸡兔同笼,头,30,脚,90,求鸡兔各几只?,23,第三节 直到循环(,REPEAT,语句),用,while,语句
20、可以实现“当型循环”,用,repeat-until,语句可以实现“直到型循环”。,repeat-until,语句的含义是:“重复执行循环,直到指定的条件为真时为止”。,直到循环语句的一般形式,:,Repeat,;,:,;,until;,其中,Repeat,、,until,是,Pascal,保留字,,repeat,与,until,之间的所有语句称为循环体。,24,说明:,repeat,语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体。,repeat-until,是一个整体,它是一个(构造型)语句,不要误认为,repeat,是一个语句,,until,是另一个语句。,repeat,
21、语句在布尔表达式的值为真时不再执行循环体,且循环体可以是若干个语句,不需用,begin,和,end,把它们包起来,,repeat,和,until,已经起了,begin,和,end,的作用。,while,循环和,repeat,循环是可以相互转化的。,25,例,4.13,求两个正整数,m,和,n,的最大公约数。程序采用,repeat-until,循环实现。,Program ex4_13;,var m,n,r :integer;,begin,readln(m,n);,repeat /,辗转相除法,r:=m mod n;,m:=n;,n:=r;,until r=0;,writeln(m);,end.,
22、26,例,4.14,校体操队到操场集合,排成每行,2,人,最后多出,1,人,;,排成每行,3,人,也多出,1,人,;,分别按每行排,4,5,6,人,都多出,1,人,;,当排成每行,7,人时,正好不多。求校体操队至少是多少人,?,【,分析,】,设校体操队为,X,人,根据题意,X,应是,7,的倍数,因此,X,的初值为,7,以后用,inc(x,7),改变,X,值;,为了控制循环,用逻辑变量,yes,为真,(True),使循环结束;,如果诸条件中有一个不满足,yes,的值就会为假,(false),,就继续循环。,Program ex4_14;,var x:integer;yes:boolean;,be
23、gin,x:=0;,repeat,yes :=true;inc(x,7);,if x mod 2 1 then yes:=false;,if x mod 3 1 then yes:=false;,if x mod 4 1 then yes:=false;,if x mod 5 1 then yes:=false;,if x mod 6 1 then yes:=false;,until yes;/,直到,yes,的值为真,writeln(All=,x);readln,end.,程序中对每个,X,值,都先给,Yes,赋真值,只有在循环体各句对,X,进行判断时,都得到“通过”(此处不赋假值)才能保持
24、真值。,27,例,4.15,求,1992,个,1992,的乘积的末两位数是多少?,【,分析,】,积的个位与十位数只与被乘数与乘数的个位与十位数字有关,所以本题相当于求,1992,个,92,相乘,而且本次的乘积主下一次相乘的被乘数,因此也只需取末两位参与运算就可以了。,Program ex4_15;,var a,t:integer;,Begin,a:=1;t:=0;,repeat,t:=t+1;,a:=(a*92)mod 100;,until t=1992;,writeln(a);,Readln;,End.,28,例,4.16,利用格里高公式求,。,/4=1-1/3+1/5-1/7+,,直到最后
25、一项的值小于,10-6,为止,.,【,分析,】,解本题的关键就是求右边数值序列的和,序列有明显的特点:分母是从,1,开始的奇数,加、减号轮流出现,因此,我们可以用,m=n+2,表示序列数值的变化,用,f=-f,来设置它们知项的符号位。,Program ex4_16;,var f:integer;n,t,pai:real;,begin,pai:=0;t:=1;n:=1;f:=1;,repeat,pai:=pai+t;,n:=n+2;,f:=-f;,t:=f/n;,until abs(t)trunc(sqrt(i)then write(i:8);,end;,end.,38,例,4.21,试编写能够
26、打印输出如下图形的程序:,#,#,#,#,#,#,#,#,程序如下:,Program ex4_21;,var i,j,k:integer;,begin,for i:=8 downto 1 do /,总共要输出,8,行内容,begin,for j:=1 to 8-i do write();/,控制每行空格数目,这个循环可以写成:,write(:8-i);,for k:=2*i-1 downto 1 do write(#);/,控制每行中的个数,writeln;,end;,end.,此程序的设计是由两个并列循环加一个嵌套循环构成的。各环的作用如下:,(,1,)外层环控制打印的行数,此倒三角形共,8
27、行,故外环的设置为递减型循环。,(,2,)嵌套在外环中的第一个并列循环为空格输出,根据图形变化控制输出不同数量的空格。,(,3,)外环内第二个并列循环为控制三角形每行中,#,号的个数。,39,例,4.22,验证哥德巴赫猜想:任一个充分大的偶数,N,(,N=4,),可以用两个素数之和表示。例如:,4=2+2,6=3+3,8=3+5,98=17+79,输入一个数,不是偶数则输出:“,is not even.”,,否则输出表示它的二个素数。,【,分析,】,哥德巴赫猜想是一个古老而著名的数学难题,它的理论证明很麻烦,迄今未得出最后证明。在这方面我国数学家陈景润的研究成果处于世界领先地位。这里只对有限
28、范围内的数用计算机加以验证,不算严格的证明。,充分大的偶数用,N,表示,将它分成,P,和,Q,,使,N,P+Q,。,P,从,1,开始(每次加,1,),,Q,N-P,。若,P,、,Q,均为素数,则输出结果,否则以,P+1,再试。,40,Program ex4_22;,var n,p,q,j:integer;,flagp,flagq:boolean;,begin,readln(n);,if n mod 2=0 then /,输入的是偶数,begin,p:=1;/p,从,1,开始枚举,repeat,p:=p+1;,q:=n-p;/n=p+q,flagp:=true;/,查看当前的,p,是不是素数,f
29、or j:=2 to trunc(sqrt(p)do,if(p mod j)=0 then flagp=false;,flagq:=true;/,查看当前的,q,是不是素数,for j:=2 to trunc(sqrt(q)do,if q mod j=0 then flagq:=false;,until flagp and flagq;/,直到所枚举的,p,、,q,是素数为止,writeln(p,q);,end,else,writeln(is not even.);/,输入不是偶数的情况,end.,41,【,上机练习,4.4】,1,、求,s=11+22+33+.+NN,2,、求,s=1+1/2
30、1/3!+1/10!,3,、输入一个整数,若是素数,输出“,YES”,,否则输出“,NO”,4,、任给一个自然数,n,,求出这个自然数不同因数的个数。,如:,n=6,时,因为,1,,,2,,,3,,,6,这四个数均是,6,的因数,故输出为,total=4,。,5,、输入一列图形(字母金字塔),a,a b,a b c,.,a b c y z,6,、把一张一元钞票换成一分,二分和五分的硬币,每种至少一枚。问有哪几种换法?,7,、百鸡问题:一只公鸡值,5,元,一只母鸡值,3,元,而,1,元可买,3,只小鸡。现有,100,元钱,想买,100,只鸡。问可买公鸡、母鸡、小鸡各几只?,42,8,、某人想
31、将手中的一张面值,100,元的人民币换成,10,元、,5,元、,2,元和,1,元面值的票子。要求换正好,40,张,且每种票子至少一张。问:有几种换法?应适当考虑减少重复次数。,9,、有一堆,100,多个的零件,若三个三个数,剩二个;若五个五个数,剩三个;若七个七个数,剩五个。请你编一个程序计算出这堆零件至少是多少个?,10,、编写一程序,验证角谷猜想。所谓的角谷猜想是:“对于任意大于,1,的自然数,n,,若,n,为奇数,则将,n,变为,3*n+1,,否则将,n,变为,n,的一半。经过若干次这样的变换,一定会使,n,变为,1,。”,11,、输入二个正整数,求出它们的最大公约数和最小公倍数。,12,、求,1-100,之间的所有素数(素数是大于,1,,且除,1,和它本身外,不能被任何其它整数所整除的整数)。,13,、哥德巴赫猜想(任何充分大的偶数都可由两个素数之和表示)。将,4-100,中的所有偶数分别用两个素数之和表示。输出为:,4=2+2,6=3+3,.,100=3+97,43,请维护编者版权,请勿将课件在网络上传播。,福建省长乐一中 董永建,浙江省温州中学 舒春平,2009,年,9,月,44,






