在实际应用中,只有前面的几种分支结构是远远不够的,如需要执行某种重复性的操作,可以利用Visual FoxPro提供的循环结构程序设计来完成。Visual FoxPro提供了3种循环流程控制结构,分别为:当型循环结构、步长型循环结构和扫描型循环结构。
格式:
DO WHILE <条件>
[<语句>]
[EXIT]
[LOOP]
ENDDO
说明:
(1)<条件>可以是条件表达式或逻辑常量。根据<条件>的逻辑值进行判断,如果<条件>的值为.T.,则执行DO WHILE和ENDDO之间的循环体;如果<条件>的值为.F.,则结束循环,而去执行ENDDO之后的命令。每执行一遍循环体,程序自动返回到DO WHILE语句,判断一次<条件>。
(2)<语句>是指定<条件>为真时执行的那组命令,即循环体。
(3)EXIT是无条件结束循环命令,使程序跳出DO WHILE…ENDDO循环,而去执行ENDDO后的第一条命令。EXIT只能在循环结构中使用,但是可以放在DO WHILE… ENDDO中的任何地方。
(4)LOOP控制直接返回到DO WHILE语句,而不执行LOOP和ENDDO之间的命令。因此LOOP称为无条件循环命令,只能在循环结构中使用。
(5)DO WHILE...ENDDO必须各占一行。每一个DO WHILE都必须有一个ENDDO与其对应,即DO WHILE和ENDDO必须成对出现。
当型循环结构的根本特点是,当所给定循环条件为真时,就反复执行其循环体;当该条件为假时,则终止执行其循环体,而去执行其后继命令。显然,若它的循环初始条件已为假,则并不执行其循环体,故它的循环体执行次数最少可为0次。
使用当型循环结构可以事先并不清楚循环的次数,但应知道什么时候结束循环的执行。为使程序最终能退出DO WHILE命令引起的循环,在没有使用EXIT的情况下,在每次程序的循环过程中必须修改程序给出的循环条件,否则程序将永远退不出循环,这种情况称作无限循环或死循环。在程序中要避免出现无限循环。
【例5-16】用DO WHILE语句编写程序,求从1到1000的和。
SET TALK OFF
CLEAR
I=1
sum=0
DO WHILE I<=1000
sum=sum+I
I=I+1
ENDDO
? "从1到1000的和是:",sum
RETURN
这是一个典型的累加程序,即反复地在先前相加的基础上再加上一个新的数。
【例5-17】打开指定的数据表,然后进行“浏览”、“修改”、“追加”和“退出”操作。
SET TALK OFF
CLEAR
ACCEPT "请输入打开的数据表:" TO T_DBF
USE &T_DBF
DO WHILE .T.
CLEAR
TEXT
1.浏览 2.修改
3.追加 0.退出
ENDTEXT
?
WAIT "请选择(0-3):" TO TN
DO CASE
CASE TN="1"
GO TOP
BROWSE NOMODIFY
CASE TN="2"
INPUT "请输入要修改的记录号:" TO JN
GO JN
EDIT
CASE TN="3"
APPEND
LIST
CASE TN="0"
EXIT
OTHER
WAIT "您选择错误,按任意键重新选择!"
ENDCASE
ENDDO
CLOSE ALL
RETURN
【例5-18】在学生档案表(xsda.dbf)中,依次显示性别为男的学生,并统计出男生的总人数。
set talk off
clear
use xsda
do while !eof()
if 性别=.F.
SKIP
LOOP
ENDIF
DISPLAY 编号,学号,姓名,性别,年龄,出生年月
SKIP
ENDDO
COUNT FOR 性别=.T. TO T_no
? "以上显示的是男生的基本档案,共计有:"+STR(T_no,3)+"人"
CLOSE ALL
RETURN
运行结果如下:
若事先知道循环次数,则可以使用步长型循环(FOR...ENDFOR)结构。步长型循环可以根据给定的次数重复执行循环体。
格式:
FOR <内存变量> = <初值> TO <终值> [STEP <步长值>]
[<语句>]
[EXIT] &&退出
[LOOP] &&跳到FOR语句执行
ENDFOR | NEXT
说明:
(1)<内存变量>是一个作为计数器的内存变量或数组元素,在FOR...ENDFOR执行之前该变量可以不存在。<初值>是计数器的初值,<终值>是计数器的终值,<步长值>是计数器值的增长或减少量。如果<步长值>是负数,则计数器被减小。如果省略STEP子句,则默认<步长值>是1。<初值>、<终值>和<步长值>均为数值型表达式。
(2)<语句>指定要执行的一个或多个Visual FoxPro命令。
(3)EXIT跳出FOR...ENDFOR循环,而去执行ENDFOR后面的命令。可把EXIT放在FOR...ENDFOR中的任何地方。
(4)LOOP将控制直接转回到FOR子句,而不执行LOOP和ENDFOR之间的命令。
(5)FOR命令和ENDFOR | NEXT命令必须各占一行,且必须成对出现。
循环的执行过程是开始时首先把初值、终值和步长值读入,然后再对内存变量的值与终值进行比较,如果内存变量的值在初值与终值范围内,则执行FOR与ENDFOR之间的命令,然后内存变量按步长值增加或减小,重新比较,直到内存变量的值不在初值与终值范围内,结束循环,而去执行ENDFOR后面的第一条命令。如果在FOR...ENDFOR之间改变<内存变量>的值,将影响循环执行的次数。
<语句>中可以嵌套控制结构的命令语句(IF、DOCASE、DO WHILE、FOR、SCAN)。“步长型”循环结构是当型循环结构衍生出来的一种特殊变型。
【例5-19】用FOR…ENDFOR语句求出1~200之和以及25~300之间的奇数之和。
SET TALK OFF
CLEAR
S=0
M=0
FOR I=1 TO 200
S=S+I
NEXT
@ 10,10 SAY "1到200之和为:"+LTRIM(STR(S))
FOR J=25 TO 300 STEP 2
M=M+J
ENDFOR
@ 12,10 SAY "25到300中奇数之和为:"+LTRIM(STR(M))
RETURN
执行结果为:
【例5-20】用FOR…ENDFOR语句绘制图案。
SET TALK OFF
CLEAR
FOR I=1 TO 10
FOR J=1 TO 5
@ J,I+J SAY "*"
@ J,22-J SAY "**********"
ENDFOR
ENDFOR
运行结果如下:
SCAN循环是为操作数据库记录设计的循环,这个循环语句在一般高级语言中没有。现在提到这个命令是为了秉承本部分知识系统性,因为还没有讲到数据库的问题,读者暂时可以跳过这一节,在学完数据库操作的相关知识后再来学习这个内容。
格式:
SCAN [NOOPTIMIZE] [<范围>] [FOR <逻辑表达式1>] [WHILE <逻辑表达式2>]
[<语句>]
[EXIT] &&退出
[LOOP] &&跳到SCAN语句执行
ENDSCAN
功能:在指定范围内,扫描满足记录的给定条件,执行相应的语句。
【例5-21】利用表扫描型循环语句,显示语文成绩大于等于85分的学生记录。
SET TALK OFF
CLEAR
USE XSCJ
SCAN
DISPLAY 编号,学号,姓名,语文,数学,外语,政治FOR 语文>=85
ENDSCAN
RETURN
执行结果为:
【例5-22】利用循环语句编写九九乘法表的程序。
CLEAR
TA=1
DO WHILE TA<=9
TB=1
?
DO WHILE TB<=TA
?? SPACE(2)+STR(TA,1)+"×"+STR(TB,1)+"="+STR(TA*TB,2)
TB=TB+1
ENDDO
TA=TA+1
ENDDO
RETURN
运行结果如下: