您的位置: 网站首页 > 程序开发 > Visaul FoxPro程序设计 > 第5章 Visual FoxPro程序设计基础 > 【5.7 模块结构程序设计】

5.7 模块结构程序设计

 

5.7  模块结构程序设计

由于一个应用程序通常是由多个相关的程序模块组成的,各模块之间按其互相调用的关系又有主模块和子模块之分。采用这种方式,能够使整个程序的结构清晰,易于分别编写与调试,且便于维护与调用。

模块化的设计要遵循“自顶向下”、“按功能划分模块”、“模块的大小要适中”、“各模块之间的接口要简单”的原则。模块可以是子程序、过程、自定义函数等。

5.7.1  子程序

子程序指的是一个能够独立实现某个功能的程序。其特点是:它总被其他程序调用而一般不能单独执行。通常把调用它的程序称为主程序,被主程序调用的程序称为子程序。

1.建立、修改子程序

建立或者修改子程序的方法与建立其他一般程序的方法一样,其格式为:

Modify Command <子程序文件名>

说明:

1)子程序的建立、修改和保存与其他Visual FoxPro程序一样可以使用Modify Command <程序文件名>命令或者通过菜单的方式来建立和修改,其扩展名也是*prg

2)子程序一定要用ReturnTo Master|To<程序名>]命令结束。Return后如果不加任何选项,则该语句结束子程序文件的运行,返回到调用子程序的主程序的下一个语句,继续执行;若选择To Master命令则返回到一级主程序;若选择To <程序名>命令则返回到“程序名”指定的程序。

2.子程序的调用

如果要调用子程序,其命令格式如下:

Do <子程序名> [With <实际参数表>]

说明:

1[With <实际参数表>]是参数传递的选择。在实际应用中,有时需要在调用主程序与被调用的子程序之间进行一些参数的传递,从而来提高程序设计的灵活性。无论是在子程序、过程,还是在自定义函数中,参数传递都是一个非常重要的应用。

2)如果存在参数传递,那么接受实际参数的Parameters <形式参数表>命令,必须是被调用子程序的第一条可执行语句。<实际参数表><形式参数表>应一一对应,当<实际参数表>的数量少于<形式参数表>的数量时,多余的形式参数取逻辑假的值。

3)当With <实际参数表>是常量、内存变量表达式列表和加圆括号的简单内存变量时,这种传递接受参数的方式是值传送方式。

4)当With <实际参数表达式列表>是简单内存变量列表时,这种传递接受参数的方式是地址传送方式。地址传送是一种双向传送,在调用With <实际参数表>中的变量值时,会按顺序传递给Parameters <形式参数表>对应的变量,而返回时,With <实际参数表>中的变量值会随Parameters <形式参数表>对应变量值的变化而变化。

【例5-23对任意给定的正整数XYZ,用子程序编写计算S=X!+ Y!+ Z!的程序,使用普通变量的方式进行传递。

*主程序5-23.PRG

clear

Store 0 To S,P

For J=1 To 3

  Input "请依次输XYZ的值:" To X1

  Do 5-23-1 With X1

  S=S+P

Endfor

? "S=",S

Return

 

*子程序5-23-1.Prg

Parameters X2

P=1

For I=1 To X2

  P=P*I

Endfor

Return

运行结果如下:

5.7.2  过程

过程也是一个实现某个功能的程序段,是子程序的另一种形式。但是,过程是主程序的一个组成部分,常把它写在主程序的最后。

格式:

Procedure<过程名>                &&过程说明语句是非执行语句

[Parameters <形式参数表>]

<过程体命令序列>                  &&过程体

Return [To Master/To <程序名>]   &&过程的结束语句

说明:

1)过程是一个程序段,一般以程序文件的组成部分存在。

2)过程的调用方法等同程序文件的执行方法:DO <过程名>[WITH <参数表>]

3)用户可以根据需要将自定义函数改成过程,或把过程改成自定义函数。

如果要调用过程,其格式如下:

DO <过程名> [With <实际参数表>]

[With <实际参数表>]的参数传递意义与子程序相同。如果存在参数传递,那么接受实际参数的Parameters <形式参数表>命令,必须写在Procedure<过程名>语句的后面。

【例5-24使用过程的方式编程求圆的面积。

SET TALK OFF

CLEAR

S=0

DO AREA WITH 3

?"圆的面积是:",S

SET TALK ON

 

PROCEDURE AREA

PARAMETERS R

S=3.1416*R*R

RETURN

运行结果如下:

5.7.3  自定义函数

自定义函数和子程序、过程相似,也是实现某个功能的一个程序块。自定义函数既可以写在主程序的后面,也可以是一个独立的程序。所不同的是,自定义函数必须通过Return <表达式>返回一个函数值。

1.自定义函数的建立

自定义函数既可以写在主程序的后面,也可以是一个独立的程序,用Modify Command <程序文件名>命令建立,其扩展名也是*.prg。自定义函数不管是写在主程序的后面,还是作为一个独立的程序来建立,其编写格式均为:

Function<函数名>         &&自定义函数说明语句

Parameters<形式参数表>

<函数体>

Return<表达式>           &&<表达式>的值作为函数值返回

说明:在调用函数时,函数名(参数)中的“参数”应与Parameters<形式参数表>中“形式参数表”一致,自定义函数必须用Return<表达式><表达式>的值作为函数值返回。

2.自定义函数的调用

自定义函数的调用与系统标准函数的调用方法相同,其形式为:

<函数名>[<参数表>]

函数的参数传送方式默认为值传送方式,但在实际变量参数前加@符号为地址传送方式。也可在调用前用命令Set Udfparms To Value/Reference指明变量参数是使用值传送方式还是使用地址传送方式。地址传送是双向传送,而值传送是单向传送。

【例5-25使用函数的方式编程求圆的面积。

SET TALK OFF

CLEAR

INPUT "请输入圆的半径:" TO X

?"则圆的面积为:", STR(area(X),8,2)

SET TALK ON

FUNCTION AREA

PARAMETERS R

S=3.1416*R*R

RETURN S

运行结果如下:

    或者   

【例5-26参数传送示例,认识值传送和地址传送的区别。

Set Udfparms To Value           &&设置为值传送,也可不设置

Clear

Wait "按任意键开始以值进行传送" Window

Store 10 To Mv1, Mv2

Modvar(Mv1,Mv2)   

?Mv1,Mv2

Wait "按任意键开始以地址传送" Window

Set Udfparms To Reference       &&设置为地址传送,也可不设置

Store 10 To Mv1,Mv2

Modvar(Mv1,Mv2)

?Mv1,Mv2

Set Udfparms To Value

Function Modvar

Parameters New_Var1,New_Var2

?New_Var1,New_Var2

Store 20 To New_Var1,New_Var2

Return

运行结果:

5.7.4  应用程序的模块化设计

在使用Visual FoxPro设计应用程序时,一般都是将一个大的程序分成若干个模块,然后分别单独对这些模块进行设计,从而简化了程序的设计。

如图5-8所示是一个简化了的学生成绩管理系统的功能模块结构,每个模块程序都对应一个独立的*.prg文件。此类管理系统的主控模块程序,通常是一个供用户选择各操作功能的菜单程序,而具体的操作功能则由其下属若干个对应子程序模块实现。

5-8  应用程序模块结构

【例5-27使用程序模块结构编写如图5-8所示的程序。

SET SAFETY OFF

SET STATUS OFF

DO WHILE .T.

  CLEAR

  @ 2,31 SAY "★★★★学生成绩管理系统★★★★"

  @ 4,40 PROMPT " 1.添加记录  "

  @ 6,40 PROMPT " 2.删除记录  "

  @ 8,40 PROMPT " 3.修改数据  "

  @ 10,40 PROMPT " 4.查询记录  "

  @ 12,40 PROMPT " 0.退出系统  "

  @ 14,30 SAY "请选择0-4:"

 MENU TO CJ

 DO CASE

   CASE CJ=1

     DO DA_TJ

   CASE CJ=2

     DO DA_SC

   CASE CJ=3

     DO DA_XG

   CASE CJ=4

     DO DA_CX

   CASE CJ=0

      WAIT WINDOW "您已经退出,欢迎下次使用!"

      EXIT

  ENDCASE

ENDDO

CLOSE

RETURN