结构化程序设计-循环结构课件_第1页
结构化程序设计-循环结构课件_第2页
结构化程序设计-循环结构课件_第3页
结构化程序设计-循环结构课件_第4页
结构化程序设计-循环结构课件_第5页
已阅读5页,还剩133页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

结构化程序设计--循环结构结构化程序设计--循环结构结构化程序设计--循环结构程序的概念程序的建立与执行简单的输入与输出命令程序是能够完成一定任务的命令序列的组合。

使用计算机解决实际问题,通常是先要对问题进行分析并建立数学模型,然后考虑数据的组织方式和算法,并用某一种程序设计语言编写程序,最后调试程序,使之运行后能产生预期的结果。这个过程称为程序设计。2.5.1程序的概念调用VFP功能的方式:1交互方式在命令窗口输入命令2程序方式先根据任务的要求确定能完成该任务的命令序列,即编写程序,再建立程序文件,再运行程序。例2.56计算圆的周长和面积CLEARR=5P=2*PI()*RS=PI()*R^2?”周长=”,P?”面积=”,SRETURN2.5.2程序文件的建立执行(1)菜单方式打开文本编辑器输入程序保存程序(2)命令方式MODICOMM[<文件名>]扩展名.prg例2.57计算5!SETTALKOFFS=1I=1DOWHILEI<=5S=S+II=I+1ENDDO?”5!=”,SSETTALKON执行程序文件(1)菜单方式(2)命令方式DO<文件名>简单输入输出命令(1)任意数据输入命令INPUT[<字符表达式>]TO<内存变量>不同类型数据要用相应的定界符INPUT”请输入姓名:”TOFN请输入姓名:”张林”(2)字符串接收命令ACCEPT[<字符表达式>]TO<内存变量>(3)单个字符接收命令WAIT[<字符表达式>]TO<内存变量>…2.6程序基本结构2.6.1顺序结构按命令出现的先后次序依次执行[例题2.2]已知一个三角形底边(A=4)和高(H=3),求它的面积。SETTALKOFFCLEARA=4H=3S=A*H/2?SSETTALKON2.6.2选择结构

1.一般形式的条件语句格式:

IF<条件><语句序列1>[ELSE<语句序列2>]ENDIF[例题2.3]编写程序,其功能是:先从键盘输入一个数x,如果x能被3整除,则输出x的平方值。SETTALKOFFCLEARALLINPUT"输入一个数:"TOXIFINT(X/3)=X/3?X*XENDIF[例题2.4]有如下命令序列,其功能是根据输入的考试成绩,显示相应的成绩等级。CLEARINPUT″输入考试成绩:″TODJIFCHJ<60DJ=″不合格″ELSEIFCHJ<90DJ=″通过″ELSEDJ=″优秀″ENDIFENDIF?″成绩等级:″+DJRETURN2.多分支语句

条件语句实现在两组代码中选择一组执行,是一种标准的选择结构。多分支语句实现一种扩展的选择结构,它可以根据条件从多组代码中选择一组执行。格式:DOCASECASE<条件1><语句序列1>CASE<条件2><语句序列2>...CASE<条件n><语句序列n>[OTHERWISE<语句序列>]ENDCASE前次课复习1.程序和程序文件2.程序的基本结构语句序列1语句序列2条件假真语句序列1语句序列2

1.一般形式的条件语句格式:

IF<条件><语句序列1>[ELSE<语句序列2>]ENDIF本次课重点内容1.循环语句2.通过例题了解循环结构的用法2.6.3循环结构1.条件循环(DOWHILE--ENDDO)DOWHILE<条件><语句序列>ENDDO先判断循环条件是否成立,条件成立执行循环体,否则执行ENDDO后面语句循环控制变量条件循环体真假5!SETTALKOFFS=1I=1DOWHILEI<=5S=S*II=I+1ENDDO?”5!=”,SSETTALKON求1+2+3+4+5SETTALKOFFS=1I=1DOWHILEI<=5S=S+II=I+1ENDDO?”1+2+3+4+5=”,SSETTALKON循环结构循环语句中可以出现两条特殊的命令:LOOP:无条件循环命令结束当次循环EXIT:无条件结束循环命令结束整个循环条件循环体LOOPEXITENDDO后面的语句假真例:1—100间奇数的和SETTALKOFFCLEARS=1N=1DOWHILEN<100N=N+1IFINT(N/2)=N/2LOOPENDIFS=S+NENDDO?”1-100之间的奇数和:”,SSETTALKON*-------------------------------------------------------*【程序填空】*-------------------------------------------------------*功能:查找XSDB表中计算机成绩最高分的学生,将其姓名和计算机字段的内容显示出来,如:王迪98。请在【】处添上适当的内容,使程序完整。*-------------------------------------------------------SETTALKOFFUSEXSDBMAX=计算机***********SPACE**********【1】dowhileNOTEOF()IFMAX<计算机

MAX=计算机***********SPACE**********【2】

