1、第九章,结构化程序设计,2018/10/12,2,9.1 程序设计基础 9.2 顺序结构程序 9.3 分支结构程序 9.4 循环结构程序 9.5 程序的模块化,2018/10/12,3,使用计算机解决实际问题,通常是先要对问题进行分析并建立数学模型,然后考虑数据的组织方式和算法,并用某一种程序设计语言编写程序,最后调试程序,使之运行后能产生预期的结果。这个过程称为程序设计。,9.1 程序设计基础,9.1.1 程序设计的概念,2018/10/12,4,9.1.2 结构化程序设计方法,结构化程序设计采用自顶向下、逐步求精和模块化的分析方法。,自顶向下是指对设计的系统要有一个全面的理解,从问题的全局
2、入手,把一个复杂问题分解成若干个相互独立的子问题,然后对每个子问题再作进一步的分解,如此重复,直到每个问题都容易解决为止。,逐步求精是指程序设计的过程是一个渐进的过程,先把一个子问题用一个程序模块来描述,再把每个模块的功能逐步分解细化为一系列的具体步骤,以致能用某种程序设计语言的基本控制语句来实现。,在编制一个较复杂的程序时,大致可分为5个步骤: 1审题 2划分处理模块 3数据库结构的设计 4画流程图 5编写程序,2018/10/12,5,任何复杂的程序都由3种基本控制结构组成。它们是顺序结构、选择结构和循环结构。,图9.1程序的控制结构,9.1.3结构化程序的控制结构,2018/10/12,
3、6,9.1.4 程序文件的建立与执行,VF程序文件又称命令文件,其扩展名为.prg。,(1) 命令方式 格式1:MODIFY COMMAND 命令文件名|? 格式2:MODIFY FILE 文件名|? 功能:调用内嵌文本编辑器,建立或修改一个指定的命令文件。,2菜单方式建立编辑程序文件,1命令方式建立或修改程序文件,(2) 菜单方式 操作步骤: 从“文件”菜单中选择“新建”菜单选项。 在“新建”对话相中选择“程序”单选按钮。 单击“新建文件”按钮。 说明: 修改命令文件时,首先从FILE菜单中选择OPEN菜单选项,然后在文件名的文本框中键入待修改的命令文件名,再单击打开按钮即可在编辑窗口打开该
4、文件。,2018/10/12,7,(1) 命令方式 格式: DO 程序文件名 功 能 : 将程序文件从磁盘调入内存, 编译成.FXP目标文件后并执行。 说明:当命令文件名的扩展名缺省时,系统按如下顺序搜索并执行的这些程序:可执行文件(.EXE)、应用程序(.APP)、编译后的目标程序文件(.FXP)和程序文件(.PRG)。,2.程序文件的执行,(2) 菜单方式 操作步骤: 在“程序”/“运行”,出现对话框。 在“执行文件”的文件名输入框中直接键入命令文件名,或在文件列表中单击所需命令文件名。 单击“运行”按钮。 终止程序运行: .CANCEL:终止程序运行,清除所有的私有变量,返回命令窗口。
5、.RETURN:结束程序执行,返回调用它的上级程序,若无上级程序则返回命令窗口。 .QUIT:结束程序执行并退出Visual.FoxPro系统,返回操作系统。,2018/10/12,8,9.2 顺序结构程序,顺序结构是最简单、最基本的一种程序结构。在顺序结构程序中,各命令按照各自出现的先后顺序,依次执行。,例92 在学生.dbf表中显示第一条记录的姓名、性别、出生日期、数学、外语成绩,* FILENAME E9_2.PRG SET TALK OFF CLEAR USE 学生 DISPLAY 姓名,性别,出生日期,数学,外语 USE SET TALK ON RETURN,2018/10/12,9
6、,其流程图如右图所示。,A,B,C,N,图中箭头表示程序执行的方向,方框代表不同的可执行语句。,2018/10/12,10,9.2.1 程序文件中的辅助命令,1、程序注释命令 格式1:NOTE|* 注释 开头代码注释行 格式2:& 注释 命令行后代码注释行 功能:对程序进行说明,对运行结果不会产生任何影响。,2、清屏命令,格式: CLEAR 功能:清除屏幕上所有显示内容,将光标置于屏幕左上角。,3、 常用状态设置命令,(1)置会话状态命令 格式: SET TALK ON|OFF,2018/10/12,11,说明:在会话状态开通时,Visual FoxPro在执行命令时会向用户提供大量的反馈信息
7、。程序调试时,一般置“会话”于开通状态,而在执行程序时则通常要求置“会话”于断开状态。,(2)置打印状态命令 格式: SET PRINT ON|OFF 说明:系统默认打印机置于断开状态,执行结果只送到屏幕,不送往打印机。反之,则在屏幕上显示的执行结果被同时打印。,(3)置屏幕状态命令 格式: SET CONSOLE ON|OFF 说明:在系统的默认状态下,用户从键盘输入的内容都在屏幕上显示,然而有时却要求键入的内容保密而不被显示,这只需使用命令SET CONSOLE OFF便可。,2018/10/12,12,(4)置缺省驱动器和目录命令 格式: SET DEFAULT TO 盘符:路径 说明:
8、用于设置进行输入输出操作时的缺省驱动器和缺省目录,9.2.2 交互式输入命令,1. 字符串接收命令 格式: ACCEPT TO 功能:暂停程序执行,将键盘输入的字符串送入指定内存变量后再继续运行。,说明: 若给出提示信息选项,将输出提示信息,否则不输出任何信息。其中可以是字符型内存变量、字符串常量或合法的字符表达式。 本命令只接收字符串,输入时该字符串不需要使用定界符,其长度不能超过254个字符。本命令以回车作为结束符。,2018/10/12,13,例9.3 在学生表中,从键盘上输入任意一个学生的学号查询学生的姓名、性别、出生日期、数学、外语成绩。,* FILENAME E9_3.PRG CL
9、EAR SET TALK OFF USE 学生 ACCEPT “请输入待查学生的学号:“ TO xh LOCATE FOR 学号=xh DISP 学号,姓名,性别, 出生日期,数学,外语 USE SET TALK ON RETURN,2018/10/12,14,2任意数据输入命令 格式:INPUT TO 功能说明: 提示信息选项同ACCEPT命令。 INPUT命令可以接收字符型、数值型、日期型及逻辑型数据。字符串的输入必须用定界符括起来,输入数值或表达式,不加任何定界符;输入日期型数据,除使用日期型的格式外,还要用大括号将其括起来。本命令以回车作为结束符。 INPUT命令不允许在没有输入任何内
10、容的情况下直接按回车。,2018/10/12,15,例9.4 输入圆半径计算圆面积。,* FILENAME E9_4.PRG NOTE 已知半径求圆面积 SET TALK OFF CLEAR STORE 3.14 TO P INPUT “请输入圆的半径: “ TO P SP*R2 ?“半径是“+LTRIM(STR(P)+“的圆面积是:“ ?S SET TALK ON,2018/10/12,16,3. 单个字符接收命令 格式: WAIT TO WINDOW NOWAIT TIMEOUT 功能:暂停程序执行,等待用户键入任何一个字符后继续。,*Filename E9_5.prg SET TALK
11、0FF USE 学生 CLEAR LIST NEXT 10 SKIP WAIT WINDOW &在屏幕右上角的窗口内显示提示信息 LIST NEXT l0 USE SET TALK ON,例9.5 学生表学生.DBF中含20条记录,分两屏输出,2018/10/12,17,4. 三种键盘输入命令的比较,5. 基本输出命令 格式: ?|?, 功能:在屏幕上输出表达式的信息,?与?的区别在于:?在当前光标的下行首列输出信息,?在当前光标当前位置输出。,2018/10/12,18,1. 格式输出命令 格式: SAY 功能:在屏幕指定的行列处显示表达式的值。 说明: 指定了输出的位置。屏幕左上角为0,0
12、,有下角为屏幕最大行数-1,屏幕最大列行数-1, 行、列都可为表达式,还可为小数。,9.2.3 格式输入输出命令,2. 格式输入命令 格式: SAY GET READ 功能:SAY命令与READ命令结合,在屏幕上指定行列处显示并允许修改一个内存变量或字段变量的值。,2018/10/12,19,说明: SAY子句用于显示提示信息,GET子句用于为变量输入新值。 GET子句中的变量必须有确定的初值。初值决定了该变量的类型和宽度。 激活CET变量是指使该变量进入编辑状态,让光标自动跳到该变量值所在位置上等待编辑修改。,2018/10/12,20,例:9.7 从键盘上任意输入两个数据,要求用格式化语句
13、完成。,* FILENAME E9_7.PRG SET TALK OFF CLEAR A=0 &表示变量A仅仅可以输入整数 B=0.00 &表示变量B仅仅可以输入实数,小数位为两位 4,10 SAY “请输入第一个整数:” GET A 6,10 SAY “请输入第二个实数:” GET B READ C=A+B 8,10 SAY STR(A)+”+”+ALLT(STR(B,10,2)+”=”+ALLT(STR(C,10,2) SET TALK ON RETURN,2018/10/12,21,根据逻辑条件是否满足来转向不同的程序去执行,这就构成了分支结构。,9.3 分支结构程序,.F.,1单分支语
14、句 (IFENDIF)简单分支语句的格式:IF ENDIF 功能说明:若条件为真则执行IF到ENDIF 中间的语句为假,则从ENDIF下条语句执行。,2018/10/12,22,例9.8 从键盘上输入任意两个数据,请按照从大到小的顺序输出,* FILENAME E9_8.PRG SET TALK OFF CLEAR INPUT “请输入第一个数据:” TO A INPUT “请输入第二个数据:” TO B IF AB &满足条件两个数据发生交换,否则不执行条件语句C=AA=BB=C ENDIF ?A,B SET TALK ON RETURN,2018/10/12,23,ACCEPT “输入要查
15、询学生的学号:” TO XH CJ=“该生数学成绩低于60分” &变量CJ用于存放是否及格的信息USE 学生表LOCATE FOR 学号=XHIF 数学=60CJ=“该生数学成绩60分以上”ENDIF?CJUSE(演示:利用MODI COMM命令生成一个.PRG文件,用DO命令执行),例: 在“学生表.DBF”表文件中,按学号查询某个学生平时成绩是否及格。,2018/10/12,24,格式:IF ELSEENDIF功能说明:若条件为真,执行命令序列1, 然后执行ENDIF的后继命令。如果条件为 假,且有ELSE子句,执行命令序列2,然 后执行ENDIF的后续命令,若无ELSE子句, 则直接转到
16、ENDIF之后。,2双分支结构(IFELSEENDIF),注: (1) IF和ENDIF必须配对使用,而ELSE可选。 (2) IF、ELSE、ENDIF必须各占一行。 (3) 可以为关系表达式、逻辑表达式。 (4)在语句序列1和语句序列2中可以嵌套IF语句。,2018/10/12,25,例9.9 从键盘接收一个字符,如果是小写字母,将其以大写字母后输出,其他字符直接输出。,* FILENAME E9_9.PRG SET TALK OFF CLEAR WAIT “请输入一个字符: “ TO L IF L=a AND L=z ?UPPER(L) ELSE ?L ENDIF SET TALK ON
17、,2018/10/12,26,ACCEPT “输入要查询学生的学号:” TO XHUSE 学生表LOCATE FOR 学号=XHIF 数学=60CJ=“数学成绩60分以上”ELSECJ=“数学成绩低于60分”ENDIF?CJUSE,例: 用选择分支语句,重新编写上例的程序。,2018/10/12,27,SET TALK OFF INPUT “请输入所用电量:“ TO DL IF DL=50 DF=DL*0.5 ELSE DF=50*0.5+(DL-50)*0.8 ENDIF ? “应缴电费为:” + LTRIM(STR(DF,10,2) + “元“ SET TALK ON RETURN,* F
18、ILENAME E9_11.PRG SET TALK OFF INPUT “请输入所用电量:“ TO DL DF=IIF(DL=50,0.5*DL,0.5*50+0.8*(DL-50) ? “应缴电费为:” + LTRIM(STR(DF,10,2) + “元“ SET TALK ON RETURN,例9.10 请用分支结构语句编程计算电费:不超过50度,每度0.5元;超过50度时,超出部分每度0.8元。,结论:条件函数IIF同样具有逻辑判断功能,2018/10/12,28,SET TALK OFFINPUT “请输入行李重量:“ TO W IF 1YF=0.22*W ELSEYF= 0.22*
19、40 + 1 ENDIF? “应交托运费为:“+LTRIM(STR(YF,10,2)+“元“ SET TALK ON RETURN,例 火车托运行李: 每人不超过40公斤,每公斤0.22元;超过40公斤时, 超出部分每公斤0.40元。填空完成以下程序。,W 40,(W-40) * 0.4,2018/10/12,29,9.3.3多分支结构,DO CASECASE 条件表达式1语句序列1CASE 条件表达式2 语句序列2CASE 条件表达式n语句序列nOTHERWISE 语句序列n+1 ENDCASE,2018/10/12,30,功能:系统依次测试语句中各个条件表达式的值: 若为真,即执行相应条件
20、表达式后的语句序列, 然后脱离情况语句,执行ENDCASE的下一语句。若所有的条件表达式的值均为假,则执行OTHERWISE后面的语句序列, 然后脱离情况语句,执行ENDCASE下一语句 。,说明: DO CASE和第一个CASE子句之间不能插入任何语句。 DO CASE和ENDCASE必须配对使用,且DO CASE,CASE,OTHERWISE和ENDCASE各子句必须各占一行。 在语句序列中可嵌套情况语句。,2018/10/12,31,例 9.12 输入任意一个百分制成绩,输出对应的5分制成绩,其对应关系如下:优(100百分成绩90)、良(90百分成绩80)、中(80百分成绩70)、及格(
21、70百分成绩60)或不及格(百分成绩60)。,CLEAR SET TALK OFF INPUT “请输入百分制成绩:“ TO CJ DO CASECASE CJ=90dj=“优“CASE CJ=80dj=“良“CASE CJ=70dj=“中“CASE CJ=60dj=“及格“OTHERWISEdj=“不及格“ ENDCASE ?5成绩等级为:+ dj SET TALK ON,2018/10/12,32,例9.13 在学生表中,从输入键盘上输入任意一个学生的学号,查找该学生,如有则显示他的数学成绩所属的等级,否则显示没有该学生。,* FILENAME E9_13.PRG SET TALK OFF
22、 CLEAR USE 学生 ACCEPT “请输入需要查询学生的学号:” TO A LOCATE FOR 学号=A IF FOUND( ) DO CASE CASE 数学=90 ?学号,姓名,数学,“优秀” CASE 数学=80 ?学号,姓名,数学,“良好” CASE 数学=70 ?学号,姓名,数学,“中等” CASE 数学=90 ?学号,姓名,数学,“及格”OTHER,?学号,姓名,数学,“不及格”ENDCASEELSE ?”无该学号的学生!” ENDIFUSE SET TALK ON RETURN,2018/10/12,33,例9.14 从键盘上任意输入一个字符,判断所输入的字符类型(数字
23、字符、大写英文字符、小写英文字符、空格字符或其他字符),* FILENAME E9_14.PRG SET TALK OFF CLEAR WAIT “请输入任意一个字符:” TO A DO CASE CASE A=”0” AND A=”A” AND A=”a” AND A=”z”WAIT “小写英文字符”+A+”!”CASE A=” ” WAIT “空格字符”+A+”!”OTHERWISEWAIT “其他字符”+A+”!” ENDCASE SET TALK ON RETURN,2018/10/12,34,例 阅读下列程序段,写出运行结果:,A=3000 DO CASECASE A=1000B=A
24、CASE A=2000B=2*ACASE A=3000B=3*A ENDCASE ? B,2018/10/12,35,循环,就是按给定的条件连续地重复执行一段特定功能的程序。循环结构也称为重复结构。,9.4 循环结构程序,Visual FoxPro给出了三种循环结构: 条件循环(DO WHILEENDDO) 计算循环(FORENDFOR) 扫描循环(SCANENDSCAN),2018/10/12,36,DO WHILE LOOPEXIT ENDDO,循环体,ENDDO后的语句,条件,.T.,.F.,条件循环结构流程图,9.4.1 DO WHILE循环,循环体,条件,2018/10/12,37,
25、(1) 系统执行该语句时,先判断循环开始DO WHILE的条件是否成立, 如果条件为真,则执行循环体中的语句序列。当执行到ENDDO时,返回到DO WHILE,再次判断条件是否为真,以确定是否再次执行循环体。若条件为假,则结束循环 ,执行ENDDO后面的语句。 如果第一次判断条件时,条件即为假,则循环体一次都不执行,这就是称为“先判断后执行”的语句。 (2)循环体中的LOOP是可选项。遇到LOOP时,不再执行后面的语句,转回DO WHILE处重新判断。其作用相当于一个特殊的“短路”返回控制。 (3)循环体中的EXIT也是可选项。遇到它时便无条件地退出循环,转到ENDDO后面的语句。其作用相当于
26、一个紧急出口。 (4)通常LOOP或EXIT出现在循环体内嵌套的分支语句中,根据条件来决定是LOOP回去,还是EXIT出去。,功能说明:,2018/10/12,38,在以循环变量作为循环控制参数的条件循环中, 循环体内一定要有修改循环变量的语句,否则就会出现死循环。,注意,2018/10/12,39,例 求自然数1至4的和。,分析算法:,1. i=1 , s=0 ;,2. 累加第 i 个数,3. 累加次数加1,4. 当 i= 4 重复做2 ;,5. ? s 。,2018/10/12,40,例 求自然数1至4的和。,SET TALK OFF,S=0,&定义一个变量表示和,并初始化,&指定以循环次
27、数作判断条件,S=S+i,&把S的值加上i后再赋给S,即求和,&修改循环变量,? S,&输出求和的结果,SET TALK ON,RETURN,&设置循环变量的初值,2018/10/12,41,S=0,i=1,1=4,S=0+1,i=1+1,.T.,2=4,S=1+2,i=2+1,3=4,S=3+3,i=3+1,4=4,S=6+4,i= 4+1,5=4,.F.,? 10,SET TALK OFF S=0 i=1 DO WHILE i=4S=S+ii=i+1 ENDDO ? S SET TALK ON RETURN,2018/10/12,42,若求自然数1至N的和呢?,程序:求自然数1至4的和,S
28、ET TALK OFF,S=0,i=1,INPUT 请输入N的值: TO N,DO WHILE i=4,S=S+i,i=i+1,ENDDO,?S,SET TALK ON,RETURN,i=N,推广1,2018/10/12,43,若求自然数1至N的积呢?,程序:求自然数1至N的和,SET TALK OFF,S=0,i=1,INPUT 请输入N的值: TO N,DO WHILE i=N,S =S + i,i =i + 1,ENDDO,?S,SET TALK ON,RETURN,推广2,S=1,S=S*i,2018/10/12,44,例 阅读程序,并说出程序的运行结果,程序结果,2,3,4,5,6,
29、程序结果,2,4,5,6,E,E,2018/10/12,45,例 求1100以内所有奇数的和。,SET TALK OFF S=0 I=0 Do while I100I = I + 1If int(I/2) = I/2LoopendifS = S + I Enddo ? “1到100的奇数和 S= ”, S SET TALK ON Return,以循环变量作为控制参数控制循环。,S=0 I=1 Do while I100 S = S + II = I + 2 Enddo ? s,程序改进:,2018/10/12,46,例9.17 求数学常量的近似值,精确到10-6。,SET TALK OFF C
30、LEAR T=1 S=1 I=1 DO WHILE .T. S=S+1/T I=I+1 T=T*I IF 1/T1E-6EXIT ENDIF ENDDO ?“E=“,STR(S,8,6) SET TALK ON RETURN,2018/10/12,47,例:显示“学生表.DBF”文件中性别为“男”的学生记录。要求用DO WHILE循环编写程序。程序文件内容如下:,SET TALK OFFCLEARUSE 学生表DO WHILE .NOT.EOF()IF 性别=“女”SKIPLOOPENDIFDISPLAY FIELDS 学号,姓名,性别,专业SKIPWAITENDDOUSESET TALK O
31、NRETURN,2018/10/12,48,例9.18 在学生表中,输出所有学生的数学成绩所属的等级。,* FILENAME E9_18.PRG SET TALK OFF CLEAR USE 学生 DO WHILE NOT EOF( ) DO CASE CASE 数学=90 ?学号,姓名,数学,“优秀” CASE 数学=80 ?学号,姓名,数学,“良好” CASE 数学=70 ?学号,姓名,数学,“中等” CASE 数学=90 ?学号,姓名,数学,“及格”OTHER ?学号,姓名,数学,“不及格”ENDCASESKIP ENDDOUSE SET TALK ON,2018/10/12,49,例
32、求连乘数1*2*3*4*,当积大于720时退出程序。,Set talk off Clear S=1 I=1 Do while .T.S = S * I I = I + 1 Enddo ? “ S= ”, S Set talk on Return,循环控制条件恒为真,要使用EXIT语句结束循环,2018/10/12,50,例:读下面程序,分析该程序实现的功能。 SET TALK OFF CLEAR USE GZ DO WHIL !EOF( ) IF 基本工资=800SKIPLOOP ENDIF DISPLAY SKIP ENDDO USE RETURN,2018/10/12,51,语句格式:FO
33、R XA TO B STEP C LOOPEXITENDFOR | NEXT,9.4.2 FOR循环,循环体,功能说明:重复执行FORNEXT(或ENDFOR)之间的N次。 其中: N=(-+1)/ 若为1,则STEP 可以省略。,循环变量,循环初值,步长值,循环终值,2018/10/12,52,例 求1100之和。,SET TALK OFF Clear S=0 for I=1 to 100 S = S + I Endfor ? “S = ”, S SET TALK ON Return,若求100的阶乘呢?,思考1,2018/10/12,53,例 求1100之奇数和。,SET TALK OFF
34、 Clear S=0 for I=1 to 100 step 2S = S + I Next ? “S = ”, S SET TALK ON Return,若求1100的偶数和呢?,思考2,2018/10/12,54,例 阅读程序,写出程序运行结果,思考3 若改成EXIT?,2018/10/12,55,例9.21 求水仙花数。所谓水仙花数是指一个三位数,其各位数字的立方和等于该数本身。如153=13+53+33,*求任意三位数I是否是水仙化数,如是输出 A=I%10 &求个位B=INT(I/10%10) &求十位C=INT(I/100) &求百位IF I=A3+B3+C3?IENDIF,CLE
35、ARFOR I=100 TO 999A=I%10B=INT(I%100/10)C=INT(I/100)IF I=A3+B3+C3?IENDIF ENDFOR RETURN,CLEAR SET TALK OFF FOR I=1 TO 9 FOR J=10 TO 9 FOR K=0 TO 9 IF 100*I+10*J+K=I3+J3+K3? 100*I+10*J+KENDIFENDFORENDFOR ENDFOR SET TALK ON RETURN,2018/10/12,56,循环嵌套(多重循环),循环体内又设置循环的情况称为多重循环,又称为循环嵌套。 内外循环的层次必须分明,不允许有交叉现象
36、出现。 循环结构可以与分支结构嵌套,同样不允许有交叉现象出现。,以下交叉情形不允许出现:,2018/10/12,57,语句格式:SCAN FOR LOOPEXITENDSCAN,9.4.3 SCAN循环,循环体,功能:在指定的范围内,依次对满足条件的记录执行相应的操作。,2018/10/12,58,2018/10/12,59,例9.23 在学生表中,输出所有学生的数学成绩所属的等级。用SCANENDSCAN循环,* FILENAME E9_23.PRG SET TALK OFF CLEAR USE 学生 SCAN DO CASE CASE 数学=90 ?学号,姓名,数学,“优秀” CASE 数
37、学=80 ?学号,姓名,数学,“良好” CASE 数学=70 ?学号,姓名,数学,“中等” CASE 数学=90 ?学号,姓名,数学,“及格”OTHER ?学号,姓名,数学,“不及格”ENDCASEENDSCANUSE SET TALK ON RETURN,2018/10/12,60,CLEARSTORE 0 TO x,yUSE 学生SCAN FOR 少数民族否IF 性别=“男“x=x+1ELSEy=y+1ENDIFENDSCAN? “少数民族男生有:“+STR(x,2)+“人“? “少数民族女生有:“+STR(y,2)+“人“USERETURN,例9.23 对学生表统计少数民族男、女生人数。
38、,2018/10/12,61,9.4.4 程序举例,SET TALK OFF CLEAR DO WHILE .T. INPUT “请输入一个数据:” TO AIF A=0 AND A=20EXITENDIF ENDDO S=1 FOR J=1 TO A S=S*J ENDFOR ?A,”的阶乘为”,S SET TALK ON RETURN,例9.25 从键盘上输入任意一个大于0而小于等于20的整数,求该数的阶乘。,2018/10/12,62,例:判断一个数是否是素数,INPUT “N=“ to N FLAG=.T. K=INT(SQRT(N) J=2 DO WHILE J=K AND FLAG
39、IF N%J=0FLAG=.F.ENDIF J=J+1 ENDDO IF FLAG?N ,”是素数!” ELSE? N ,”不是素数!” ENDIF,2018/10/12,63,例9.26:求21000中所有的素数,SET TALK OFF CLEAR FOR N=2 TO 1000 FLAG=.T. & 假设该数为素数,FLAG标志为.T. K=INT(SQRT(N) J=2 DO WHILE J=K AND FLAG IF N%J=0 FLAG=.F. & 2K之间的任何整数整除N,则N不是素数,FLAG=.F. ENDIF J=J+1 ENDDO IF FLAG ?N ENDIF END
40、FOR SET TALK ON RETURN,2018/10/12,64,9.5 程序的模块化,结构化程序设计方法通常将一个复杂的规模较大的程序系统划分为若干个功能相关又相对独立的一个个较小的模块,再把这些模块划分为更小的用几十行语句实现的简单模块。将一个应用程序划分成一个个功能简单、单一的模块程序,不仅便于程序的开发,也利于程序的阅读和维护。,模块是一个相对独立的程序段,它可以被其他模块所调用,也可以去调用其他模块。通常,把被其他模块调用的模块称为子程序或叫过程。把调用其他模块而没有被其他模块调用的模块称为主程序。在Visual FoxPro中,模块可以是命令文件,也可以是过程。,2018/
41、10/12,65,9.5.1 子程序、过程和自定义函数,1、子程序 子程序的调用 格式:DO | WITH 功能:在命令文件中调用执行指定的子程序。其中,WITH 子句指定传递到程序或过程的参数,在中列出的参数可以是表达式、内存变量、常量、字段名或用户定义函数。可把参数放在圆括号中,各参数用逗号分隔。传递给一个程序的参数最多为24个。,(2) 返回主程序语句,格式:RETURN TO MASTER|TO 功能:中止该子程序的执行,返回到调用它的程序,从调用该子程序的下一条语句继续执行。,2018/10/12,66,说明: 若程序是被另一个程序调用的,遇到RETURN时,则自动返回到上级调用程序
42、。 选用TO MASTER子句时,则返回到最高一级调用程序,即在命令窗口下,调用的第一个主程序。 在程序最后,如果没有RETURN命令,则程序运行完后,将自动默认执行一个RETURN命令,但过程文件除外。 执行RETURN命令时,释放本程序所建立的局部变量,恢复用PRIVATE隐藏起来的内存变量。 TO 表示将控制权交给指定的程序。 RETURN 表示将表达式的值返回调用程序,用于自定义函数。,2018/10/12,67,例9.27 求1!+2!+3!+.+10!=?,* 主程序,E9_27.PRG SET TALK OFF CLEAR S=0 FOR I=1 TO 10 T=1 DO SUB
43、 S=S+T ENDFOR ?“ 1!+2!+3!+.+10!=“,S SET TALK ON,*以下为子程序,文件名为SUB.PRG FOR J=1 TO IT=T*J ENDFOR RETURN,2018/10/12,68,2. 自定义函数,(1)自定义函数的结构 格式: FUNCTION PARAMETERS RETURN ,用户自定义函数是除系统提供的函数外,用户自己定义的某些具有特殊功能的函数,它能增强用户编程的灵活性和通用性。,(3) 子程序的嵌套调用,主程序可以调用子程序,子程序还可以调用另外的子程序,这就是子程序的嵌套调用。每个被调用程序的末尾或返回处都要加上RETURN命令。
44、,2018/10/12,69,说明: FUNCTION 表示一个函数定义的开始,同时给函数命名。自定义函数不能作为一个独立的程序文件,而只能放在某程序中。 不能用内部函数名来命名自定义函数。 若自定义函数中包含自变量,程序的第一行必须是参数定义命令PARAMETERS。 自定义函数除了可以作为一个函数被其它程序调用外,还可用DO 的形式来执行。 自定义函数的数据类型取决于RETURN语句中的数据类型。如果省略,则返回.T.。,(2)自定义函数的调用,调用形式:(),自变量可以是任何合法的表达式,自变量的个数必须与自定义函数中PARAMETERS语句里的变量个数相等,自变量的数据类型也应符合自定
45、义函数的要求。,2018/10/12,70,* MAIN.PRG 调用PR函数求1100内所有的素数 SET TALK OFF CLEAR FOR I=1 TO 100 IF PR(I) ?I ENDIF ENDFOR RETURN,例9.28 定义一个判断n是否素数的函数,然后调用该函数求21000内的全部素数。,FUNCTION PR &判断n是否素数的函数 PARAMETERS n flag=.T. k=INT(SQRT(n) j=2 DO WHILE j=k .AND. flag IF n%j=0 flag=.F. ENDIF j=j+1 ENDDO RETURN flag,调用函数,
46、2018/10/12,71,2. 过程及过程文件 (1) 过程 过程是以PROCEDURE语句开头,以RETURN语句结束的一段程序 。,形式: PROCEDURE PARAMETER RETURN TO MASTER| TO 过程名,说明: 每个过程实际上是一个独立的子程序或一个用户定义函数。 PROCEDURE 用于过程的第一条语句,它标识了每个过程的开始,同时定义了过程名。 过程如果以RETURN 作为结束语句,那么该过程既可用DO 的形式执行,又可当做一个合法的自定义函数,可供随时调用。 含有PARAMETER选项的过程称为“有参过程”,该项缺省的过程称为“无参过程”。,2018/10
47、/12,72,(2) 过程文件,将多个过程放在一个文件中,这个文件就叫过程文件。 PROCEDURE RETURN PROCEDUBE RETURN,说明: 过程文件的扩展名为.PRG它的建立方法与命令文件的建立方法相同。 一个过程文件可包含的过程数不限,且过程的排列顺序任意。 过程文件中的每个过程必须以PROCEDURE开头,其后是过程名。 过程可以放在过程文件中,也可以放在调用它的程序末尾。,2018/10/12,73,(3) 过程文件的打开与关闭,调用过程之前应当先打开该过程所在的过程文件,使用完毕则关闭过程文件。 格式:SET PROCEDURE TO ,功能:打开指定的过程文件 说明
48、: Visual FoxPro规定,一次只能打开一个过程文件。当用户使用本命令打开一个过程文件时,系统将自动关闭在此之前已经打开的过程文件。 过程文件使用完后,要及时关闭,以释放它们占用的内存空间。关闭过程文件可以使用下列两条命令: SET PROCEDURE TO CLOSE PROCEDURE,(4) 过程的调用 格式:DO WITH 参数表 功能;调用指定的过程。,2018/10/12,74,SET TALK OFF AREA=0 REP=.T. DO WHILE REP &限制所输入的三边一定能够组成一个三角形 CLEAR INPUT “请输入第一边大小:“ TO X INPUT “请输入第二边大小:“ TO Y INPUT “请输入第三边大小:“ TO Z IF X=0.OR.Y=0.OR.Z=0.OR.X+Y=Z.OR.Y+Z=X.OR.X+Z=Y ? “不能构成一个三角形,请重新输入!“ LOOP ENDIF REP=.F. ENDDO DO SUB WITH X,Y,Z,AREA ?“AREA=“,AREA RETURN PROCEDURE SUB PARAMETER A,B,C,S P=(A+B+C)/2 S=SQRT(P*(P-A) *(P-B) *(P-C) RETURN,