第四章 程序设计基础

67
1 第第第 第第第第第第

description

第四章 程序设计基础. 本 章 要 点. 程序 文件 程序的 控制结构 多模块程序 窗口设计 样例. Visual FoxPro 的工作方式. Visual FoxPro 系统提供有三种工作方式:即单命令方式、菜单方式及程序文件方式。 1. 单命令方式 Visual FoxPro 单命令方式是利用 Command 窗口来实现的。用户通过 Command 窗口输入命令,并执行操作。在 Command 窗口中,可以输入单个的操作命令和系统命令,完成对数据库的操作管理和系统环境的设置;也可以建立命令文件及运行命令文件。 - PowerPoint PPT Presentation

Transcript of 第四章 程序设计基础

Page 1: 第四章 程序设计基础

1

第四章

程序设计基础

Page 2: 第四章 程序设计基础

2

目 录

上一页下一页退 出

本 章 要 点程序文件

程序的控制结构

多模块程序

窗口设计样例

Page 3: 第四章 程序设计基础

3

目 录

上一页下一页退 出

Visual FoxPro 的工作方式 Visual FoxPro 系统提供有三种工作方式:即单命令方式、

菜单方式及程序文件方式。 1. 单命令方式 Visual FoxPro 单命令方式是利用 Command 窗口来实现

的。用户通过 Command 窗口输入命令,并执行操作。在Command 窗口中,可以输入单个的操作命令和系统命令,完成对数据库的操作管理和系统环境的设置;也可以建立命令文件及运行命令文件。

Command 窗口不仅是 Visual FoxPro 命令的执行窗口,也是 Visual FoxPro 命令文件的编辑窗口。

所谓单命令方式,即输入一条命令,完成一个操作的工作方式。

要 点

Page 4: 第四章 程序设计基础

4

目 录

上一页下一页退 出

2. 菜单方式 在 Visual FoxPro 环境下,也可以通过系统提供的菜单选项,

对数据库资源进行操作管理和对系统环境进行设置;并通过菜单建立命令文件及运行命令文件。所谓菜单方式,即通过打开不同的菜单选择并完成不同的操作。我们在以前各章所讲的内容其实都可说是菜单方式。

3. 程序文件方式 程序文件(简称程序)也叫做命令文件。运用程序文件方式

进行数据库管理,是通过程序文件编辑工具,将对数据库资源进行操作管理的命令和对系统环境进行设置的命令,集中在一个以( .PRG )为扩展名的命令文件中,然后再通过菜单方式或命令方式运行该命令文件。所谓命令方式,即通过程序文件中的命令完成不同的操作。

要 点

Page 5: 第四章 程序设计基础

5

目 录

上一页下一页退 出

4.1 程序文件 有关此 Visual FoxPro 程序的几点说明 :1 .注释语句【格式 1 】 NOTE < 注释内容 >【格式 2 】 * < 注释内容 >【格式 3 】 && < 注释内容 >【功能】增强程序文件的易读性或放弃 < 注释内容 > 中语

句的执行 2 .命令的分行Visual FoxPro 程序是命令行的序列,每个命令都以回车键结

束,一行只能写一条命令;若一条命令太长,一行写不下,也可分行书写,并在分行处加上续行符“;”,再按回车键。

Page 6: 第四章 程序设计基础

6

目 录

上一页下一页退 出

4.1.1 程序文件的建立、修改与执行

1 .建立或修改程序文件 可用两种方式调用系统内置的文本编辑器建立或修改程序文

件 : 命令方式 MODIFY COMMAND [< 盘符 >] [< 路径 >] 〈程序文件名〉

菜单方式 打开“文件”菜单,选择“新建”;在“新建”窗口,选择

“程序”,再选择“新建文件”

要 点

Page 7: 第四章 程序设计基础

7

目 录

上一页下一页退 出

2 .保存程序 程序输入、编辑完毕,单击【文件】 | 【保存】菜单项,或

按 Ctrl+W 复合键,在“另存为”对话框中指定程序文件的存放位置和文件名,并单击“保存”按钮保存程序文件并退出文本编辑器。程序文件的默认扩展名是 .PRG 。

Page 8: 第四章 程序设计基础

8

目 录

上一页下一页退 出

3 .执行程序程序文件建立后,可以用多种方式、多次执行它。下面是两

种常用的方式。( 1 )菜单方式 ① 单击【程序】 | 【运行】菜单项,打开“运行”对话框; ② 从文件列表框中选择要运行的程序文件,并单击“运

行”命令按钮,启动运行该程序文件 ( 2 )命令方式【格式】 DO [< 盘符 >][< 路径 >\]< 文件名 > 【功能】执行指定 < 盘符 > 、 < 路径 > 下的程序文件

Page 9: 第四章 程序设计基础

9

目 录

上一页下一页退 出

1 、程序结尾的专用命令执行程序文件时,将依次执行文件中的命令,直到所有命令

执行完毕,或者执行到以下命令:① CANCAL :终止程序运行,清除所有的私有变量,返回命令

窗口;② RETURN :结束程序执行,返回调用它的上级程序,若无上

级程序则返回命令窗口;③ QUIT :结束程序执行并退出 Visual FoxPro 系统,返回操作

系统

4.1.2 程序文件中的专用命令

Page 10: 第四章 程序设计基础

10

目 录

上一页下一页退 出

2 、输入输出专用命令ACCEPT 、 INPUT 等命令很少使用,这里仅介绍定位输入输出命令。@< 行 , 列 >[SAY 表达式 1][GET 变量名 ][DEFAULT 表达式 2]

功能:在屏幕的指定行列输出 SAY 子句的表达式值,并可修改 GET 子句的变量值。

SAY 子句用来输出数据, GET 子句用来输入及编辑数据。GET 子句中的变量必须具有初值,或用 Default 子句指定初值。GET 子句的变量必须用 READ 命令来激活。

Page 11: 第四章 程序设计基础

11

目 录

上一页下一页退 出

[例 4-1 ]试编一程序,能根据记录号来修改某设备的价格和部门

( 1 )建立程序*e4-1.prg

CLEAR

USE sb

Jlh=1 && GET 变量必须有初值

@2,10 SAY “ 请输入记录号 :”GET jlh

READ

GO jlh

@4,10 SAY “ 请修改第 :”+STR(jlh,1)+” 个设备的数据 :” && 输出提示字符串

@2,10 SAY “ 价格” GET 价格 &&价格是字段变量,已由初值

@2,10 SAY “ 部门” GET 部门

READ

USE

Page 12: 第四章 程序设计基础

12

目 录

上一页下一页退 出

( 2 )运行程序输入命令 DO e4-1 后程序开始执行

Page 13: 第四章 程序设计基础

13

目 录

上一页下一页退 出

3 . WAIT 命令【格式】 WAIT [< 提示信息 >][TO< 内存变量 >] [WINDOW [AT<行 >,< 列 >]] [NOWAIT] [CLEAR|NOCLEAR] [TIMEOUT< 数值表达式>]【功能】显示提示信息,暂停程序执行,直到用户按任意键或单击鼠标时继续执行程序。 若选择可选项 [TO < 内存变量 >] ,将输入的单个字符作为字符型数据赋给指定的 < 内存变量 > ;若用户是按 Enter 键或单击鼠标, < 内存变量 > 的值为空串。 若省略所有可选项,屏幕显示“键入任意键继续……”默认提示信息

[例 4-2 ] WAIT 命令输出信息提示 .

WAIT “ 请检查输入内容 !”WINDOW

Page 14: 第四章 程序设计基础

14

目 录

上一页下一页退 出

4.2 程序的控制结构 Visual FoxPro 系统提供的命令丰富,且功能强大,把这些

命令和程序设计语句有效地组织在一起,就形成了实现某一特定功能的程序。

Visual FoxPro 系统的程序有两个特点:一是程序控制流模式,由顺序、分支、循环三种基本结构构成。二是面向对象可视化的结构程序模块,在每个模块的内部也是由程序控制流组成。常见的控制结构如下:

1 .顺序结构 顺序结构是在程序执行时,根据程序中语句的书写顺序依

次执行的命令序列。 Visual FoxPro 系统中的大多数命令都可以作为顺序结构中的语句。

2 .分支结构 分支结构是在程序执行时,根据不同的条件,选择执行不

同的程序语句,用来解决有选择、有转移的诸多问题。

要 点

Page 15: 第四章 程序设计基础

15

目 录

上一页下一页退 出

3 .循环结构

循环结构则能够使某些语句或程序段重复执行若干次。如果某些语句或程序段需要在一个固定的位置上重复操作,使用循环是最好的选择。

4 .过程结构

在许多应用程序中,有一些程序段需要反复执行多次,这些程序段不在一个固定的位置上,而是分散在程序的许多位置上重复执行,可将其与嵌入它的程序分开,形成独立的程序序列,待使用时再调入程序中,以实现不同位置上的重复操作。这样做增强了程序的可读性和模块化。我们称这种具有独立功能而且可以被其它程序调用的程序序列为过程。

要 点

Page 16: 第四章 程序设计基础

16

目 录

上一页下一页退 出

分支结构形式有如下三种: 1 .简单条件语句(单向分支)

单向分支语句,即根据用户设置的条件表达式的值,决定某一操作是否执行。