ENDIF***********SPACE**********【3】enddo?XM,MAXUSESETTALKONRETURN9.4.2FOR循环语句格式:

FOR<循环变量>=<初值>TO<终值>[STEP<步长值>]<命令组>[EXIT][LOOP]ENDFOR|NEXT

执行过程:首先计算初值、终值和步长值,并将初值赋给循环变量,再将循环变量的值与终值比较,如果循环变量的值在初值与终值范围内,则执行FOR与ENDFOR之间的命令,然后循环变量按步长值增加或减小,再重新比较,直到循环变量的值不在初值与终值范围内,结束循环,转去执行ENDFOR后面的第一条命令。

使用说明:

(1)FOR、ENDFOR|NEXT必须各占一行,且它们必须成对出现。

(2)循环变量可以是一个内存变量或数组元素。如果在FOR…ENDFOR之间改变循环变量的值,将影响循环执行的次数。

(3)<初值>、<终值>和<步长值>均为数值型表达式。如果省略STEP子句,则默认步长值是1。

(4)退出循环后,循环变量的值等于最后一次循环时的值为加上步长值。

(5)LOOP语句和EXIT语句的功能与前面的当型循环语句相同。9.4.3SCAN循环语句格式:

SCAN[<范围>][FOR<条件>][WHILE<条件>]<命令组>[EXIT][LOOP]ENDSCAN执行过程:首先将表记录指针移动到指定范围内的第一条记录上,然后判断记录指针是否超过指定范围以及该记录是否满足WHILE子句所描述的条件,若记录指针超过指定范围或该记录不满足WHILE子句所描述的条件,则结束扫描循环,执行ENDSCAN后面的语句。若记录指针未超过指定范围且该记录满足WHILE子句所描述的条件,则判断该记录是否满足FOR子句所描述的条件,若不满足,记录指针移到下一条记录,进行下一轮循环判断,否则执行命令组后,记录指针下移一条记录,再进行下一轮循环判断。

使用说明:

(1)对指定范围内满足条件的记录执行命令组。若省略范围,则默认为ALL。

(2)SCAN语句自动把记录指针移向下一个符合指定条件的记录,并执行同样的命令组。

(3)LOOP语句和EXIT语句的功能与前面的当型循环语句相同。

例对学生表,分别统计少数民族男、女学生的人数。

CLEARSTORE0TOx,yUSE学生

SCANFOR少数民族否

IF性别="男"x=x+1ELSEy=y+1ENDIFENDSCAN?"少数民族男生有:"+STR(x,2)+"人"?"少数民族女生有:"+STR(y,2)+"人"USERETURN9.1.2程序的控制结构任何复杂的程序都由3种基本控制结构组成。它们是顺序结构、选择结构和循环结构。1.顺序结构这是最简单的一种基本结构,依次顺序执行不同的程序块。2.选择结构根据条件满足或不满足而去执行不同的程序块。3.循环结构循环结构是指重复执行某些操作,重复执行的部分称为循环体。9.1.3结构化程序设计方法结构化程序设计采用自顶向下、逐步求精和模块化的分析方法。自顶向下是指对设计的系统要有一个全面的理解,从问题的全局入手,把一个复杂问题分解成若干个相互独立的子问题,然后对每个子问题再作进一步的分解,如此重复,直到每个问题都容易解决为止。逐步求精是指程序设计的过程是一个渐进的过程,先把一个子问题用一个程序模块来描述,再把每个模块的功能逐步分解细化为一系列的具体步骤,以致能用某种程序设计语言的基本控制语句来实现。逐步求精总是和自顶向下结合使用,一般把逐步求精看作自顶向下设计的具体体现。模块化是结构化程序的重要原则。所谓模块化就是把大程序按照功能分为较小的程序。

9.1.4程序文件的建立与执行1.建立或修改程序文件同建立其他类型文件一样,建立或修改程序文件也有菜单和命令两种操作方式。(1)命令方式要建立或者修改一个程序文件,可使用MODIFY命令。其格式是:

MODIFYCOMMAND[<文件名>|?]MODIFYFILE[<文件名>|?]

其中<文件名>指明要建立或者修改的文件。如果省略文件名,编辑窗口会打开名为untitled.prg的文件。当关闭窗口时出现对话框,要求输入文件名。若使用?,则显示“打开”对话框。在此框中,用户可以选择一个已存在的文件或者输入要建立的新文件名。如果没有给文件指定扩展名,则MODIFYCOMMAND默认为.prg,而MODIFYFILE却默认为空,所以使用MODIFYFILE建立程序文件时文件名必须带扩展名.prg。(2)菜单方式选择“文件”菜单中的“新建”命令,并选择“程序”单选按钮,并单击“新建文件”命令按钮。在文本编辑窗口输入程序内容。不管是用命令方式还是用菜单方式,打开文本编辑窗口后,就可以一条一条地输入命令。在输入过程中出现错误,可用编辑命令进行修改。这里的编辑操作同其他编辑软件(如Word)的编辑操作没有什么不同。当程序建立或修改完毕后,可用Ctrl+W或Ctrl+End存盘,退出编辑窗口。要修改程序文件,选择“文件”菜单中的“打开”命令打开文件即可。2.执行程序

