1、第四章 循环程序设计,本章内容: DO WHILE语句 FOR-ENDFOR语句 SCAN-ENDSCAN语句 多重循环,第一节 循环的概念,一、概念:循环是按照给出的条件去重复执行一段具有特定功能的程序。二、DO 语句格式: DO WHILE (语句行序列)LOOP(语句行序列)EXIT(语句行序列)ENDDO,F,T,功能:,说明:,1循环中DO WHILE和ENDDO必须成对出现,缺一不可。 2LOOP语句为可选项,它使计算机不执行LOOP后面的(语句行序列)而回到循环的开始DO WHILE位置,实际上它相当于一种特殊的循环终端语句。通常它被用于当遇到某个特殊的条件时,需要阻止执行循环体
2、内下面语句的场合,因此LOOP语句必须包括在IF-ENDIF或DO CASE-ENDCASE之间。 3EXIT语句为可选项,它使循环强行结束,而执行ENDDO下面的第一条语句。一般情况下,它用于遇到某个特殊的条件需要中途退出循环的场合。因此,EXIT语句也必须包括在IF-ENDIF或DO CASE-ENDCASE之间。,4、DO WHILE语句操作模式,一、循环次数已知INPUT “N=“ TO NI=1DO WHILE I=N做某件事情I=I+1ENDDO,例1: 1+2+3+4+100=? 思路:累加器S=S+I记数器I=I+1SET TALK OFFS=0 &累加器赋初值0I=1 &记数
3、器赋初值1DO WHILE I=100S=S+I &先进行累加I=I+1 &再进行记数。ENDDO ?“S=“,S RETU,问题一:I=0可以吗?,SET TALK OFFS=0I=0DO WHILE I100 I=I+1 &先记数S=S+I &再累加ENDDO ?“S=“,S RETU,问题二、累加器S=S+X中加数是灵活多变的,要视具体问题而言。,例1:偶数累加?奇数想加?S=S+2例2:仍然为累加,但加数递减。S=S-2例3:仍然为累加,但加数是一个表达式。S=S+AI可见:加数是一个增量,这个增量可为正数,也可为负数;可是整数,也可是小数;可是一个常量,也可是一个有规律变化的表达式。
4、,例2:打印1*1=1 1*2=2 1*3=3 1*4=4. . . 1*9=9 方式一:SET TALK OFFA=1B=1DO WHILE B=9C=A*B?STR(A,1)+“*“+STR(B,1)+“=“+STR(C,2)+“ “B=B+1ENDDO,方式二:将上述语句改为:A,COL()+4 SAY STR(A,1)+“*“+STR(B,1)+“=“; +STR(C,2)+“ “,例3:试判断一个数M是否为素数。,方法一:SET TALK OFFINPUT “M=“ TO MI=2S=.T.DO WHILE I=M-1IF M/I=INT(M/I)S=.F.EXITENDIFI=I+
5、1ENDDO,IF S?M,“是素数“ELSE?M,“不是素数“ENDIFRETU,方法二:SET TALK OFFINPUT “M=“ TO MI=1A=0 &用A变量统计整除次数,其初值为零DO WHILE I=MIF M/I=INT(M/I)A=A+1 &每当I能被M整除,则累计一次整除次数ENDIFI=I+1ENDDOIF A=2?M,“是素数“ELSE?M,“不是素数“ENDIFRETU,B、利用结束标记,跳出循环。(永真循环)置初值DO WHILE .T.INPUT “X=“ TO XIF X=结束标记EXITENDIF做某件事情ENDDO,例1:试编一程序,将若干个数累加,当输入
6、“0”时结束累加。,分析:本程序是循环次数未知的问题。利用永真循环来完成此类程序。),*遇到结束标记停止累加模块SET TALK OFFS=0DO WHILE .T. INPUT “X=“ TO X IF X=0 EXIT ENDIF S=S+X ENDDO? “S=“,SRETU,例2:选举问题。,SET TALK OFF STORE 0 TO Z,W,L,Q DO WHILE .T.WAIT “请输入选择(1:张三,2:李四,3:王五,0:结束,其余放弃)“ TO XIF X=“0“EXITENDIFDO CASECASE X=“1“Z=Z+1CASE X=“2“W=W+1CASE X=“
7、3“L=L+1OTHERQ=Q+1ENDCASE ENDDO,?“张三的选票“,Z,“张“ ?“李四的选票“,L,“张“ ?“王五的选票“,W,“张“ ?“弃权票数为“,Q,“张“RETU,C、对表进行操作USE 表名置初值 DO WHILE .NOT.EOF() 做某件事情 SKIP ENDDO,例1:试编一程序,按表格形式打印工资表。(分析:表格有几部分:标题 2、顶线 3、表头内容 4、中割线及记录 5、尾线本程序数据从表中取得,应先打开表,然后打印表头。利用循环打印表中数据,由于表中数据是变化的,所以循环条件应为“.NOT.EOF()”,这样无论表中有多少条记录,均循环打印出来。)程序
8、见教材P130,例2:在RS表中统计女高级工程师的人数有多少,并依次显示每个女高级工程师的姓名及年龄、职称的情况。SET TALK OFF USE RSCLEARN=性别=“女“.and.职称=“高级工程师“COUNT FOR &N TO M? “我单位有女高级工程师“+STR(M,2)+“名“WAITLOCATE FOR &N,DO WHILE .NOT.EOF()CLEAR5,10 SAY “姓名“ GET 姓名7,10 SAY “年龄“+STR(YEAR(DATE()-YEAR(出生日期),2)9,10 SAY “职称“ GET 职称WAITCONTENDDORETU,D、做某件事情,次
9、数未知,直到用户不希望做为止。 置初值 JX=“Y“ DO WHILE UPPER(JX)=“Y“ 做某件事情 WAIT “继续(Y/N)?“ TO JX ENDDO,例1:(教材P131面)例18:进一步完善,使查找一 张凭证后,可以继续查找,直到不希望查找为止。分析:将例11程序放在一个循环中即可多次查找,由于查找的次数未知,查到即结束循环,所以循环应每次认证,由用户认证,希望继续查找打“Y”,否则选择“N”。程序见教材P131,例2、在屏幕上设计自选格式输入记录。SET TALK OFFUSE RSCLEARJX=“Y“DO WHILE UPPER(JX)=“Y“APPE BLANK3,
10、10 SAY “姓名“ GET 姓名5,10 SAY “性别“ GET 性别7,10 SAY “职称“ GET 职称READWAIT SPACE(30)+“继续输入吗(Y/N)?“ TO JXENDDORETU,E、其他模式例1:假定某一年的工业生产总值为P,平均增长率为C%,问过多少年工业生产总值可以翻一番?SET TALK OFFINPUT “当年工业生产总值“ TO PINPUT “年增长率“ TO CP1=PI=0DO WHILE P1=2*PP1=P1*(1+C*0.01)I=I+1ENDDO?“过“+STR(I,2)+“年,工业生产总值可以翻一番?“RETU,二、FOR循环语句格式
11、:FOR 内存变量= TO STEP (语句行序列)LOOP(语句行序列)EXIT(语句行序列)ENDFOR,功能:内存变量的初值是,终值是,每次的增量是,该循环从开始,每次增加或减少,直到的值为止,即跳出循环。它与DO WHILE语句的区别是,不需要置初值,并且循环体中不需要指定累计方式。,例1:用语句改写累加程序:,N个数累加SET TALK OFFINPUT “输入欲累加数个数“ TO NS=0FOR I=1 TO N STEP 1INPUT “X=“ TO XS=S+XENDFOR? “S=“,SSET TALK ONRETURN,结论: (用FOR语句完成程序,程序结构简单,逻辑清晰
12、,所以对于循环次数已知的循环,应使用本语句。 ),例2:1*2+2*3+N*(N+1)SET TALK OFFINPUT “N=“ TO NS=0FOR I=1 TO N S=S+I*(I+1)ENDF?“S=“,SRETU,例3:1!+2!+3!+. . . .+N!SET TALK OFFINPUT “N=“ TO NS=0T=1FOR I=1 TO N T=T*IS=S+TENDF?“S=“,SRETU,例4:有菲氏数列,前面两位数为0,1,从第三位开始每位数为前两位之和,试编程显示出前50位数字。方式一:SET TALK 0FFA=0B=1?A,BFOR I=3 TO 50C=B+A?
13、CA=BB=CENDFRETU,方式二:SET TALK OFFDIMEN A(50)A(1)=0A(2)=1FOR I=3 TO 50A(I)=A(I-1)+A(I-2)ENDFFOR I=1 TO 50?A(I)ENDFRETU,例5:找出10000以内的同构数。正整数n若是它平方数的尾部,则称n为同构数。(例如,6是其平方数36的尾部,76是其平方数5776的尾部,6与76都是同构数。 试求指定位数的同构数序列。)方法一:SET TALK OFFFOR I=1 TO 10000S=I*I-IA=LEN(LTRIM(STR(I) &求I的位数IF S/10A=INT(S/10A)?“I=“
14、,IENDIFENDFORRETU,三、SCAN语句格式:SCAN 范围 FOR 条件1 WHILE 条件2(语句行序列)LOOP(语句行序列)EXIT(语句行序列)ENDSCAN功能:本语句对打开的表进行循环操作,它从表指定的范围开始,每处理一条后将指针向下移动到满足条件的一条记录,直到遇到表结束标志。,三、SCAN语句操作模式USE 表名置初值 SCAN FOR 条件 做某件事情 ENDSCAN,例1:用SCAN语句改写打印工资表的程序,并打印基本工资大于120元的记录,程序如下: SET TALK OFFUSE GZ SET PRINT ON? SPACE(13)+“工 资 表“ ? S
15、PACE(13)+“-“?“?“编 号 姓 名 基本工资补助工资应发工资扣款 实发工资“ SCAN FOR JBGZ120 ?“ “ ? “+编号+“+姓名+“+STR(基本工资,8,2)+“+STR(补助工资,8,2)+“+STR(应发工资,8,2)+“+STR(扣;款,6,2)+“+STR(实发工资,8,2)+“ ENDSCAN,?“? “SET PRINT OFF RETURN从本例中可以看出,用本循环语句对表循环,特别简练,所以对于表的循环,应使用语句。,例2:对PZK.DBF表中所有金额大于1000元的记录加200元,如果记录号超过80就停止操作。SET TALK OFFUSE PZ
16、KSCAN FOR 金额1000IF RECNO()=80EXITENDIFREPLACE 金额 WITH 金额+200DISPENDSCAN,四、 多重循环,例1:请编程完成下图*,SET TALK OFF FOR I=1 TO 5?SPACE(I+2)FOR J=1 TO 8? “*“ENDF ENDF RETU,例2:请编程完成下图,*,SET TALK OFF FOR I=1 TO 4?SPACE(6-I)FOR J=1 TO 2*I-1? “*“ ENDF ENDF RETU,例3:请编程完成下图,1 2 3 4 5 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1
17、 2 3 4,SET TALK OFF FOR N=1 TO 5A=NFOR M=1 TO 5?AA=A+1A=IIF(A5,1,A)ENDF? “ ENDF RETU,提问:改变图形,如何改变程序?,5 4 3 2 14 3 2 1 53 2 1 5 42 1 5 4 31 5 4 3 2,SET TALK OFF FOR N=5 TO 1 STEP -1A=NFOR M=5 TO 1 STEP -1?AA=A-1A=IIF(A1,5,A)ENDF?“ ENDF RETU,例4:找出1000以内的完备数。(所谓完备数是一个数,它等于它的各个因子之和。)SET TALK OFFFOR I=2
18、TO 1000S=0FOR J=1 TO I-1IF INT(I/J)=I/JS=S+JENDIFENDFIF I=S?I,“是一个完备数“ENDIFENDF RETU,例5:找出0-999之间的所有“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。(例如,153=1*3+5*3+3*3,故153是水仙花数。)(分析:本问题有1000个数需遍历判断,所以需要三重循环。分别控制百位数、十位位数、个位数,最内层循环执行一千次,每次均判断该数是否为水仙花数。),* 找水仙花数模块SET TALK OFFFOR X=0 TO 9 & 百位数循环FOR Y=0 TO 9 & 十
19、位数循环FOR Z=0 TO 9 & 个位数循环S1=X*100+Y*10+ZS2=X*3+Y*3+Z*3IF S1=S2 ?“X=“,X,“Y=“,Y,“Z=“,ZENDIFENDFORENDFORENDFORSET TALK ON,例6:有W,O,N,E,T,W五个数,他们满足:ONE+ ONE , 求这五个数。(选学)TWO分析:1、O不大于5且O0再进一步O为偶数,所以O为2或42、E只能为1,2或6,73、T为4,8,5,9,SET TALK OFF FOR O=2 TO 4 STEP 2FOR N=0 TO 9FOR E=1 TO 7IF E=1.OR.E=2.OR.E=6.OR.E=7FOR T=4 TO 9IF T=4.OR.T=5.OR.T=8.OR.T=9FOR W=0 TO 9S1=O*100+N*10+ES2=T*100+W*10+OIF S2=2*S1? STR(S1,5)? “+“+STR(S1,4)?REPL(“-“,10)?STR(S2,5)ENDIF,ENDFENDIFENDFENDIFENDFENDF ENDF RETU,总结:本章介绍三种循环语句,先将它们的用处用表格总结如下:,