( 1)语句格式: IF 〈条件表达式〉 〈命令行序列〉 ENDIF ( 2)语句功能:

该语句首先计算〈条件表达式〉的值,当〈条件表达式〉的值为真时,执行〈命令行序列〉;否则,执行 ENDIF 后面的第一条命令。

分支结构

要 点

条件式

达式 真

语句序列

ENDIF 之后语句

Page 17: 第四章 程序设计基础

17

目 录

上一页下一页退 出

[例 4-3 ]将 SB.dbf 中第一个非主要设备的价格减少 10% 。*e4-3.prg

use sb

locate for not 主要设备if found()

display 名称 , 价格replace 价格 with 价格 *(1-0.1)

display 名称 , 价格endif

use

return

Page 18: 第四章 程序设计基础

18

目 录

上一页下一页退 出

2 .带 else 的条件语句(双向分支) 双向分支语句,即根据用户设置的条件表达式的值,选

择两个操作中的一个来执行。 ( 1)语句格式: IF 〈条件表达式〉

〈命令行序列 1〉 ELSE

〈命令行序列 2〉 ENDIF

( 2)语句功能: 该语句首先计算〈条件表达式〉的值,当〈条件表达式〉

的值为真时,执行〈命令行序列 1〉中的命令;否则,执行〈命令行序列 2〉中的命令;执行完〈命令行序列 1〉或〈命令行序列 2〉后都将执行 ENDIF 后面的第一条命令。

要 点

条件式 假

语句序列 2 语句序列 1

ENDIF 后面语句

Page 19: 第四章 程序设计基础

19

目 录

上一页下一页退 出

宏代换函数:格式:& < 字符型内存变量 >[. 字符表达式 ]

功能:替换出字符型内存变量的值

[例 4-4 ]宏代换示例*e4-4.prg

m=5

x=“m“ && x 为字符型内存变量?x && 显示 m

? &x && 显示 5 ,得到了变量 x 的值

Page 20: 第四章 程序设计基础

20

目 录

上一页下一页退 出

[例 4-5 ]试编一程序,能打开任意一个表来浏览。*e4-5.prg

@5, 10 SAY " 请输入表名: " get bm default space(10)

Read && 例如输入 sb

bm=alltrim(bm) && 删去两端空格if file(“&bm..dbf”) && 文件存在返回 .T.,&bm 后用一个 . 来连接扩展名 .

dbf

use &bm

browse

else

wait " 该文件不存在! " window

endif

Page 21: 第四章 程序设计基础

21

目 录

上一页下一页退 出

3 .多向分支 多向分支语句,即根据多个条件表达式的值,选择执

行多个操作中的一个对应执行 。( 1)语句格式: DO CASE

CASE〈条件表达式 1〉 < 命令行序列 1〉 CASE〈条件表达式 2〉 < 命令行序列 2〉

… … CASE〈条件表达式 N 〉 〈命令行序列 N 〉] [ OTHERWISE 〈命令行序列 N+1〉] ENDCASE

要 点

条件式 2

语句序列 1

ENDCASE 后面语句

条件式 n-1

Otherwise

条件式 1

真 语句序列 2

真 语句序列 n-1

有 语句序列 n

Page 22: 第四章 程序设计基础

22

目 录

上一页下一页退 出

( 2)语句功能: 该语句根据给出的 N 个〈条件表达式〉的值,选

择 N+1个〈命令行序列〉中的一个执行。当所有 CASE中〈条件表达式〉的值都是假时,如果有 OTHERWISE项,则执行〈命令行序列 N+1〉,再执行ENDCASE后面的第一条命令;否则,直接执行 ENDCASE后面的第一条命令。

要 点

Page 23: 第四章 程序设计基础

23

目 录

上一页下一页退 出

[例 4-6 ]显示当前季节程序。*e4-6.prgyue=month(date()) &&获取当前月份do case

case inlist(yue, 3,4,5) && 第一个表达式的值是其余表达式值之一就返回 .T.

jj=" 春 "case inlist(yue, 6,7,8)

jj=" 夏 "case inlist(yue, 9,10,11)

jj=" 秋 "case inlist(yue, 12,1,2)

jj=" 冬 "endcase

wait jj window &&当前季节显示在 WAIT 提示窗口内

Page 24: 第四章 程序设计基础

24

目 录

上一页下一页退 出

4 .使用分支语句应注意的几点 ( 1) IF… … ENDIF 和 DO CASE… … ENDCASE 必须配

对使用, DO CASE与第一个 CASE〈条件表达式〉之间不应有任何命令。

( 2)〈条件表达式〉可以是各种表达式或函数的组合,其值必须是逻辑值。

( 3)〈命令行序列〉可以由一个或多个命令组成,可以是条件控制语句组成的嵌套结构。

( 4) DO CASE… … ENDCASE 命令,每次最多只能执行一个〈命令行序列〉。在多个 CASE项的〈条件表达式〉值为真时,只执行第一个〈条件表达式〉值为真的〈命令行序列〉,然后执行 ENDCASE的后面的第一条命令。

要 点

Page 25: 第四章 程序设计基础

25

目 录

上一页下一页退 出

循环结构 1 . DO WHILE 循环语句【格式 1 】 DO WHILE < 条件表达式 >

< 语句序列 >

ENDDO

要 点

ENDDO 后面的语句

条件表达式式

循环体

假 一个循环结构一般应具备如下的条件:

( 1 )循环的初始条件:一般为给循环控制变量赋初值;

( 2 )循环头:循环语句的起始,设置、判断循环条件;

( 3 )循环尾:循环语句的结尾;

( 4 )循环体:位于循环头和循环尾之间、循环控制重复执行的语句序列

Page 26: 第四章 程序设计基础

26

目 录

上一页下一页退 出

[例 4-7 ]试编一程序,显示 SB.DBF 中所有单价超过 10000 元的设备名称。*e4-7.prg

use sb

do while not eof()

if 价格 >10000

? 名称endif

skip

enddo

use

Page 27: 第四章 程序设计基础

27

目 录

上一页下一页退 出

[例 4-8 ]按 9 万元以上, 1 ~ 9 万元, 1 万元以下三级价格分档统计 sb.dbf 中设备的个数。

*e4-8.prgstore 0 to k1, k2, k3use sbdo while not eof()

do casecase 价格 >90000

k1=k1+1case 价格 <10000

k3=k3+1otherwise

k2=k2+1endcase skip

enddo? "9 万元以上设备个数 :"+str(k1)? "1-9 万元以上设备个数 :"+str(k2)? "1 万元以下设备个数 :"+str(k3)use

Page 28: 第四章 程序设计基础

28

目 录

上一页下一页退 出

2 . FOR 循环语句 (步长循环)【格式】FOR < 循环变量 >=< 初值 > TO < 终值 > [STEP< 步

长 >]

< 循环体 >

ENDFOR|NEXT

要 点

Page 29: 第四章 程序设计基础

29

目 录

上一页下一页退 出

[例 4-9 ]编写计算 S=1+2+3+…+100 的程序。*e4-9.prg

s=0 && s 为累加器,初值为 0

for i=1 to 100 && i 为计数器,初值为 1

s=s+I && 累加next

? "s=", s

Page 30: 第四章 程序设计基础

30

目 录

上一页下一页退 出

3 .“指针”型循环控制语句(扫描循环) “ 指针”型循环控制语句,即根据用户设置的表中的当前记

录指针,决定循环体内语句的执行次数据。 ( 1)语句格式: SCAN [〈范围〉][ FOR 〈条件表达式 1 〉 [ WHILE 〈条件表达式 2 〉 ] ] 〈命令行序列〉 ENDSCAN

( 2)语句功能: 该语句在指定的范围内,用数据记录指针来控制循环次数。

执行语句时,首先判断函数 EOF ()的值,若其值为“真”,则结束循环,否则,结合〈条件表达式 1〉或〈条件表达式2〉,执行〈命令行序列〉,记录指针移到指定的范围和条件内的下一条记录,重新判断函数 EOF ()的值,直到函数 EOF ()的值为真时结束循环。

要 点

Page 31: 第四章 程序设计基础

31

目 录

上一页下一页退 出

[例 4-10 ]用扫描循环语句显示 SB.DBF 中所有单价超过 10000 元的设备名称。

*e4-10.prg

use sb

scan for 价格 >10000

? 名称endscan

use

Page 32: 第四章 程序设计基础

32

目 录

上一页下一页退 出

4 .辅助循环语句【格式 2 】 DO WHILE < 条件表达式 > < 语句序列 1> [LOOP] < 语句序列 2> [EXIT] < 语句序列 3> ENDDO

ENDDO 后面的语句

条件表达式式

循环体

[LOOP]

[EXIT]

•LOOP 语句:强行返回到循环开始语句。•EXIT 语句:强行跳出循环,接着执行 ENDDO 后的语句

Page 33: 第四章 程序设计基础

33

目 录

上一页下一页退 出

[例 4-11 ]编程计算 S=1+2+3+…+100 ,并求 1 ~ 100 间奇数的和。*e4-11.prg

store 0 to i,s,tdo while i < 100

i=i+1s=s+I && 累加 i值if int(i/2) = i/2 && i 为偶数时条件值为 .T.

loopendift=t+I && 累加奇数

enddo

?"1+2+3+...+100=", s?"1-100 奇数和为: ", t

Page 34: 第四章 程序设计基础

34

目 录

上一页下一页退 出

使用 FOR循环语句的有关说明:① 省略STEP <步长 > ,则〈步长〉为默认值1;② 〈初值〉、〈终值〉和〈步长〉都可以是数值表达式,但这些表达式仅在循环语句开始执行时计算一次。循环语句执行过程中,初值、终值和步长是不会改变的,并由此确定循环的次数;

③ 可以在循环体内改变循环变量的值,但会改变循环执行次数;

④ EXIT和 LOOP 命令可以出现在循环体内。执行 LOOP 命令时,结束本次循环,循环变量增加一个步长值,返回 FOR循环头判断循环条件是否成立。执行 EXIT命令时 ,程序跳出循环,执行循环尾后面的语句

Page 35: 第四章 程序设计基础

35

目 录

上一页下一页退 出

5 .多重循环多重循环即循环的嵌套,是在一个循环结构的循环体中又包含

另一个循环。我们称外层循环为外循环,被包含的循环为内循环。嵌套层数一般没有限制,但内循环的循环体必须完全包含在外循环的循环体中,不能相互交叉。正确的嵌套关系如:

DO WHILE < 条件表达式 1> < 语句序列 11> DO WHILE < 条件表达式 2> < 语句序列 21> DO WHILE < 条件表达式 3> < 语句序列 3> ENDDO < 语句行序列 22> ENDDO < 语句行序列 12> ENDDO

Page 36: 第四章 程序设计基础

36

目 录

上一页下一页退 出

[例 4-12 ]在 sb.dbf 中找出所有价格不超过 P 的设备的编号、名称与价格,并要求在各行下显示一条虚线。

*e4-12.prg

clearuse sb@5, 10 say" 请输入价格: "get jg default 0read scan && 外循环

if 价格 < jg? 编号 + space(3) + 名称+ space(3) + str( 价格, 9 , 2)? && 起换行作用for i=1 to 30 && 内循环,显示由 30 个“-”号构成的虚线

??“-“ && 内循环的循环体 endfor

endifendscan

use

Page 37: 第四章 程序设计基础

37

目 录

上一页下一页退 出

6 .使用循环语句时应注意的几点 ( 1) DO WHILE和 ENDDO 、 FOR 和 ENDFOR 、 S

CAN 和 ENDSCAN 必须配对使用。 ( 2)〈命令行序列〉可以是任何 FoxPro 命令或语句,

也可以是循环语句,即可以为多重循环。 ( 3)〈循环变量〉应是数值型的内存变量或数组元素。 ( 4) EXIT和 LOOP 命令嵌入在循环体内,可以改变循环次数,但是不能单独使用。 EXIT的功能是跳出循环,转去执行 ENDDO 、 ENDFOR 、 ENDSCAN 后面的第一条命令; LOOP 的功能是转回到循环的开始处,重新对“条件”进行判断,相当于执行了一次 ENDDO 、ENDFOR 、 ENDSCAN 命令,它可以改变〈命令行序列〉中部分命令的执行次数。 EXIT、 LOOP 可以出现在〈命令行序列〉的任意位置。

要 点

Page 38: 第四章 程序设计基础

38

目 录

上一页下一页退 出

作业:1 、求一元二次方程 AX2+ BX+ C= 0 的实根。程序文件名为 zy4-1.P

RG 。

2 、编写一密码校验程序(假设密码为 ABC )。运行时屏幕显示“请输入密码”,如密码正确,提示“欢迎使用本系统”,否则提示“密码错误”。程序文件名为 zy4-2.PRG 。

3 、假设收入( P )与税率( R )的关系如下表,编程求税金。程序文件名为 zy4-3.PRG 。

0 P< 800 R= 0.05 800 ≤ P< 2000

0.08 2000≤P< 5000 0.1 P≥5000

Page 39: 第四章 程序设计基础

39

目 录

上一页下一页退 出

4.3 过程及过程调用 Visual FoxPro 与其他高级语言一样,支持结构化程序设计方法,允许将若干命令或语句组合在一起作为整体调用,这些可独立存在并可整体调用的命令语句组合称为过程 。

1. 调用过程语句,即执行已有的过程。语句格式:

DO 〈过程名〉 WITH <参数表 > 语句功能:执行以〈过程名〉为名的过程。 2. 过程返回语句,即返回过程的调用处。 语句格式: RETURN[TO MASTER|TO 〈过程名〉]

语句功能:将控制返回到调用程序中调用命令的下一语句。

要 点

Page 40: 第四章 程序设计基础

40

目 录

上一页下一页退 出

4.3 多模块程序应用程序一般都是多模块程序,可包含多个模块程序。模块是可以命名的一个程序段,可指主程序、子程序和自定义程序。

Page 41: 第四章 程序设计基础

41

目 录

上一页下一页退 出

4.3.1 子程序调用与返回1. 调用过程语句,即执行已有的过程。

语句格式:DO 〈程序名 1 〉[ WITH < 参数表 > ][ IN 〈程序名 2 〉]

语句功能:执行以〈过程名 1〉为名的过程。< 参数表 > 中的参数可以是表达式,但若为内存变量必须具有初值当〈程序名 1 〉是 IN 子句〈程序名 2 〉中的一个过程时, DO 命令调用该过程。当调用子程序时参数表中的参数要传给子程序时,子程序也必须设置相应的参数接收语句。

接收参数和回送参数语句: PARAMETERS < 参数表 > 该语句必需是被调用程序中中第一条语句。 <参数表 > 中的参数可以是任意合法的内存变量名。

Page 42: 第四章 程序设计基础

[例 4-13 ]设计一个计算圆面积的子程序,并要求在主程序中带参数调用它。

主程序

*e4-13.prg

ymj=0

@5,10 SAY "请输入半径: " get bj default 0

read

do js with bj,ymj && 调用子程序

?"ymj=",ymj &&显示圆面积

return

子程序

*js.prg

parameters r,s

s=PI()*r*r && vfp 的 PI函数返回 π值

return && 返主

Page 43: 第四章 程序设计基础

43

目 录

上一页下一页退 出

2. 子程序嵌套过程返回语句,即返回过程的调用处。语句格式: RETURN [ TO MASTER | TO 〈程序名〉]

语句功能:将控制返回到调用程序中调用命令的下一语句。

主程序 …

DO A …

子程序 A …

DO B …

RETURN

子程序 B … …

RETURN

主程序 …

DO A …

子程序 A …

DO B …

RETURN

子程序 B … …

RETURN To MASTER

Page 44: 第四章 程序设计基础

44

目 录

上一页下一页退 出

4.3.2 自定义函数

一、自定义函数的建立自定义函数具有如下语法结构: FUNCTION < 函数名 >

PARAMETER < 参数表 >

< 语句序列 >

RETURN < 表达式 >若使用 FUNCTION 语句来指出函数名,表示该函数包含在调用程序中。若缺省该句,表示此函数是一个独立文件,函数名将在建立文件时确定,其扩展名默认为 .PRG 。< 语句序列 >组成为函数体,用于进行各种处理;简单的函数其函数体也可为空。RETURN 语句用于返回函数值,其中的 < 表达式 >值就是函数值。若缺省该语句,则返回的函数值为 .T.

自定义函数与系统函数调用方法相同:函数名 [<参数表 >]

Page 45: 第四章 程序设计基础

[例 4-14 ]设计一个自定义函数,用来求一元一次方程 AX+B=0 的根。*e4-14.prg

解法一:自定义函数作为一个独立的文件

*root.prg

parameters a,b

return iif(a=0,"无解 ",-b/a)

?"x=:",root(3,1)

解法二:自定义函数与其调用语句包含在同一程序中

*root1.prg

clear

@5,10 say " 一次项系数: "get a default 1

@7,10 say "常 数 项: "get b default 0

read

?"x=:",root(a,b)

funtion root

parameters u,v

return iif(u=0,"无解 ",-v/u)

Page 46: 第四章 程序设计基础

46

目 录

上一页下一页退 出

二、数组参数的传递

在调用自定义函数或过程时,也可将数组作为参数来传送数据。发送参数与接收参数都使用数组名,发送参数数组名前要加 @ 来标记,而作为接收参数的数组不需要事先定义

Page 47: 第四章 程序设计基础

[例 4-14 ]解法三:用数组传递参数

*root2.prg

clear

dimension fs(2)

fs(1)=1

fs(2)=0

@5,10 say " 一次项系数: "get fs(1)

@7,10 say "常 数 项: "get fs(2)

read

?"x=:",root(@fs) && 数组名前加 @ 可传递数组

funtion root

parameters js

return iif(js(1)=0,"无解 ",-js(2)/js(1))

Page 48: 第四章 程序设计基础

48

目 录

上一页下一页退 出

4.3.3 过程如果将多模块程序中的每个模块(主程序、子程序或自定义函数)分别保存为一个 .PRG 文件,则每执行一个模块就要打开一次文件,势必增加总的运行时间。VFP允许在一个 .PRG 文件中设置多个程序模块,并将主程序以外的每个模块定义为一个过程,这种文件可称为“过程文件”,仍使用 .PRG 为扩展名。过程格式为:PROCEDURE < 过程名 >

[PARAMETERS < 参数名 >]

< 命令序列 >

[RETURN]

Page 49: 第四章 程序设计基础

[例 4-15 ]将 4-13 的程序改变为过程调用

*e4-15.prgset decimals to 2 && 设置小数保留 2 位ymj=0@5,10 SAY "请输入半径: " get bj default 0readdo js with bj,ymj && 调用过程 js?"ymj=",ymj return && 程序结束语句,允许省略procedure js && 过程 js 开始语句parameters r,s s=pi()*r*rreturn && 过程结束语句,允许省略

Page 50: 第四章 程序设计基础

[例 4-16 ]调用过程文件中的过程实例主程序:

*e4-16.prg

ymj=0

@5,10 SAY "请输入半径: " get bj default 0

read

do js with bj,ymj in js1 && 调用过程文件 js1 中的过程js

?"ymj=",ymj

过程文件:

*js1.prg

procedure js

parameters r,s

s=pi()*r*r

Page 51: 第四章 程序设计基础

51

目 录

上一页下一页退 出

4.3.4 变量的过程域1.公共变量公共变量是指在所有程序模块中都有效的内存变量。在程序或过程中定义公共变量的语句为:

【格式】 PUBLIC < 内存变量表 > 【说明】( 1 )若下层模块中建立的内存变量要供上层模块使用,或某模块中

建立的内存变量要供并列模块使用,必须将这种变量说明成公共变量。

( 2 ) VFP 默认命令窗口中定义的变量都是公共变量,但这样定义的变量不能在程序方式下利用。

( 3 )程序中止执行时公共变量不会自动清除,而只能用命令来清除,使用 Release 或 Clear All 都可以清除公共变量。

Page 52: 第四章 程序设计基础

52

目 录

上一页下一页退 出

2 .私有变量 私有变量是指在建立它的程序以及被此程序调用的程序有效的内存变量在程序中没有被说明为私有变量的内存变量都被看作是私有变量。私有变量也可以用 PRIVATE 说明,命令格式为:【格式 1 】 PRIVATE < 内存变量表 > ALL [LIKE | EXCEPT <通配符 >]【说明】( 1 )用 PRIVATE 语句说明的内存变量,只能在本程序及其下属过程 中使用,退出程序时,变量自动释放;

( 2 )用 PRIVATE 语句在过程中说明的局部变量,可以与上层调用程 序出现的内存变量同名,但它们是不同的变量,在执行被调 用过程期间,上层过程中的同名变量将被隐藏。

Page 53: 第四章 程序设计基础

[例 4-17 ]变量隐藏与恢复的示例*e4-17.prg

parameters sj &&sj 为私有变量,程序调用前的 bj被隐藏起来

private mj &&mj 为私有变量,程序调用前的同名变量 mj被隐藏起来

mj=3.14*sj*sj

?" 程序执行时的变量清单: "

list memo like ? j

return

在命令窗口键入:

release all

mj=0 && 清楚用户定义的所有内存变量

bj=3 && 在命令窗口设置的变量是公共变量

?" 程序执行前的变量清单: "

list memo like ? j &&显示变量清单

do e4-17 with bj &&bj传入 e4-17

?" 程序执行后的变量清单: " &&显示变量清单

list memo like ? j && 程序执行结束时,被屏蔽的变量 mj,bj被恢复

Page 54: 第四章 程序设计基础

54

目 录

上一页下一页退 出

3. 本地变量本地变量只能在建立它的模块中使用,并且不能在高层或底层模块使用,该模块运行结束时本地变量就自动释放。[格式] LOCAL < 内存变量表 >

[功能]将 < 内存变量表 > 指定的变量设置为本地变量,并将这些变量的初值均赋以 .F. 。

Page 55: 第四章 程序设计基础

55

目 录

上一页下一页退 出

4.3.5 程序调试方法

1 、程序中的常见错误语法错误超出系统允许范围的错误逻辑错误

2 、查错技术设置断点单步执行跟踪设置错误陷阱

Page 56: 第四章 程序设计基础

56

目 录

上一页下一页退 出

1.打开调试器 选择【工具】 | 【调试器 】 命 令 。 “ 调试器 ” 窗 口 是 一 个独立 运 行 的 窗 口 ,它 有自己的 菜 单 和工 具栏, 在 “ 调试器 ” 窗 口 中 可 有 选择地打 开 5 个子窗口 :跟踪、监视、局部、 调 用堆栈和调试输出。

如图所示 :

二、调试器

Page 57: 第四章 程序设计基础

57

目 录

上一页下一页退 出

2 .跟踪代码在调试中,最有用的方法就是跟踪代码,以此观察每一行代码的运行,同时检查所有的变量、属性和环境设置值,如图所示

1 、如果“跟踪”窗口没有打开,在调试窗口的菜单栏中选择【窗口】 | 【跟踪】命令