(1)命令方式使用DO命令执行一个VisualFoxPro程序文件或其它文件。命令格式为:DO<文件名>如果文件名不带扩展名,则VisualFoxPro按下列顺序寻找并执行这些程序:可执行文件(.EXE)、应用程序(.app)、编译后的目标程序文件(.fxp)和程序文件(.prg)。9.2.1程序文件中的辅助命令

1.程序注释命令为增强程序的可读性,往往需要在程序中使用注释来对程序进行说明,为阅读程序提供方便。VisualFoxPro中有两种程序注释命令。命令格式:

NOTE|*[注释]&&[注释]

第一个命令在程序中加注释行信息。执行程序文件时,不执行以NOTE或*开头的行。如果要在下一行继续注释,可在本注释行尾加上一个分号;,或者直接回车再另用一个注释命令。第二个命令在命令语句的尾部加注释信息。9.2顺序结构程序2.常用状态设置命令(1)置会话状态命令命令格式:

SETTALKON|OFF

在会话状态开通时,VisualFoxPro在执行命令时会向用户提供大量的反馈信息。工作于程序方式时,这不仅会减慢程序的运行速度,而且还会与程序本身的输出相互夹杂,引起混淆。所以程序调试时,一般置“会话”于开通状态,而在执行程序时则通常要求置“会话”于断开状态。(2)置打印状态命令命令格式:

SETPRINTON|OFF

系统默认打印机置于断开状态,就是说命令的执行结果只送到屏幕,不送往打印机。若用命令SETPRINTON置打印机为接通状态,则在屏幕上显示的执行结果被同时打印。

(3)置屏幕状态命令命令格式:

SETCONSOLEON|OFF

在系统的默认状态下,用户从键盘输入的内容都在屏幕上显示,然而有时却要求键入的内容保密而不被显示,这只需使用命令SETCONSOLEOFF便可。在应用程序中当用户键入密码的时就可先执行此命令。(4)置缺省驱动器和目录命令命令格式:

SETDEFAULTTO[盘符:][路径]

用于设置进行输入输出操作时的缺省驱动器和缺省目录。9.2.2交互式输入命令1.字符串接收命令字符串接收命令显示提示信息,等待用户从键盘输入一个字符串并按回车键后,存入指定的内存变量中。命令格式为:

ACCEPT[<提示信息>]TO<内存变量>其中<提示信息>可以是字符型内存变量、字符串常量或合法的字符表达式。输入的数据不需要用定界符括起来,ACCEPT命令总是将它作字符型数据处理。

例在学生表中,需要按学号查询学生的姓名和入学成绩。

CLEARSETTALKOFFUSE学生

ACCEPT"请输入待查学生的编号:"TObh1LOCATEFOR学号=bh1DISP学号,姓名,入学成绩

USESETTALKONRETURN

若输入的编号在学生表中不存在,程序并未反应,因此程序需进一步完善。2.任意数据输入命令命令格式:

INPUT[<提示信息>]TO<内存变量>

该命令与ACCEPT命令的区别在于键入的数据类型不同,它不仅可以接收字符型数据,还可以接收数值型、日期型和逻辑型表达式的值。其中,对于字符串的输入必须用定界符括起来,输入数值或表达式,不加任何定界符;输入日期型数据,除使用日期型的格式外,还要用大括号{}将其括起来。例如

INPUT"请输入一个数值表达式:"TOnumINPUT"请输入一个日期:"TOdat

执行情况如下:请输入一个数值表达式:98/10/10

请输入一个日期:{^1998-10-10}3.单个字符接收命令命令格式:

WAIT[<提示信息>][TO<内存变量>][WINDOW[NOWAIT]][TIMEOUT<数值表达式>]

命令暂停程序执行,等待用户键入任何一个字符后继续。使用说明:

(1)当命令中包括TO<内存变量>可选项时,则定义一个字符型内存变量,并将键入的一个字符存入该变量中。

(2)若只按回车键,则在内存变量中存入的内容将是一个空字符。

(3)若包含提示信息,则在屏幕上显示提示信息的内容;若没有该选择项,则显示系统默认的提示信息:

Pressanykeytocontinue(4)如果选择WINDOW,则命令执行时,在VisualFoxPro主窗口的左上角会出现一个提示信息窗口,有关提示信息便在此窗口中显示。

(5)如果选择NOWAIT,则WAIT命令并不会暂停程序的执行,而是仅在VisualFoxPro主窗口的左上角提示窗口中显示提示信息,并且用户只要一移动鼠标或按下任意键,提示窗口便会自动被清除。NOWAIT必须与WINDOW合用才有效果。(6)TIMEOUT子句用于指定WAIT命令等待的时间。如果在由<数值表达式>所限定的秒数之内用户仍未移动鼠标或按下任一键,则程序便继续执行。

WAIT只需用户按一个键,而不像INPUT或ACCEPT命令需要用回车键确认输入结束。因此,WAIT命令的执行速度快,常用于等待用户对某个问题的确认。9.2.3格式输入输出命令的基本形式VisualFoxPro提供了格式输入输出命令,这里先介绍其基本用法。

1.格式输出命令的基本形式命令格式:

@<行,列>SAY<表达式>

命令在指定位置输出表达式的值。使用说明:

(1)<行,列>指定了输出的位置。标准屏幕是25行80列,左上角顶点为(0,0),右下角坐标为(24,79)。

(2)行、列都可为表达式,还可为小数。2.格式输入命令的基本形式命令格式:

@<行,列>[SAY<提示信息>]GET<变量>READ[SAVE][CYCLE][TIMEOUT<等待时间>]

命令用READ命令来激活当前所有的GET变量,显示并允许修改变量的值。

使用说明:

(1)SAY子句用于显示提示信息,GET子句用于为变量输入新值。

(2)GET子句中的变量必须有确定的初值。初值决定了该变量的类型和宽度。例如:

name=SPACE(8)@5,10SAY"请输入学生姓名"GETname&&name的宽度为8个字符

READ(3)激活CET变量是指使该变量进入编辑状态,让光标自动跳到该变量值所在位置上等待编辑修改。若有多个GET变量,则它们将依次被激活(其中无须修改的变量可按回车键越过),直至最后一个GET变量处理结束后,READ命令的作用才终止。如果在READ命令中使用了CYCLE可选项,则在编辑最后一个GET变量后,又回过去重新激活第一个GET变量,如此不断地循环,直至按Ctrl+W(保存编辑内容)或按Esc(舍弃编辑内容)或执行命令CLEARREAD。

READ命令使用TIMEOUT子句来约束执行命令的等待时间(以秒为单位),若超过了预定的等待时间却还没有输入数据,则将中断READ的执行。(4)一般说来,已被激活过的GET变量便被清除,但若在READ命令中带有可选项ASVE,就不做清除工作,当遇到下一个READ命令时,这些GET变量将被再一次激活。9.3.1双分支选择语句语句格式:

IF<条件><命令组1>[ELSE<命令组2>]ENDIF

执行过程:9.3选择结构程序

如果<条件>成立,就执行命令组1,命令组1执行完成后就转到ENDIF之后的命令。如果<条件>不成立,当有ELSE子句时,执行命令组2,命令组2执行完成后转去执行ENDIF之后的命令,当没有ELSE子句时,则直接转到ENDIF之后的命令。

使用说明:

(1)选择语句只能在程序中使用,正因为只能在程序中使用,我们称之为语句,而不叫作命令。以后其它语句也是这样。

(2)IF、ELSE、ENDIF必须各占一行。每一个IF都必须有一个ENDIF与其对应,即IF和ENDIF必须成对出现。

(3)<条件>可以为关系表达式、逻辑表达式或其它逻辑量。

(4)命令组1或命令组2中可以包含IF语句,即IF语句可以嵌套。

例根据输入的学生姓名,在学生表中查找学生记录

SETTALKOFFUSE学生

name=space(8)@10,5SAY"请输入学生姓名:"GETnameREADLOCATEFOR姓名=name&&在学生表中查找记录,xm是字段名

IFFOUND()&&判断是否找到。

DISPLAY&&找到,显示该记录ELSE@12,5SAY"对不起,该单位无此人!"ENDIFSETTALKONUSERETURN9.3.2多分支选择语句语句格式:

DOCASECASE<条件1><命令组1>CASE<条件2><命令组2>…[OTHERWISE<命令组n>]ENDCASE

执行过程:在执行DOCASE语句时,依次判断各<条件>是否满足,若<条件>满足,就执行该条件后的命令组,直到遇到下一个CASE、OTHERWISE或ENDCASE。命令组执行后不再判断其他条件,而转向执行ENDCASE后面的第一条命令。所以在一个DOCASE结构中,最多只能执行一个CASE语句。如果没有一个<条件>满足,就执行OTHERWISE后面的命令组,直到ENDCASE。如果没有OTHERWISE,则不作任何操作就转向ENDCASE之后的第一条命令。

例在学生表中,查询“周文杰”的记录,根据其性别和年龄确定参加运动会的项目。

SETTALKOFFUSE学生

LOCATEFOR姓名="周文杰"IF.NOT.EOF()DOCASECASE性别="男"?"请参加拔河比赛"CASE性别="女"ANDYEAR(DATE())-YEAR(出生日期)>25?"请参加投篮比赛"CASE性别="女"ANDYEAR(DATE())-YEAR(出生日期)<=23?"请参加1500米比赛"ENDCASEELSE?"该单位无此人"ENDIFSETTALKONRETURN9.4.1DOWHILE循环语句格式:

DOWHILE<条件><命令组>[EXIT][LOOP]ENDDO9.4循环结构程序

执行过程:当给定的条件满足时,执行DOWHILE和ENDDO之间的命令组。命令组执行完毕后,程序自动返回到DOWHILE语句,再一次判断DOWHILE语句中的<条件>。如果<条件>仍然满足,则再执行一遍命令组,如果<条件>不满足,则结束循环,转去执行ENDDO之后的命令。

EXIT控制从循环体内跳出,转去执行ENDDO后的第一条命令,可把EXIT放在循环体的任何地方。因此EXIT被称为无条件结束循环命令,只能在循环结构中使用。

LOOP控制直接转回到DOWHILE语句,而不执行LOOP和ENDDO之间的命令。因此LOOP称为无条件循环命令,只能在循环结构中使用。例逐条输出学生表中1984年出生的学生的记录。CLEARUSE学生INDEXONYEAR(出生日期)TAGcsrqsySEEK1984DOWHILEYEAR(出生日期)=1984DISPLAYSKIPENDDOUSERETURN

例求1~100之间全部奇数之和

SETTALKOFFSTORE0TOx,yDOWHILE.T.x=x+1DOCASECASEINT(x/2)=x/2LOOPCASEx>=100EXITOTHERWISEy=y+xENDCASEENDDO?"0~100之间的奇数之和为:",ySETTALKONRETURN9.4.2FOR循环语句格式:

FOR<循环变量>=<初值>TO<终值>[STEP<步长值>]<命令组>[EXIT][LOOP]ENDFOR|NEXT

执行过程:首先计算初值、终值和步长值,并将初值赋给循环变量,再将循环变量的值与终值比较,如果循环变量的值在初值与终值范围内,则执行FOR与ENDFOR之间的命令,然后循环变量按步长值增加或减小,再重新比较,直到循环变量的值不在初值与终值范围内,结束循环,转去执行ENDFOR后面的第一条命令。

使用说明:

(1)FOR、ENDFOR|NEXT必须各占一行,且它们必须成对出现。

(2)循环变量可以是一个内存变量或数组元素。如果在FOR…ENDFOR之间改变循环变量的值,将影响循环执行的次数。

(3)<初值>、<终值>和<步长值>均为数值型表达式。如果省略STEP子句,则默认步长值是1。

(4)退出循环后,循环变量的值等于最后一次循环时的值为加上步长值。

(5)LOOP语句和EXIT语句的功能与前面的当型循环语句相同。9.4.3SCAN循环语句格式:

SCAN[<范围>][FOR<条件>][WHILE<条件>]<命令组>[EXIT][LOOP]ENDSCAN执行过程:首先将表记录指针移动到指定范围内的第一条记录上,然后判断记录指针是否超过指定范围以及该记录是否满足WHILE子句所描述的条件,若记录指针超过指定范围或该记录不满足WHILE子句所描述的条件,则结束扫描循环,执行ENDSCAN后面的语句。若记录指针未超过指定范围且该记录满足WHILE子句所描述的条件,则判断该记录是否满足FOR子句所描述的条件,若不满足,记录指针移到下一条记录,进行下一轮循环判断,否则执行命令组后,记录指针下移一条记录,再进行下一轮循环判断。

使用说明:

(1)对指定范围内满足条件的记录执行命令组。若省略范围,则默认为ALL。

(2)SCAN语句自动把记录指针移向下一个符合指定条件的记录,并执行同样的命令组。

(3)LOOP语句和EXIT语句的功能与前面的当型循环语句相同。

例对学生表,分别统计少数民族男、女学生的人数。

CLEARSTORE0TOx,yUSE学生

SCANFOR少数民族否

IF性别="男"x=x+1ELSEy=y+1ENDIFENDSCAN?"少数民族男生有:"+STR(x,2)+"人"?"少数民族女生有:"+STR(y,2)+"人"USERETURN9.4.4程序举例例某集团公司下属6个分公司,各分公司均已建立了各自的人事档案表,表结构相同,表文件名分别为rsda1.dbf、rsda2.dbf、…、rsda6.dbf。现要求统计各公司会计师、经济师和其他人员的人数。SETTALKOFFFORk=1TO6db="rsda"+SUBSTR(STR(k),10,1)USE&dbSTORE0TOx,y,zSCANDOCASECASE职称="会计师"x=x+1CASE职称="经济师"y=y+1OTHERWISEz=z+1ENDCASEENDSCAN?"第"+STR(k,1)+"分公司会计师有"+STR(x,3)+"名"?"第"+STR(k,1)+"分公司经济师有"+STR(y,3)+"名"?"第"+STR(k,1)+"分公司其他人员有"+STR(z,3)+"名"ENDFORSETTALKONRETURNCLEAR*定义数组并输入数据INPUT'm='TOmINPUT'n='TOnDIMENSIONda(m,n)FORi=1TOmFORj=1TOnINPUT'da('+STR(i,2)+','+STR(j,2)+')='TOda(i,j)ENDFORENDFOR*处理num=0&&存放共有多少个元素符合条件FORi=1TOm&&考虑每一行

FORj=1TOn&&考虑i行的每个元素

FORk=1TOn&&判断当前元素是否在所在行上最大IFda(i,j)<da(i,k)EXITENDIFENDFORIFk<=n&&若当前元素不是最大,考虑下一个元素

LOOPENDIFFORp=1TOm&&判断当前元素是否在所在列上最小

IFda(i,j)>da(1,j)EXITENDIFENDFORIFp<=m&&若当前元素不是最小,考虑下一个元素

LOOPENDIF?'da('+STR(i,2)+','+STR(j,2)+')=',da(i,j)num=num+1ENDFORENDFOR?'共有'+STR(num,2)+'个元素符合条件'RETURN9.5.1子程序、过程和函数

1.子程序

(1)子程序的结构。在VisualFoxPro程序文件中,可以通过DO命令调用另一个程序文件,此时,被调用的程序文件就称为子程序。子程序的结构与一般的程序文件一样,而且也可以用MODIFYCOMMAND命令来建立、修改和存盘,扩展名也默认为.PRG。子程序和其他程序文件的惟一区别是其末尾或返回处必须有返回语句。9.5程序的模块化

命令格式:

RETURN[TOMASTER|TO<程序文件名>|<表达式>]

命令功能:中止一个程序、过程或用户定义函数的执行,返回到上一级调用程序、最高级调用程序、另外一个程序或者命令窗口。

使用说明:①若程序是被另一个程序调用的,遇到RETURN时,则自动返回到上级调用程序。如果是在最高一级主程序中,遇到RETURN时,则返回到命令窗口。②选用TOMASTER子句时,则返回到最高一级调用程序,即在命令窗口下,调用的第一个主程序。③在程序最后,如果没有RETURN命令,则程序运行完后,将自动默认执行一个RETURN命令,但过程文件除外。

④执行RETURN命令时,释放本程序所建立的局部变量,恢复用PRIVATE隐藏起来的内存变量。⑤TO<程序名>表示将控制权交给指定的程序。⑥RETURN<表达式>表示将表达式的值返回调用程序,用于自定义函数。(2)子程序的调用。子程序调用命令与主程序执行命令相同,其格式都为:

DO<程序文件名>|<过程名>[WITH<参数表>]

其中,WITH<参数表>子句指定传递到程序或过程的参数,在<参数表>中列出的参数可以是表达式、内存变量、常量、字段名或用户定义函数。可把参数放在圆括号中,各参数用逗号分隔。传递给一个程序的参数最多为24个。(3)子程序的嵌套调用。主程序可以调用子程序,子程序还可以调用另外的子程序,这就是子程序的嵌套调用。实际上,子程序和主程序都是相对的,任何一个程序可以调用其它程序,也可以被其他程序调用。每个被调用程序的末尾或返回处都要加上RETURN命令。

一个程序或子程序遇到调用子程序命令就转去执行子程序,而本程序的余下部分要等从子程序返回后才得以继续执行。如果在某一个子程序的RETURN命令中使用TOMASTER短语,则从此子程序直接返回到第一级主程序,其间子程序DO命令以下的命令均不执行。在主程序中也可以使用RETURN命令,它将清除内存变量,使程序退回到命令窗口。RETURN命令也可以作为每个程序的结束标志。2.自定义函数

(1)自定义函数的结构。一个自定义函数实际上就是一个子程序,惟一的差别是在RETURN语句后带有表达式,以指出函数的返回值。自定义函数的格式:

[FUNCTION<函数名>][PARAMETERS<参数表>]<命令组>RETURN[<表达式>]

使用说明:①若不写FUNCTION<函数名>选项,则表明该自定义函数是一个独立的程序文件。若写上该选项,则表明该自定义函数不能作为一个独立的程序文件,而只能放在某程序中。②如果自定义函数名与VisualFoxPro的内部函数名相同,系统只承认内部函数,因此不能用内部函数名来命名自定义函数。③若自定义函数中包含自变量,程序的第一行必须是参数定义命令PARAMETERS。④自定义函数除了可以作为一个函数被其它程序调用外,还可用DO<文件名>的形式来执行,在这种情况下,它不是作为函数,而是作为程序或过程来运行,它的RETURN语句中的<表达式>相应地不起作用。⑤自定义函数的数据类型取决于RETURN语句中<表达式>的数据类型。如果省略<表达式>,则返回.T.。

(2)自定义函数的调用。自定义函数的调用形式是:

<函数名>(<自变量表>)

其中,自变量可以是任何合法的表达式,自变量的个数必须与自定义函数中PARAMETERS语句里的变量个数相等,自变量的数据类型也应符合自定义函数的要求。

例定义一个判断n是否素数的函数,然后调用该函数求2~1000内的全部素数。*prime.prg判断n是否素数的函数

PARAMETERSnflag=.T.k=INT(SQRT(n))j=2DOWHILEj<=k.AND.flagIFMOD(n,j)=0flag=.F.ENDIFj=j+1ENDDORETURNflag

