《第四讲循环结构的Fortran程序设计.ppt》由会员分享,可在线阅读,更多相关《第四讲循环结构的Fortran程序设计.ppt(25页珍藏版)》请在三一办公上搜索。
1、2023/6/23,1,第四讲 循环结构程序设计,循环结构在程序设计中广泛使用,是一种非常重要的程序结构。其基本思想是重复,即重复执行某些语句、以完成大量的计算要求。但是,循环不是简单的重复,因为尽管每次都执行相同的语句,但是在循环过程中变量在变化,而且完成了循环次数或在一定的条件下能退出循环。本讲介绍Fortran90实现循环结构的2种方法:1、do循环结构;2、do while循环结构。,循环次数事先可以确定下来,用do语句实现循环,非常方便。比如,当x=1、2、3、10时,分别计算lnx和sinx的值,用do循环实现的程序如下:,2023/6/23,2,1 用do语句实现循环,Integ
2、er xDo x=1,10,1Print*,x,log(x*1.0),sin(x*1.)End doEnd,2023/6/23,3,一、do循环的一般格式,do i=e1,e2,e3(do语句)循环体(执行的操作)end do(结束语句),其中:(1)i代表循环变量(可为整型或实型);(2)e1,e2,e3称为参数表达式,分别为循环变量的初值、终值和步长;(3)循环体是循环过程被重复执行的语句组;(4)end do是循环结束的终端语句,其与do语句配合使用。,2023/6/23,4,说明:,(1)步长为1时,表达式e3可以省略。比如“do i=1,10,1”与“do i=1,10”相同。,(3
3、)参数表达式“i=e1,e2,e3”表示循环次数为:r=max(int(e2-e1+e3)/e3),0)比如:do i=10,1,-2的循环次数r=5,而do i=10,1,2的r=0(即不循环),注意:1、步长不能为0;2、循环次数不能为0。,2023/6/23,5,二、do循环的执行过程,(1)循环体指do语句和end do语句之间的语句,不包括do语句,因此do语句在循环过程中只执行一次。如果循环参数表达式中含变量,那么即使在循环体中改变变量的值,循环参数并不改变。比如:,Integer a,b,c,Ia=1;b=7;c=2Do i=a,b,c+1a=2;b=b+a;c=c*iPrint
4、*,i,a,b,cEnd doEnd输出为:1 2 9 2 4 2 11 8 7 2 13 56,进入do循环后,首先计算出循环变量i的初值1、终值7、步长3(即执行do语句),尽管在循环体中改变了变量a、b、c的值,但是循环变量的初值、终值、步长不再变化。,2023/6/23,6,(2)由于在循环过程中,循环变量会自动按循环要求变化,因此不能在循环体内给循环变量进行赋值。,Integer iDo i=1,5,2i=i+1Print*,iEnd doEndError for3598:assignment to Do variable i detected between i and=,(3)由
5、于每循环一次循环变量自动增加一个步长的值,因此退出循环后循环变量的值,比最后一次循环时循环变量的值多1个步长。,Integer i,mDo i=1,10,2m=iEnd doPrint*,i,mEnd输出为:11 9,三、do循环举例,例1:输入x、n,计算输出:,分析:累加项可表示为递推Fi=Fi-1*x/i,用赋值语句F=F*x/i来实现。重复加是循环操作,程序为:,2023/6/23,7,Integer n,iReal x,F,yRead*,x,nF=1.0Y=1.0Do i=1,nF=F*x/iY=Y+FEnd doPrint*,x=,x,n=,nWrite(*,*)y=,yEnd从键
6、盘输入:3,3 输出为:x=3.0 n=3 y=13.0,2023/6/23,8,例2:输入一个整数,判断并输出是否为完数(除自身外所有因子之和等于本身的数),比如6=1+2+3,所以6是完数。,分析:因为找一个整数的因子及求它们的和可以用循环来实现,而用选择结构可进行判断与输出其是否为完数,程序为:,Integer m,i,sumRead*,mSum=0Do i=1,m/2!求除本身之外的因子及之和If(mod(m,i).eq.0)sum=sum+iEnd doif(m.eq.sum)thenWrite(*,*)m,”是完数”ElsePrint*,m,不是完数End ifend,2023/6
7、/23,9,例3:找出3位整数中全部的水仙花数。,分析:利用do循环逐一判断3位整数100,999中哪些是水仙花数,并输出,程序为:,Integer m,m1,m2,m3,nDo m=100,999 m1=m/100m2=mod(m/10,10)m3=mod(m,10)n=m1*3+m2*3+m3*3If(n.eq.m)Print*,m,是水仙花数End doend,2023/6/23,10,比如:求两个整数m和n的最大公约数和最小公倍数。,分析:最大公约数在1,min(m,n)范围内,且同时能被m和n整除,因此利用do i=min(m,n),1搜寻,一旦mod(m,i)=0、mod(n,i)
8、=0则此时的i就是最大公约数,并利用exit退出循环。然后利用最大公约数,求出最小公倍数。程序为:,2023/6/23,11,Integer a,b,t,iread*,a,bif(ab)thent=aa=bb=tend ifDo i=a,1,-1if(mod(a,i)=0.and.mod(b,i)=0)thenprint*,g=,iexitend ifend doprint*,l=,a*b/i!求最小公倍数End比如:12,9 g=3,l=36,注意:在程序中,do语句中的内容省略,表示循环条件永远成立。当x为偶数时执行cycle语句-直接执行下一次循环。当x大于100时,执行exit语句-跳
9、出循环体。,2023/6/23,12,(2)cycle语句,Cycle语句是用来结束本次循环,即跳过循环体中尚未执行的语句。在循环结构中,cycle语句将使控制直接转向循环条件的测试部分,从而决定是否继续执行循环。,Cycle语句与exit语句的区别在于:cycle语句只是结束本次循环,而不是终止整个循环的执行。Exit语句则是结束所在循环,跳出所在循环体。,例如:求1100中全部奇数之和。,Integer:x=0,y=0dox=x+1if(mod(x,2)=0)thencycleelse if(x100)thenexitelsey=y+xend ifend doprint*,yEnd,202
10、3/6/23,13,2 用do while语句实现循环,对于循环次数确定的循环问题,使用do循环是比较方便的。但是,有些循环问题事先是无法确定循环次数的,只能通过给定的条件来决定是否继续循环。这时可以使用do while语句来实现循环。,一、do while循环的一般格式,do while(条件表达式)(do while语句)循环体(执行的操作)end do(结束语句),其中:(1)表示循环的条件表达式,要用括号括起来;(2)循环体是在循环过程中被重复执行的语句组;(3)end do是循环结束的终端语句,do while语句与end do语句要配合使用。,2023/6/23,14,比如:rea
11、l:p=1.0do while(P0)print*,pread*,pend doEnd该程序输出所输入的全部正数,直到输入负数或零,程序结束。,(4)对于循环次数确定的循环问题也可以使用do while语句来实现,比如:求5!,integer:m=1,n=1do while(m=5)n=n*mm=m+1end doprint*,nEnd,2023/6/23,15,二、do while循环的执行过程,(1)当给定的条件满足时,执行do while和end do之间的循环体语句;(2)语句执行完毕后,程序自动返回到do while语句,再一次判断do while语句中的条件。(3)如果条件仍然满足
12、,则再执行一遍循环体语句,如果条件不满足,则结束循环,去执行end do后的语句。,2023/6/23,16,三、do while循环举例,例1:输入一个整数,输出其位数。,分析:输入的整数存入变量m中,用变量n来统计m的位数,程序为:,Integer:m,n=0read*,mDo while(m0)n=n+1m=m/10end doprint*,n=,nEnd比如:129 n=3,2023/6/23,17,分析:这种累加求和的问题,关键是如何求累加项,通常的办法是利用前一项来求后一项,即利用递推法来求累加项。,例2:求,直到最后一项的绝对值小于106时,停止计算。X右键盘输入。,real x
13、,a,sinteger:i=1read*,xs=xa=xdo while(abs(a)=1.0e-6)i=i+1a=-x*x/(2*i-2)/(2*i-1)*as=s+aend doprint*,x,sEnd,2023/6/23,18,3 Fortran循环结构程序设计的其它问题,一、do循环与do while循环的互换,Do循环和do while循环是Fortran90中常用的2种基本循环结构,前者主要用于确定循环次数的问题、而后者则常用来处理事先无法确定循环次数的问题,但也并非绝对,很多情况下二者可以互换使用。比如:输入一个整数,判断是否为素数。,分析:所谓素数指这样的整数:除了1和本身不
14、能被其它任何数整除的数。判断一个数是否为素数,可以按照2,3,m-1逐一检查能否除下,但当m很大时检查量太大。有一个结论:只需检查2,3,m1/2即可判断m是否为素数。这个问题既可用do循环实现,也可利用do while来解决,程序分别为:,2023/6/23,19,implicit noneinteger m,i,jread*,mj=sqrt(real(m)do i=2,jif(mod(m,i).eq.0)exitend doif(ij.and.m1)thenprint*,m,是素数elseprint*,m,不是素数end ifEnd,implicit noneinteger m,i,jre
15、ad*,mi=2j=sqrt(real(m)do while(ij.and.m1)thenprint*,m,是素数elseprint*,m,不是素数end ifEnd,2023/6/23,20,二、循环的嵌套,如果循环体中又包括一个循环结构,就称为循环的嵌套,也叫多重循环结构。在设计多重循环时,要特别注意内、外循环之间的关系,以及各语句放置的位置,不能搞错。,比如:求100,200以内的全部素数。,分析:分两步:(1)判断一个数是否为素数的程序段(见前面的例子);(2)利用穷举法将判断一个数是否为素数的程序段,对指定范围内的每一个数都执行一遍,即可求出该范围内的所有素数了。,implicit
16、noneinteger m,i,jlogical zcdo m=101,200,2 zc=.true.i=2 j=sqrt(real(m)do while(i=j.and.zc)if(mod(m,i).eq.o)zc=.False.i=i+1 end do if(zc)then print*,m,是素数 end ifEnd doend,2023/6/23,21,分析:该问题要求对5个x值、10个y值,计算出50个F值。然后每10个F值求和得到5个S值。再5个S值连乘得出M的值。可用二重循环实现:每个S由10个F累加,M由5个S累乘得到。X和Y有明显的规律,可用循环变量得到。,real:x,y,
17、F,s,M=1.0integer i,jdo i=1,5 x=i*2.0 s=0.0 do j=1,10 y=j/10.0 F=sqrt(x*2+y*2)s=s+F end do M=M*sEnd doprint*,M=,MEnd输出结果:M=4.107494E8,2023/6/23,22,4 循环结构程序设计上机,1、已知,分别求:(1)当n取1000时,S的值;【7.852727E-1】(2)S0.78时的最大n值和此时n值对应的S值;【0.7799640;23】(3)求S的值,直到累加项小于104为止。【7.817278E-1】,2、甲、乙、丙三球迷分别预测已进入半决赛A、B、C、D四对
18、的名次,甲预测:A第一、B第二,乙预测:C第一、D第三,丙预测:D第二、A第三。结果每人的预测只对了一半,试问真正的名次应该是怎样?【3、2、1、4】,本讲学习了“重复操作、完成大量计算”的循环结构程序设计问题,包括do循环和do while循环。知道了2种循环结构的编写格式、执行过程及其使用。还明白在do循环的循环体中可加入控制语句,比如exit语句和cycle语句的使用,以及二者之间的互换,循环的嵌套等。,2023/6/23,23,integer i,nreal s,xs=0.0n=1000do i=1,n x=2.0/(4*i-3)/(4*i-1)s=s+xEnd doprint*,s=
19、,send,integer i,nreal s,xs=0.0i=1do while(s0.78)x=2.0/(4*i-3)/(4*i-1)s=s+x i=i+1End don=i-2s=s-xprint*,s=,s,n=,nend,递推、迭代法,integer i,nreal s,xs=0.0i=1x=2.0/(4*i-3)/(4*i-1)do while(x=1E-4)s=s+x i=i+1 x=2.0/(4*i-3)/(4*i-1)End don=i-2s=s-xprint*,s=,send,穷举法,2023/6/23,24,3、某些分子和分母都是二位数的真分数,分子的个位数与分母是十位数
20、相同,而且奇怪的是:如果去掉分子的个位数和分母的十位数字,结果与原分数值一样。试求出所有这样的真分数。,integer fz,fm,fz1,fz2,fm1,fm2do fz=10,99do fm=10,99 fz1=fz/10 fz2=fz-fz1*10 fm1=fm/10 fm2=fm-fm1*10 if(fz.ge.fm)cycle if(fz2.ne.fm1)cycle if(fm2.eq.0)cycle if(fz*fm2.ne.fm*fz1)cycle print*,分子,fz,分母,fmEnd doend doend,【16/64、19/95】【26/65、49/98】,2023/6/23,25,integer a,b,c,dlogical L!L为逻辑型变量do a=1,4 do B=1,4 if(B=A)cycle!两队不允许相同名次,取下一个B值 do c=1,4 if(c=a.or.c=b)cycle!取下一个C值 d=10-a-b-c!四对名次总和为10 L=(a=1).neqv.(b=2).and.(c=1)&.neqv.(d=3).and.(d=2).neqv.(a=3)if(L)print*,A,B,C,D=,a,b,c,d end do end doEnd doend,穷举法,