2 、在调试窗口的菜单栏中选择【调试】 | 【运行】命令。打开要调试的程序

3 、在调试窗口的菜单栏中选择【调试】 | 【单步】命令(或 F6 键),或选择【调试】 | 【单步跟踪】命令( F8 键)

Page 58: 第四章 程序设计基础

58

目 录

上一页下一页退 出

3.设置断点 ( 1 )在特定代码行设置断点

在“跟踪”窗口中,找到需要设置断点的那一行,并将光标放置在该代码行上 按下 F9 键或者单击“调试器”工具栏上的“切换断点”按扭。或者双击该行代码行左边的灰色区域,该代码行左边的灰色区域中会显示一个实心点,这表明在该行已经设置一个断点。如果正在调试对象,那么,通过从对象列表中选择对象,从过程列表中选择所需方法程序或事件,就可以在“跟踪”窗口中找到特定的代码行

Page 59: 第四章 程序设计基础

59

目 录

上一页下一页退 出

( 2 )在文件指定位置设置断点 在调试窗口中选择【工具】 | 【断点】命令,打开“断点”对话框

1 、在“类型”列表框中选择“在定位处中断”

2 、在“定位”和“文件”输入框中指定所需断点的位置和文件来设置断点

Page 60: 第四章 程序设计基础

60

目 录

上一页下一页退 出

4 .移去断点在“断点”对话框中,单击断点列表框中某断点左侧的复选框可使该断点无效,单击“删除”按钮可删除选定的断点。在“跟踪”窗口中,双击断点标记可以删除该断点。

Page 61: 第四章 程序设计基础

61

目 录

上一页下一页退 出

5 .查看存储元素的值( 1 )在“局部”窗口中查看变量的值 “局部”窗口会显示调用堆栈上的任意程序、过程或方法程

序里所有的变量、数组、对象和对象元素,如图所示。默认情况下,在“局部”窗口中所显示的是当前执行程序中的变量值

通过在“位置”列表中选择程序或过程,也可以查看其他程序或过程中的变量值

Page 62: 第四章 程序设计基础

62

目 录

上一页下一页退 出

( 2 )在“监视”窗口中查看变量的值 在“监视”窗口的“监视”框中,键入任意一个有效的 Visual FoxPro 表达式,然

后按下回车键。这时,该表达式的值和类型就会出现在“监视”窗口的列表中。如图所示

若要从“监视”窗口中移去某监视项,选择该项,然后按 DEL 键;或者从快捷菜单中,选择“删除监视”

Page 63: 第四章 程序设计基础

63

目 录

上一页下一页退 出

( 3 )在“跟踪”窗口中查看变量值 在“跟踪”窗口中,将光标定位到任何一个变量、数组或属性上,就会出现提示条,并显示它的当前值

Page 64: 第四章 程序设计基础

64

目 录

上一页下一页退 出

6.查看事件发生的序列 若要跟踪事件,可按如下操作:在调试窗口的菜单中选择【工具】 | 【事件跟踪】命令。打开如图所示的跟踪对话框。

② 选择要跟踪的事件:系统默认的跟踪事件为 Visual FoxPro 系统定义的所有事件,用户可从“跟踪事件”列表中选择不跟踪的事件,并单击中部的左箭头按钮将其加入“可用事件”列表中

③ 启动事件跟踪:选中“开启事件跟踪”复选框,便可激活事件跟踪 ④ 选择跟踪输出去向

Page 65: 第四章 程序设计基础

65

目 录

上一页下一页退 出

4.3.6 结构化程序设计典型的数据库应用系统通常含有输入、修改、查询、统计、打印报表等功能模块,它是一个多模块系统,通常用菜单来管理这些模块。下面介绍一个用传统的结构化程序设计方案编写的应用程序。结构化程序设计常用的 3 种方法是:自顶向下,逐步求精;模块化;层次化。

Page 66: 第四章 程序设计基础

[例 4-19 ]试编一程序,能对 sb 表进行维护、查询和打印数据。*e4-19.prgclearuse sbtext ******************************************* * 1 、设备数据维护 2 、打印设备数据 * * 3 、按编号查询设备 4 、退出 * *******************************************endtextdo while .t. @6,5clear @6,5 say "请输入 1~ 4 : " get xz default space(1) read do case case xz="1" *do e1 case xz="2" *do e2 case xz="3" list ro printer prmpt noconsole case xz="1" wait " 系统将关闭 " window timeout 3 exit endcaseenddouse

Page 67: 第四章 程序设计基础

67

目 录

上一页下一页退 出

4.4 窗口设计样例

浏览窗口的定制: BROWSE 命令、定义功能键窗口命令与函数:窗口命令(表 4.1 )、信息对话框函数 Messagebox 。