*main.prg调用该函数求2~1000内的全部素数

FORm=2TO1000IFprime(m)?mENDIFENDFORCANCEL3.过程与过程文件

(1)过程的结构。过程的一般格式是:

PROCEDURE<过程名>[PARAMETERS<参数表>]<命令组>RETURN

使用说明:①每一个过程均以PROCEDURE开始,以RETURN结束。每个过程实际上是一个独立的子程序或一个用户定义函数。②PROCEDURE<过程名>用于过程的第一条语句,它标识了每个过程的开始,同时定义了过程名。③过程如果以RETURN<表达式>作为结束语句,那么该过程既可用DO<过程名>的形式执行,又可当做一个合法的自定义函数,可供随时调用。

例使用带传递参数的过程调用方式计算三角形面积。

SETTALKOFFarea=0STORE.T.TOrepDOWHILErepCLEARINPUT"请输入第一边大小:"TOxINPUT"请输入第二边大小:"TOyINPUT"请输入第三边大小:"TOzIFx=0.OR.y=0.OR.z=0.OR.x+y<=z.OR.y+z<=x.OR.x+z<=y?"不能够成一个三角形,请重新输入!"LOOPENDIF

rep=.F.ENDDODOsubWITHx,y,z,area?"Area="+STR(area,6,2)RETURNPROCEDUREsubPARAMETERa,b,c,sp=(a+b+c)/2s=SQRT(p*(p-a)*(p-b)*(p-c))RETURN(2)过程文件。一个过程可以以文件形式单独存在,也可以将多个过程合并到一个文件中,这个文件称为过程文件。在过程文件中,每个过程仍然是独立的,可以单独调用。由于过程文件是将许多过程集中起来以一个文件的形式存储在磁盘上的,当打开一个过程文件时,该过程文件中的所有过程即同时被打开,关闭一个过程文件时,过程文件中的所有过程也同时被关闭,从而大大减少访问磁盘的次数,提高程序运行速度。过程文件也是程序文件,同其它程序文件一样,可以用MODIFYCOMMAND命令或其它文字编辑软件进行编辑。

例假设有三个过程:p1,p2,p3,把它们组织到过程文件proc.prg中。*proc.prg过程文件

PROCEDUREp1?"过程p1"RETURNPROCENUREp2?"过程p2"RETURNPROCEDUREp3?"过程p3"RETURN(3)过程文件的打开与关闭。在过程文件被打开之前,过程文件中所包含的过程是不能被任何程序调用的,因此,在调用过程前,先要打开过程文件。命令格式:

SETPROCEDURETO[<过程文件名>]

命令功能:打开一个过程文件。

使用说明:①任一时刻只能有一个被打开的过程文件,因此,每次打开过程文件时自动关闭先前打开的过程文件。过程文件被打开后,它所包括的过程便可被其它程序调用。调用时与子程序一样,仍使用DO命令。②打开过程文件命令在主程序中使用,一般应放在程序的前部,循环的外面,至少应放在调用过程文件中的过程命令之前。③也可把打开过程文件的主程序与过程合在一起,组成一个磁盘文件。但主程序必须在文件中的开始位置,这样才能在主程序中直接调用过程。④过程文件使用完后,要及时关闭,以释放它们占用的内存空间。关闭过程文件可以使用下列两条命令:

SETPROCEDURETOCLOSEPROCEDURE9.5.2内存变量的作用域1.全局内存变量全局内存变量是指在上、下各级程序中都有效的内存变量。全局变量就像在一个程序中定义的变量一样,可以任意改变和引用,当程序执行完后,其值仍然保存。若欲清除这种变量,必须用RELEASE命令。定义全局变量需用下面的命令。

命令格式1:

PUBLIC<内存变量表>|ALL|ALLLINK<通配符>|ALLEXCEPT<通配符>

命令格式2:

PUBLIC[ARRAY]<数组名>(<下标上界1>[,<下标上界2>])[,<数组名>(<下标上界1>[,<下标上界2>]),…]

命令功能:定义全局内存变量或数组。

使用说明:①<内存变量表>中可以包含普通变量,也可以包含数组变量。②任何全局内存变量或数组必须先定义,后赋值。反之,如果程序中已给一个内存变量或数组赋值,或者已用DIMENSION建立了数组,再用PUBLIC将其定义为全局变量或数组将产生错误。③定义后尚未赋值的全局变量其值为逻辑值.F.。④使用ALL选择项时,定义所有内存变量;使用ALLLINK<通配符>时,定义所有变量名与<通配符>匹配的内存变量;使用ALLEXCEPT<通配符>时,定义所有变量名不与<通配符>匹配的内存变量。<通配符>中允许用?和*。⑤全局变量在程序结束时不释放,即使主程序也是这样。⑥当进入下一级子程序时,已在上级由PUBLIC说明过的与之同名的内存变量可以用PRIVATE命令暂时隐藏起来,作为本级程序的局部变量使用。待本级子程序结束返回上一级程序后,便释放它们作为本级程序的局部变量特性,恢复它们全局变量的特性和内容。⑦在命令窗口中建立的所有内存变量或者数组自动定义为全局型。⑧命令格式2可以定义数组,其规则与DIMENSION命令相同。2.局部内存变量局部内存变量只能在定义它的程序及其下级程序中使用,一旦定义它的程序运行结束,它便自动被清除。也就是说,在某一级程序中定义的局部变量,不能进入其上级程序使用,但可以到其下级程序中使用,而且当在下级程序中改变了该变量的值时,在返回本级程序时被改变的值仍然保存,本级程序可以继续使用改变后的变量值。

