VFP结构化程序设计课件.ppt
VFP程序设计基础,-第五章,本章内容,1.程序文件的建立与运行 2.VFP的基本语句,3.输入命令和输出命令 4.顺序结构程序设计,5.分支结构程序设计 6.循环结构程序设计,7.模块结构程序设计,1、程序文件的建立与运行,1.1 程序文件的建立 1.2 程序文件的运行 1.3 程序文件的修改,1.1 程序文件的建立与运行,第一章VFP的工作方式有哪两种?,交互操作方式程序执行方式将一批经常要执行的命令编写成程序,并将其存储为程序文件,1.1 程序文件的建立与运行,程序文件可用VFP自身提供的编辑器,也可用任一文本编辑器来建立和修改建立方式:菜单方式命令方式格式:MODIFY COMMAND 利用项目管理器,举例,【例1】:在默认目录上建立一个查看xsda表结构和内容的命令文件 MODIFY COMMAND W1 CLEAR USE XSDA LIST STRUCTURE LIST USE,1.2 程序文件的运行,菜单方式(程序运行)命令方式格式:Do 程序名【例2】:运行已建立的文件W1.PRGdo W1.PRG&扩展名可省略在项目管理器中运行程序,1.3 程序文件的修改,菜单方式“打开”选择程序文件。命令方式modify command,2、VFP的基本语句,2.1 赋值语句2.2 语句的换行 2.3 注释语句2.4 暂停语句2.5 常用显示语句2.6 结束程序运行命令,Store to 名称列表=左边只能是一个变量名,不能是表达式X=33=xX=3+2=2+y,?表达式&换行输出?表达式&不换行输出,2.2 语句的续行,程序中每条命令都以回车键结尾,一行只能写一条命令。若命令需分行书写,应在一行终了时键入续行符“;”,然后按回车例如:Thisform.label1.caption=“太长了,我要”+;“换行了”注意:作为续行符的;只能出现在行尾,2.3 注释语句,功能:提高程序的可读性行首注释格式:Note*行尾注释格式:&,2.4 暂停语句,格式:WAITTOWINDOWAT,TIMEOUT n,若省略,默认的信息是“按任意键继续”,将按下的键以字符形式保存到变量中,若变量不存在,则创建一个。注:单击鼠标,则存储空字符串,指定自动等待键盘或鼠标输入的秒数,若有此项,必须放语句的最后,举例,【例3】:在w2.prg文件里删除编号为1的记录,在删除前用wait语句暂停并提示信息。,2.5 常用显示语句,和命令功能:输出文本两者区别:换行输出;不换行输出如:这是显示文本的例子不换行结束?命令功能:将字符串表达式的值发送到打印机,2.6 结束程序运行命令,ReturnReturn To MasterCANCELQUIT,1、返回到上级程序模块2、返回到最上级主程序3、强行停止程序执行,关闭所有文件,返回系统交互状态4、停止所有程序运行,关闭所有文件,退回到操作系统中,说明,3、输入命令和输出命令,3.1 INPUT命令 3.2 ACCEPT命令 3.3.SAY|GET命令,3.1 INPUT命令,格式:Input 提示语 to 变量名 可以接收数值、字符、日期、逻辑等类型的常量、变量,不能接收空表达式。字符常量必须定界【例】input“输入任意字符均可”to nn?nn,3.2 ACCEPT命令,格式:Accept 提示语 to 变量名只可以接收字符常量,字符不定界【例】Accept“输入任意字符”to nn?nn,4、顺序结构程序设计,程序执行时,按先后顺序依次执行。除非:遇到RETURN命令遇到文件尾(EOF)遇到另一个Procedure或Function关键字是程序中最基本的常用的结构。,举例,【例4】在屏幕的指定位置显示系统日期和时间见程序w3.prg,说明,set talk onoff 命令功能:选择OFF状态则执行的中间结果不显示缺省时为ON状态,【例5】求1+2+3+4的结果(见w4.prg)set talk offn=0n=n+1 n=n+2n=n+3n=n+4?ncancel,output:10,【例6】:编一个程序,将华氏温度F=68度变换成摄氏温度,,并将结果显示出来(见w5.prg)计算公式为:C=5*(F-32)/9set talk offF=68C=5*(F-32)/9?“摄氏:”+STR(C,4)+“度”+“,”+“华氏:”+STR(F,4)+“度”cancel,output:摄氏:20度,华氏:68度,【改编程序】:将任意华氏温度变换成摄氏温度(见w5_1.prg)计算公式为:C=5*(F-32)/9 set talk offInput“请输入华氏温度:”to FC=5*(F-32)/9?“华氏:”+STR(F,4)+“度”+“,”+“摄氏:”+STR(C,4)+“度”cancel,5、分支结构程序设计,简单分支结构,5.1,选择分支结构,5.2,分支嵌套结构,5.3,多路分支结构,5.4,体现计算机的逻辑判断能力根据给定的不同逻辑条件,转向执行不同的程序语句,进行相应的处理这些不同的转向就构成了分支结构,5.1 简单分支结构,格式:if条件表达式Then 语句组endif,简单分支流程图,举例,【例7】:给出两个数,从大到小排列。(见w6.prg)input“请输入第一个数:”to x input“请输入第二个数:”to y if xy t=x x=y y=t endif?x,y cancel,5.2 选择分支结构,语句格式:IF条件表达式 语句组1ELSE 语句组2ENDIF语句功能:当条件为真时,先执行语句组1然后再去执行ENDIF后面的语句当条件为假时,先执行语句组2后再转去执行ENDIF后面的语句,选择分支流程图,【改编程序】:实现华氏温度与摄氏温度的转换.计算公式为:C=5*(F-32)/9、F=C*9/5+32 set talk offinput“请选择转换方式:1、华氏转换成摄氏;2、摄氏转换成华氏”to zif z=1 Input“请输入华氏温度:”to F C=5*(F-32)/9?“华氏”+STR(F,4)+“度,摄氏”+STR(C,4)+“度”else Input“请输入摄氏温度:”to C F=C*9/5+32?“摄氏”+STR(C,4)+“度,华氏”+STR(F,4)+“度”endifcancel,(见w7.prg),【例8】:铁路托运行李,假设每张车票可按每公斤0.5元托运50公斤以内的行李,如果超过50公斤时,超过的部分每公斤加价0.3元。(见w8.prg)计算公式如下:X=0.5W W50 SET TALK OFF INPUT 请输入行李的重量为:TO W IF W=50 X=0.5*W ELSE X=0.5*50+0.8*(W-50)ENDIF?“行李的重量为:”+STR(W,6,2)+“公斤,其运费为:”+STR(X,6,2)+“元”CANCEL,根据学生档案表(XSDA.dbf),按输入的姓名查找其基本情况。分析:查找记录可以使用locate命令,判断是否找到记录可以使用found函数。SET TALK OFF CLEAR USE XSDA ACCEPT“”TO XM LOCATE FOR 姓名=XM IF FOUND()?”姓名:”+姓名?“性别:”,性别?“年龄:”+STR(年龄,2)?”出生年月:”+dtoc(出生年月)else?”对不起,没有查找到此人!”endif close all return,5.3 分支嵌套语句,有IF必有ENDIF,成对出现每一层的IF和ELSE及ENDIF必须一一对应IF-ELSE-ENDIF 每个命令各占一行,不能在同一行出现,第一层,ENDIF,ENDIF,IF 条件,ELSE,语句组3,第三层,ENDIF,第二层,【例9】:判断某个数是正数还是负数。Input“请输入一个数:”to numIf num0?“是正数!”Else if num0?“是负数!”else?“是0!”endifEndifcancel,(见w9.prg),Input“请输入成绩:”to scoreIf score=90?“成绩等级:”+“优秀”Else if score=80?“成绩等级:”+“良好”else if score=70?“成绩等级:”+“中等”else if score=60?“成绩等级:”+“及格”else?“成绩等级:”+“不及格”endif endif endif endifcancel,【例10】:把成绩转换成等级分数,(见w10.prg),DO CASE CASE 条件表达式1 语句组1 CASE 条件表达式2 语句组2:OTHERWISE 语句组 ENDCASE,5.4 多路分支语句,执行多重选择,用于嵌套层数较多的情况,Input“请输入成绩:”to scoreDo case case score=90?“成绩等级:”+“优秀”case score=80?“成绩等级:”+“良好”case score=70?“成绩等级:”+“中等”case score=60?“成绩等级:”+“及格”case score60?“成绩等级:”+“不及格”Endcasecancel,【改编程序】:把成绩转换成等级分数,(见w10_1.prg),Set talk offClearUse xscjAccept“”to xmLocate for 姓名=xm平均分=int(语文+数学+外语+政治)/4If found()do case case 平均分=90 pd=“优秀”case 平均分=80 and 平均分90 pd=“良好”,根据学生成绩表(xscj)输入学生的姓名,并计算其平均成绩及等级。,(见li5-14.prg),case 平均分=70 and 平均分=60 and 平均分70 pd=“及格”otherwise pd=“不及格”Endcase?xm+”+str(平均分,6,2)+”等级为:”+pdElse?”对不起,没有找到这个人!”EndifClose allreturn,6、循环结构程序设计,当型循环结构,6.1,步长型循环结构,6.2,扫描型循环结构,6.3,循环是指按照给定的条件去重复执行一段具有特定功能的程序,6.1 当型循环结构,语句格式:DO WHILE 条件表达式 语句组 ENDDO语句功能:当条件表达式的值为真时,执行语句;否则执行ENDDO后面的语句。,循环体,循环体可以是一个语句。一组语句。也可以是一个VFP子程序,说明,循环语句本身不会修改执行的条件要在循环体内设置修改循环条件的语句。否则会出现死循环。,循环语句流程图:,【例11】:以显示方式输出1到10的数字SET TALK OFFCLEARI1DO WHILE I=10?I II1ENDDO说明:语句II1就是用来修改循环条件,(见w11.prg),【例12】有程序如下:,(见w12.prg),STORE 0 TO C,WUSE XSDADO WHILE.NOT.EOF()DO CASE CASE 性别=.t.W=W+1 CASE 性别=.f.C=C+1 ENDCASE SKIPENDDO?“男生人数为:,W?“女生人数为:,CSET TALK ONCANCEL,转跳语句(LOOP),在DO WHILEENDDO循环体内提供了一条短路语句,可以起到转跳作用语句格式:LOOP语句功能:中断本次循环体的执行跳回到DO WHILE的开始处,重复条件的判断,说明:,LOOP语句一定要用在DOWHILE的循环体内才有意义LOOP语句使它后面的语句在本次循环时不被执行在具有多重DO WHILEENDDO嵌套的程序中,LOOP只返回到与它本身所处的内层循环体相匹配的 DO WHILE语句,出口语句(EXIT),如果在循环的中途,需要结束循环而转到本层循环的后继命令去执行,可以用出口命令语句格式:EXIT语句功能:终止DO WHILEENDDO的正常循环无条件地转到ENDDO的后继命令去执行多重循环,只能跳出一层,多重循环中LOOP和EXIT的作用域,循环的嵌套:如果在一个循环程序的循环体内又包含着另一些循环,就构成了多层次(多重)循环LOOP和EXIT语句放在哪一个层次,它就只能在那个层次中起作用,这个层次就是它的作用域,DO WHILE DO WHILE LOOP EXIT ENDDO LOOP EXITENDDO,【例13】:求0100之间奇数之和 SET TALK OFF X=0 Y=0 DO WHILE X100 X=X+1 IF INT(X/2)=X/2 LOOP ELSE Y=Y+X ENDIF ENDDO?0100之间的奇数之和为:,Y SET TALK ON CANCEL,用INT(X/2)是否等于X/2判断X是否为偶数是则执行LOOP语句,返回DO WHILE。如果INT(X/2)不等于X/2说明X的值为奇数。执行LOOP后面的语句,将奇数累加。,(见w13.prg),【例14】:计算123100的和SET TALK OFFN1S0DO WHILE.T.IF N100 EXIT ENDIF S=S+N N=N+1ENDDO?“S=”,S,S N,1,2,3,3,6,4,10,5,+N,+1,5050,101,(见w14.prg),【例】在学生档案表(xsda)中,依次显示性别为男的学生,并统计出男生的总人数。,Set talk offClearUse xsdaDo while!eof()if 性别=.f.skip loop endif disp 编号,学号,姓名,性别,年龄,出生年月 skipEnddoCount for 性别 to T_no?”以上显示的是男生的基本档案,共计有:”+str(T_no,3)+”人”Close allreturn,语句格式:FOR 循环变量=TO STEP 命令序列 LOOP EXITENDFOR语句功能:循环过程是首先将初值赋于循环变量,每当执行一次循环,循环变量增加一个步长,直到循环变量值大于终值时结束循环。LOOP语句用于转到FOR语句继续执行循环。EXIT用于跳出循环,转到ENDFOR后面命令执行。,6.2 步长型循环结构,例 判断下列几个程序的结果,1、For n=1 to 11 step 2?“,n Endfor2、For n=1 to 10-1?Endfor3、For n=1 to 10?Endfor,n=1+2=3 n=3+2=5 n=5+2=7 n=7+2=9 n=9+2=11 n=11+2=13,n=1+1=2 n=2+1=3 n=3+1=4 n=4+1=5 n=5+1=6 n=6+1=7 n=7+1=8 n=8+1=9 n=9+1=10,n=1+1=2 n=2+1=3 n=3+1=4 n=4+1=5 n=5+1=6 n=6+1=7 n=7+1=8 n=8+1=9 n=9+1=10 n=10+1=11,语句格式:SCAN范围FOR条件表达式 命令序列LOOPEXITENDSCAN,SCAN的功能是在表中移动并重执行命令序列。循环开始时记录指针指向满足条件的第一个记录。执行到ENDSCAN时,记录指针指向第二个满足条件记录。控制又回到SCAN循环的开始,直到所有记录处理完,循环也就结束了。,6.3 扫描型循环结构,例:查找入学成绩500分的记录。SET TALK OFFUSE xsdaSCANDisp for 入学成绩500.00ENDSCANUSERETURN,用SCANENDSCAN命令显示表的记录USE XSDASCAN DISPLAYENDSCANRETURN用FOR.ENDFOR命令显示表的记录USE XSDAFOR I=1 TO 5 GO I DISPLAYENDFORRETURN,判断以下程序的运行结果:,S=0 P=1 DO WHILE P=100 S=S+P P=P+1 ENDDO?S=,S CANCEL,(1)1+2+100的值,S=0+1=1P=1+1=2,S=1+2=3P=2+1=3,S=3+2+1=6P=3+1=4,S=100+3+2+1=5050P=1+1+1+1=101,(2)5!的值,SET TALK OFF T=1 N=1 DO WHILE N=5 T=T*N N=N+1 ENDDO?T=,T CANCEL,T=1*1=1N=1+1=2,T=1*2=2N=2+1=3,T=(1*2)*3=6N=3+1=4,T=(1*2*3)*4=24N=4+1=5,T=(1*2*3*4)*5=120N=5+1=6T=120,SET TALK OFF S=0 T=1 N=1 DO WHILE N=5 T=T*N S=S+T N=N+1 ENDDO?S=,S CANCEL,(3)求S=1!+2!+3!+5!的值,T=1*1=1S=0+1=1N=1+1=2,T=1*2=2S=1+(1*2)=3N=2+1=3,T=(1*2)*3=6S=1+(1*2)+(1*2*3)=9N=3+1=4,T=(1*2*3)*4=24S=1+2!+3!+4!=33N=4+1=5,T=(1*2*3*4)*5=120S=1+2!+3!+4!+5!=153N=5+1=6S=153,SET TALK OFF I=1 DO WHILE I=3 J=5 DO WHILE J=7?I,J J=J+1 ENDDO I=I+1 ENDDO CANCEL,1 51 61 72 52 62 73 53 63 7,FOR I=10 TO 1 STEP-2?I=,I ENDFOR?I RETURN,I=10I=8I=6I=4I=20,7、模块结构程序设计,应用程序一般都是多模块程序,可包含多个程序模块。模块是可以命名的一个程序段,可指子程序、函数、过程,能够完成一定功能的可供其它程序使用(调用)的独立程序段称为子程序。它独立存在,但可以被多次调用,调用子程序的程序称为主程序。,7.1 子程序,1、建立、修改子程序方法同前 modify command 要注意两个问题,一是每个子程序必须单独使用一个文件名保存起来二是主程序和子程序之间有关变量值的传递关系。子程序文件名的扩展名也是.PRG。,7.1 子程序,2、子程序的返回RETURN TO MASTER|TO 说明:a.该语句放在一个程序的末尾。b.不带参数的RETURN语句的功能是将程序控制权返回到调用该子程序的主程序的下一条命令语句。c.RETURN TO MASTER:如果有多级程序调用,某一子程序的该语句将使程序控制权返回到最高一级调用程序。d.RETURN TO:表示将控制权交给指定的程序。,7.1 子程序,3、子程序的调用 DO with 说明:a.程序文件名1:指定要执行程序的名字。DO 直接执行或调用指定的程序。b.WITH:指定传递到子程序的参数,在中列出的参数可以是表达式、内存变量、常量、字段或用户自定义函数。,【例15】利用主程序调用子程序的方法计算任意3个自然数的阶乘和,即求s=a!+b!+c!,factor=1FOR x=n TO 1 STEP-1 factor=factor*xENDFORRETURN 注意,该子程序中的变量n的值需要由主程序传递。将该子程序保存文件名为:jc 调用该子程序的主程序为:CLEARINPUT a=to aINPUT b=to bINPUT c=to c,s=0&定义存放阶乘的累加和的变量factor=1&定义与子程序传递阶乘计算结果的变量n=a&定义计算阶乘需要自然数的传递变量DO jcs=factorn=bDO jcs=s+factorn=cDO jcs=s+factor?ALLTRIM(STR(a,3)+“!+”+ALLTRIM(STR(b,3)+“!+”+;ALLTRIM(STR(c,3)+!=,sRETURN,(见w15.prg),7.2 过程,过程是实现某个功能的程序段,是子程序的另一种形式。过程是主程序的一部分,常把它写在主程序的最后格式:procedure parameters return to master/to 调用格式:DO WITH,7.3 自定义函数,自定义函数和子程序、过程相似,也是实现某个功能的一个程序块。自定义函数既可以写在主程序的后面,也可以是一个独立的程序。与其他程序不同,自定义函数必须通过Return返回一个函数值。自定义函数格式 Function parameters return 函数调用格式,7.3 自定义函数,例:定义一个计算求立方数的函数。,(1)创建函数求立方数函数。函数名为cube(即以cube.prg为文件名存盘)。PARAMETERS v RETURN v*v*v 下面程序中调用求立方函数cube.prg,求1到10的立方数。,(2)在程序中调用函数*求1到10的立方数。程序名为CX23CLEARFOR i=1 TO 10?i,cube(i)ENDFORRETURN自定义函数cube不仅可以在程序中调用,也可以命令窗口里调用。,主程序和子程序或过程的参数传递,为了正确传递参数,被调用的子程序或过程的第一条可执行命令必须是:PARAMETERS 私有变量LPARAMETERS 局部变量调用子程序或过程的命令格式为:DO|WITH|()实参可以是常量、变量或表达式。调用子程序或过程时,系统会自动把实参传递给形参。实参和形参数目应尽量一致。若形参的数目多于实参数目,多于形参初值为逻辑值.F.,接收参数的命令,参数的传递方式,按DO|WITH 格式调用模块程序时如果实参是常量或表达式,系统会将实参的值传递给形参,这样的传递方式称为按值传递。如果实参是变量那么传递给形参的是变量的地址,形参变量值的改变将影响实参变量值,这种参数的传递称为按引用传递。按|()格式调用模块程序时,默认按值传递参数。如果实参是变量,可以通过如下命令重新设置参数传递方式:SET UDFPARMS TO VALUE|REFERENCETO VALUE:为按值传递。形参变量值的改变不会影响实参变量的值TO REFERENCE:为按引用传递。形参变量值和实参变量值同时改变,procedure heparameters x,yz=x+yreturn zendproc,Do he with m,n 按地址传递Do he with(m),(n)按值传递(表达式)Do he with 5,4 按值传递(常量)He(m,n)按值传递He(m),(n)按值传递He(5,4)按值传递,Set udfparms to referenceHe(m,n)按地址传递He(m),(n)按值传递He(5,4)按值传递,参数传递的注意事项,:形参的数目不能少于实参的数目,否则系统产生运行时错误。如果形参的数目多于实参的数目,多余的形参取初值即逻辑值.F.。SET UDFPARMS TO 命令仅影响 过程名()形式:按值传递:形参的值不影响实参的值;按引用传递:形参的值将改变实参的值。,参数的传递方式实例,CLEARSTORE 100 TO x1,x2SET UDFPARMS TO VALUEDO p4 WITH x1,(x2)?第一次:,x1,x2STORE 100 TO x1,x2P4(x1,(x2)?第二次:,x1,x2SET UDFPARMS TO REFERENCEDO p4 WITH x1,(x2)?第三次:,x1,x2,STORE 100 TO x1,x2P4(x1,(x2)?第四次:,x1,x2*过程p4PROCEDURE p4 PARAMETERS x1,x2 STORE X1+1 TO X1 STORE X2+1 TO X2ENDPROC,变量的作用域,变量和数组的作用域指的是变量和数组在什么范围内是有效的或能够被访问。在Visual Foxpro6.0中,变量的作用域共有三类:全局变量、私有变量和局部变量。可以使用PUBLIC、LOCAL、PRIVATE命令强制规定变量的作用范围。,全局变量,全局变量也称为公共变量,在任何程序模块中都可以使用。公共变量要先建立后使用。用PUBLIC命令建立。PUBLIC 该命令的功能是建立公共的内存变量,并为它们赋值.F.全局变量在Visual Foxpro运行期间,可以被任何过程或程序使用全局变量一旦建立就一直有效,即使程序运行结束也不会消失。只有当执行Clear Memory、Release、Quit等命令后,全局变量才被释放。在命令窗口中直接使用而由系统自动隐含建立的变量也是全局变量,局部变量,用LOCAL定义的变量称为局部变量,只能在创建他们的过程或程序中使用和修改,不能被更高层或更低层的过程或程序访问。当建立局部变量的模块程序运行结束,局部变量自动释放。建立局部变量的格式 LOCAL 该命令建立指定的局部内存变量,并为它赋值.F.局部变量必须先建立后使用LOCAL命令在建立局部变量的同时,也具有隐藏在上层模块中建立的同名变量的作用,但与PRIVATE命令不同,LOCAL命令只在它所在的模块内隐藏这些同名命令,一旦到了下层模块,这些同名命令就会重新出现。,私有变量,用PRIVATE定义的变量称为私有变量,只能被当前过程及所调用的过程使用,并将以前过程中定义的同名变量保存起来,在当前过程中使用私有变量不影响这些同名变量的原始值。如果没有使用PUBLIC、LOCAL、PRIVATE强制规定,在程序中直接使用的变量都是私有变量。其作用域是建立它的模块及其下属的各层模块当程序运行结束,此模块程序中的私有变量将自动清除。Private命令的语法格式 private private all LIKE|EXCEPT,变量的隐藏,开发应用程序时,主程序与子程序不一定是同一个人设计的,编写子程序的人不可能对主程序中用到的变量了解的非常清除。子程序中用到的变量可能在主程序中已经建立,子程序的运行会无意间改变主程序的变量取值。解决此问题的办法,用private命令隐藏主程序中可能存在的变量,使得这些变量在子程序中暂时无效。命令格式:private private all like except,PUBLIC X,YX=10Y=100DO P8?X,Y,PROCEDURE P8 PRIVATE X X=50 LOCAL Y DO P9?X,YENDPROC,PROCEDURE P9 X=“aaa”Y=“bbb”RETURNENDPROC,10 bbb,aaa.F.,