例分析下列程序的执行情况*主程序main.prgr=100DOsub?pRETURN*子程序sub.prgp=2*3.14*rRETURN

3.隐藏内存变量命令格式:

PRIVATE<内存变量表>|ALL|ALLLIKE<通配符>|ALLEXCEPT<通配符>

命令功能:隐藏当前程序中指定的内存变量或数组。

使用说明:①<内存变量表>指出需要隐藏的内存变量。②对PRIVATE中内存变量的修改并不影响上级程序中与之同名的内存变量的值。此命令只对本级程序及以下各级子程序有效,当返回到上级程序时,被PRIVATE隐藏的当前程序中的内存变量自动被删除。③在它们被隐藏期间,程序就不能再调用这些被隐藏的上级内存变量,但实际上它们仍然存在,一旦含有PRIVATE内存变量的程序结束后,被PRIVATE隐藏起来的哪些以前建立的同名的上级内存变量自动恢复以前的内容和状态。

例写出下列程序的输出

r=100p=10DOsub?pRETURNPROCEDUREsubPRIVATEpp=2*3.14*rRETURN9.5.3调用子程序时的数据传递

1.利用变量的作用域实现数据传递合理地利用前面介绍的内存变量作用域特性,可以实现调用子程序时的数据传递。例计算矩形面积的程序。

*main.prg主程序

gao=8kuan=6c=0DOsub?cCANCEL*sub.prg子程序

c=gao*kuanRETURN2.利用参数实现数据传递命令格式:

PARAMETERS<内存变量表>

命令功能:指定子程序中的局部变量名,并由这些局部变量接收上级程序中用DO…WITH<参数表>传递来的参数,将其依次赋给<内存变量表>中的各局部变量,也可以回送子程序运行的结果。充当传递数据的主程序中的内存变量也称作实际参变量。子程序PARAMETERS中与之相对应的参变量称形式参变量。

使用说明:

(1)该命令必须放在本级程序的首行。

(2)必须和DO…WITH配合使用。<内存变量表>中变量的个数要与上级程序中的WITH<参数表>中的参数个数相同。各变量用逗号分隔,最多能传递24个参数。

(3)变量类型自动与上级程序中的参数相匹配。(4)参数传递有两种方式:值传递和地址传递。如果使用值传递方式,则子程序中参数变化后的值不回传给上级调用程序。如果使用地址传递方式,则子程序中参数变化后的值要回传给上级调用程序。常量和表达式只能使用值传递方式,内存变量既可以使用值传递方式,又可以使用地址传递方式。使用值传递方式的变量要用括号括起来,使用地址传递方式的变量不加括号。如果不允许子程序改变传递参数变量的值,应该使用值传递方式。如果允许子程序改变传递参数变量的值,则要使用地址传递方式。(5)在自定义函数中,仍然使用PARAMETER语句接收上级调用程序传递来的参数。不过,在自定义函数中,默认的参数传递方式是值传递方式。要改变参数的传递方式,需要使用命令:

SETUDFPARMSTOVALUE|REFERENCE

该命令用于设置参数传递方式。选择VALUE,按值传递方式传递参数,选择PREFERENCE,按地址传递方式传递参数。

例写出下列程序的输出

SETTALKOFFx=1y=3DOsubWITHx,(y),5?x,yRETURNPROCEDUREsubPARAMETERa,b,ca=a+b+cb=a+b-cRETURN程序调试就是确定程序出错的位置,然后加以改正,一直到达到预定的设计要求为止。程序调试往往是先分模块调试,当各模块都调试通过以后,再联合起来进行调试,通过联调后,便可试运行,试运行无误即可投入正常使用。9.6.1程序调试概述程序的错误有两类:语法错误和逻辑错误。语法错误相对容易发现和修改,当程序运行遇到这类错误时,VisualFoxPro会自动中断程序的执行,并弹出编辑窗口,显示出错的命令行,给出出错信息,这时可以方便地修改错误。逻辑错误就不那么容易发现了,这类错误系统是无法确定的,只有由用户自己来查错。这时往往需要跟踪程序的执行,在动态执行过程中监视并找出程序中的错误。9.6.2调试器窗口选择“工具”菜单中的“调试器”命令或在命令窗口输入DEBUG命令,系统打开调试器窗口。在VisualFoxPro调试器窗口中,选择“窗

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论