Visual FoxPro
1
i s u a l
F
V
o x P r o
Visual FoxPro
2
9.1 程序设计基础
9.2 顺序结构程序
9.3 选择结构程序
9.4 循环结构程序
9.5 程序的模块化
9.6 程序的调试
Visual FoxPro
3
9.1.1 程序设计的概念
什么叫程序设计? 对于初学者来说, 往往把
程序设计简单地理解为只是编写一个程序 。 这是
不全面的 。 程序设计反映了利用计算机解决问题
的全过程, 包含多方面的内容, 而编写程序只是
其中的一个方面 。 使用计算机解决实际问题, 通
常是先要对问题进行分析并建立数学模型, 然后
考虑数据的组织方式和算法, 并用某一种程序设
计语言编写程序, 最后调试程序, 使之运行后能
产生预期的结果 。 这个过程称为程序设计 。
9.1 程序设计基础
Visual FoxPro
4
在拿到一个实际问题之后,应对问题的性
质与要求进行深入分析,从而确定求解问题的
数学模型或方法,接下来进行算法设计,并画
出流程图。有了算法流程图,再来编写程序是
很容易的事情。有些初学者,在没有把所要解
决的问题分析清楚之前就急于编写程序,结果
编程思路紊乱,很难得到预想的结果。
Visual FoxPro
5
9.1.2 程序的控制结构
任何复杂的程序都由 3种基本控制结构组成。它
们是顺序结构、选择结构和循环结构。
1,顺序结构
这是最简单的一种基本结构,依次顺序执行不同的
程序块。
2,选择结构
根据条件满足或不满足而去执行不同的程序块。
3,循环结构
循环结构是指重复执行某些操作,重复执行的部分
称为循环体 。
Visual FoxPro
6
9.1.3 结构化程序设计方法
结构化程序设计采用自顶向下, 逐步求精和模
块化的分析方法 。
自顶向下是指对设计的系统要有一个全面的理
解, 从问题的全局入手, 把一个复杂问题分解成若
干个相互独立的子问题, 然后对每个子问题再作进
一步的分解, 如此重复, 直到每个问题都容易解决为止 。
逐步求精是指程序设计的过程是一个渐进的过
程, 先把一个子问题用一个程序模块来描述, 再把
每个模块的功能逐步分解细化为一系列的具体步骤,
以致能用某种程序设计语言的基本控制语句来实现 。
逐步求精总是和自顶向下结合使用, 一般把逐步求精看作自顶向下设计的具体体现 。
模块化是结构化程序的重要原则 。 所谓模块化
就是把大程序按照功能分为较小的程序 。
Visual FoxPro
7
9.1.4 程序文件的建立与执行
1,建立或修改程序文件
同建立其他类型文件一样,建立或修改程序文件也有
菜单和命令两种操作方式。
(1)命令方式
要建立或者修改一个程序文件,可使用 MODIFY命令。
其格式是:
MODIFY COMMAND [<文件名 >|?]
MODIFY FILE [<文件名 >|?]
Visual FoxPro
8
其中 <文件名 >指明要建立或者修改的文件。如
果省略文件名,编辑窗口会打开名为
untitled.prg的文件。当关闭窗口时出现对话框,
要求输入文件名。若使用?,则显示“打开”
对话框。在此框中,用户可以选择一个已存在
的文件或者输入要建立的新文件名。如果没有
给文件指定扩展名,则 MODIFY COMMAND
默认为,prg,而 MODIFY FILE却默认为空,
所以使用 MODIFY FILE建立程序文件时文件
名必须带扩展名,prg。
Visual FoxPro
9
(2)菜单方式
选择“文件”菜单中的“新建”命令,并选择“程序”
单选按钮,并单击“新建文件”命令按钮。在文本
编辑窗口输入程序内容。
不管是用命令方式还是用菜单方式,打开文本编辑窗
口后,就可以一条一条地输入命令。在输入过程中
出现错误,可用编辑命令进行修改。这里的编辑操
作同其他编辑软件(如 Word)的编辑操作没有什
么不同。当程序建立或修改完毕后,可用 Ctrl+W或
Ctrl+End存盘,退出编辑窗口。
要修改程序文件,选择“文件”菜单中的“打开”命
令打开文件即可。
Visual FoxPro
10
2,执行程序
(1)命令方式
使用 DO命令执行一个 Visual FoxPro程序文件或其它
文件。命令格式为:
DO <文件名 >
如果文件名不带扩展名,则 Visual FoxPro按下列顺序
寻找并执行这些程序:可执行文件 (.EXE)、应用程
序 (.app)、编译后的目标程序文件 (.fxp)和程序文件
(.prg)。
Visual FoxPro
11
9.2.1 程序文件中的辅助命令
1.程序注释命令
为增强程序的可读性,往往需要在程序中使用注释
来对程序进行说明,为阅读程序提供方便。 Visual
FoxPro中有两种程序注释命令。
命令格式:
NOTE|* [注释 ]
&& [注释 ]
第一个命令在程序中加注释行信息。执行程序文件
时,不执行以 NOTE或 *开头的行。如果要在下一行
继续注释,可在本注释行尾加上一个分号 ;,或者直
接回车再另用一个注释命令。
第二个命令在命令语句的尾部加注释信息。
9.2 顺序结构程序
Visual FoxPro
12
2.常用状态设置命令
( 1)置会话状态命令
命令格式:
SET TALK ON|OFF
在会话状态开通时,Visual FoxPro在执行命令时会
向用户提供大量的反馈信息。工作于程序方式时,
这不仅会减慢程序的运行速度,而且还会与程序本
身的输出相互夹杂,引起混淆。所以程序调试时,
一般置“会话”于开通状态,而在执行程序时则通
常要求置“会话”于断开状态。
Visual FoxPro
13
( 2)置打印状态命令
命令格式:
SET PRINT ON|OFF
系统默认打印机置于断开状态,就是说命令的
执行结果只送到屏幕,不送往打印机。若用命令
SET PRINT ON置打印机为接通状态,则在屏幕
上显示的执行结果被同时打印。
Visual FoxPro
14
( 3)置屏幕状态命令
命令格式:
SET CONSOLE ON|OFF
在系统的默认状态下,用户从键盘输入的内容都在
屏幕上显示,然而有时却要求键入的内容保密而不
被显示,这只需使用命令 SET CONSOLE OFF便可。
在应用程序中当用户键入密码的时就可先执行此命
令。
( 4)置缺省驱动器和目录命令
命令格式:
SET DEFAULT TO [盘符,][路径 ]
用于设置进行输入输出操作时的缺省驱动器和缺省
目录。
Visual FoxPro
15
9.2.2 交互式输入命令
1,字符串接收命令
字符串接收命令显示提示信息,等待用户从键盘输
入一个字符串并按回车键后,存入指定的内存变量
中。 命令格式为:
ACCEPT [<提示信息 >] TO <内存变量 >
其中 <提示信息 >可以是字符型内存变量、字符
串常量或合法的字符表达式。输入的数据不需要用
定界符括起来,ACCEPT命令总是将它作字符型数
据处理。
Visual FoxPro
16
例 在学生表中,需要按学号查询学生的姓名和入
学成绩。
CLEAR
SET TALK OFF
USE 学生
ACCEPT "请输入待查学生的编号," TO bh1
LOCATE FOR 学号 =bh1
DISP 学号,姓名,入学成绩
USE
SET TALK ON
RETURN
若输入的编号在学生表中不存在,程序并未反应,
因此程序需进一步完善。
Visual FoxPro
17
2,任意数据输入命令
命令格式:
INPUT [<提示信息 >] TO <内存变量 >
该命令与 ACCEPT命令的区别在于键入的数据类型不
同,它不仅可以接收字符型数据,还可以接收数值
型、日期型和逻辑型表达式的值。其中,对于字符
串的输入必须用定界符括起来,输入数值或表达式,
不加任何定界符;输入日期型数据,除使用日期型
的格式外,还要用大括号 {}将其括起来。例如
INPUT "请输入一个数值表达式," TO num
INPUT "请输入一个日期," TO dat
执行情况如下:
请输入一个数值表达式,98/10/10
请输入一个日期,{^1998-10-10}
Visual FoxPro
18
3,单个字符接收命令
命令格式:
WAIT [<提示信息 >] [TO <内存变量 >] [WINDOW
[NOWAIT]] [TIMEOUT <数值表达式 >]
命令暂停程序执行,等待用户键入任何一个字符后继
续。
使用说明:
(1) 当命令中包括 TO <内存变量 >可选项时,则定义
一个字符型内存变量,并将键入的一个字符存入该变
量中。
(2) 若只按回车键,则在内存变量中存入的内容将是
一个空字符。
(3) 若包含提示信息,则在屏幕上显示提示信息的内
容;若没有该选择项,则显示系统默认的提示信息:
Press any key to continue
Visual FoxPro
19
(4) 如果选择 WINDOW,则命令执行时,在 Visual
FoxPro主窗口的左上角会出现一个提示信息窗口,
有关提示信息便在此窗口中显示。
(5) 如果选择 NOWAIT,则 WAIT命令并不会暂停
程序的执行,而是仅在 Visual FoxPro主窗口的左上
角提示窗口中显示提示信息,并且用户只要一移动
鼠标或按下任意键,提示窗口便会自动被清除。NOWAIT必须与 WINDOW合用才有效果。
(6) TIMEOUT子句用于指定 WAIT命令等待的时间。
如果在由 <数值表达式 >所限定的秒数之内用户仍未
移动鼠标或按下任一键,则程序便继续执行。
WAIT只需用户按一个键,而不像 INPUT或
ACCEPT命令需要用回车键确认输入结束。因此,
WAIT命令的执行速度快,常用于等待用户对某个
问题的确认。
Visual FoxPro
20
9.2.3 格式输入输出命令的基本形式
Visual FoxPro提供了格式输入输出命令,这里先介
绍其基本用法。
1.格式输出命令的基本形式
命令格式:
@<行,列 > SAY <表达式 >
命令在指定位置输出表达式的值。
使用说明:
(1) <行,列 >指定了输出的位置。标准屏幕是 25行 80
列,左上角顶点为 (0,0),右下角坐标为 (24,79)。
(2) 行、列都可为表达式,还可为小数。
Visual FoxPro
21
2.格式输入命令的基本形式
命令格式:
@<行,列 > [SAY <提示信息 >] GET <变量 >
READ [SAVE] [CYCLE] [TIMEOUT <等待时间 >]
命令用 READ命令来激活当前所有的 GET变量,显
示并允许修改变量的值。
使用说明:
(1) SAY子句用于显示提示信息,GET子句用于为
变量输入新值。
(2) GET子句中的变量必须有确定的初值。初值决
定了该变量的类型和宽度。例如:
name=SPACE(8)
@5,10 SAY "请输入学生姓名 " GET name &&
name的宽度为 8个字符
READ
Visual FoxPro
22
(3) 激活 CET变量是指使该变量进入编辑状态,让
光标自动跳到该变量值所在位置上等待编辑修改。
若有多个 GET变量,则它们将依次被激活 (其中无须
修改的变量可按回车键越过 ),直至最后一个 GET变
量处理结束后,READ命令的作用才终止。如果在
READ命令中使用了 CYCLE可选项,则在编辑最后
一个 GET变量后,又回过去重新激活第一个 GET变
量,如此不断地循环,直至按 Ctrl+W(保存编辑内
容 )或按 Esc(舍弃编辑内容 )或执行命令 CLEAR
READ。
READ命令使用 TIMEOUT子句来约束执行命令的
等待时间 (以秒为单位 ),若超过了预定的等待时间
却还没有输入数据,则将中断 READ的执行。
Visual FoxPro
23
(4) 一般说来,已被激活过的 GET变量便被清除,
但若在 READ命令中带有可选项 ASVE,就不
做清除工作,当遇到下一个 READ命令时,这
些 GET变量将被再一次激活。
Visual FoxPro
24
9.3.1 双分支选择语句
语句格式:
IF <条件 >
<命令组 1>
[ELSE
<命令组 2>]
ENDIF
执行过程:
9.3 选择结构程序
Visual FoxPro
25
如果 <条件 >成立,就执行命令组 1,命令组 1执行完
成后就转到 ENDIF之后的命令。如果 <条件 >不成立,
当有 ELSE子句时,执行命令组 2,命令组 2执行完
成后转去执行 ENDIF之后的命令,当没有 ELSE子
句时,则直接转到 ENDIF之后的命令。
使用说明:
(1) 选择语句只能在程序中使用,正因为只能在程
序中使用,我们称之为语句,而不叫作命令。以后
其它语句也是这样。
(2) IF,ELSE,ENDIF必须各占一行。每一个 IF都
必须有一个 ENDIF与其对应,即 IF和 ENDIF必须成
对出现。
(3) <条件 >可以为关系表达式、逻辑表达式或其它
逻辑量。
(4) 命令组 1或命令组 2中可以包含 IF语句,即 IF语句
可以嵌套 。
Visual FoxPro
26
例 根据输入的学生姓名,在学生表中查找学生记录
SET TALK OFF
USE 学生
name=space(8)
@10,5 SAY "请输入学生姓名," GET name
READ
LOCATE FOR 姓名 =name &&在学生表中查找记录,xm是字段名
IF FOUND() &&判断是否找到。
DISPLAY &&找到,显示该记录
ELSE
@12,5 SAY "对不起,该单位无此人 !"
ENDIF
SET TALK ON
USE
RETURN
Visual FoxPro
27
9.3.2 多分支选择语句
语句格式:
DO CASE
CASE <条件 1>
<命令组 1>
CASE <条件 2>
<命令组 2>

[OTHERWISE
<命令组 n>]
ENDCASE
Visual FoxPro
28
执行过程:
在执行 DO CASE语句时,依次判断各 <条件 >是否
满足,若 <条件 >满足,就执行该条件后的命令组,
直到遇到下一个 CASE,OTHERWISE或
ENDCASE。命令组执行后不再判断其他条件,而
转向执行 ENDCASE后面的第一条命令。所以在一
个 DO CASE结构中,最多只能执行一个 CASE语句。
如果没有一个 <条件 >满足,就执行 OTHERWISE后
面的命令组,直到 ENDCASE。如果没有
OTHERWISE,则不作任何操作就转向 ENDCASE
之后的第一条命令。
Visual FoxPro
29
例 在学生表中,查询“周文杰”的记录,根据
其性别和年龄确定参加运动会的项目。
SET TALK OFF
USE 学生
LOCATE FOR 姓名 ="周文杰 "
IF,NOT.EOF()
DO CASE
CASE 性别 ="男 "
"请参加拔河比赛 "
Visual FoxPro
30
CASE 性别 ="女 " AND YEAR(DATE())-YEAR(出
生日期 )>25
"请参加投篮比赛 "
CASE 性别 ="女 " AND YEAR(DATE())-
YEAR(出生日期 )<=23
"请参加 1500米比赛 "
ENDCASE
ELSE
"该单位无此人 "
ENDIF
SET TALK ON
RETURN
Visual FoxPro
31
9.4.1 DO WHILE循环
语句格式:
DO WHILE <条件 >
<命令组 >
[EXIT]
[LOOP]
ENDDO
9.4 循环结构程序
Visual FoxPro
32
执行过程:
当给定的条件满足时,执行 DO WHILE和 ENDDO
之间的命令组。命令组执行完毕后,程序自动返回
到 DO WHILE语句,再一次判断 DO WHILE语句
中的 <条件 >。如果 <条件 >仍然满足,则再执行一遍
命令组,如果 <条件 >不满足,则结束循环,转去执
行 ENDDO之后的命令。
EXIT控制从循环体内跳出,转去执行 ENDDO后的
第一条命令,可把 EXIT放在循环体的任何地方。因
此 EXIT被称为无条件结束循环命令,只能在循环结
构中使用。
LOOP控制直接转回到 DO WHILE语句,而不执行
LOOP和 ENDDO之间的命令。因此 LOOP称为无条
件循环命令,只能在循环结构中使用。
Visual FoxPro
33
例 逐条输出学生表中 1984年出生的学生的记录。
CLEAR
USE 学生
INDEX ON YEAR(出生日期 ) TAG csrqsy
SEEK 1984
DO WHILE YEAR(出生日期 )=1984
DISPLAY
SKIP
ENDDO
USE
RETURN
Visual FoxPro
34
例 求 1~ 100之间全部奇数之和
SET TALK OFF
STORE 0 TO x,y
DO WHILE,T.
x=x+1
DO CASE
CASE INT(x/2)=x/2
LOOP
CASE x>=100
EXIT
OTHERWISE
y=y+x
ENDCASE
ENDDO
"0~ 100之间的奇数之和为,",y
SET TALK ON
RETURN
Visual FoxPro
35
9.4.2 FOR循环
语句格式:
FOR <循环变量 >=<初值 > TO <终值 > [STEP <
步长值 >]
<命令组 >
[EXIT]
[LOOP]
ENDFOR|NEXT
Visual FoxPro
36
执行过程:
首先计算初值、终值和步长值,并将初值赋给循环
变量,再将循环变量的值与终值比较,如果循环变
量的值在初值与终值范围内,则执行 FOR与
ENDFOR之间的命令,然后循环变量按步长值增加
或减小,再重新比较,直到循环变量的值不在初值
与终值范围内,结束循环,转去执行 ENDFOR后面
的第一条命令。
Visual FoxPro
37
使用说明:
(1) FOR,ENDFOR|NEXT必须各占一行,且它们
必须成对出现。
(2) 循环变量可以是一个内存变量或数组元素。如
果在 FOR…ENDFOR 之间改变循环变量的值,将影
响循环执行的次数。
(3) <初值 >,<终值 >和 <步长值 >均为数值型表达式。
如果省略 STEP子句,则默认步长值是 1。
(4) 退出循环后,循环变量的值等于最后一次循环
时的值为加上步长值。
(5) LOOP语句和 EXIT语句的功能与前面的当型循
环语句相同 。
Visual FoxPro
38
9.4.3 SCAN循环
语句格式:
SCAN [<范围 >] [FOR <条件 >] [WHILE <条件 >]
<命令组 >
[EXIT]
[LOOP]
ENDSCAN
Visual FoxPro
39
执行过程:
首先将表记录指针移动到指定范围内的第一条记录
上,然后判断记录指针是否超过指定范围以及该记
录是否满足 WHILE子句所描述的条件,若记录指
针超过指定范围或该记录不满足 WHILE子句所描
述的条件,则结束扫描循环,执行 ENDSCAN后面
的语句。若记录指针未超过指定范围且该记录满足
WHILE子句所描述的条件,则判断该记录是否满
足 FOR子句所描述的条件,若不满足,记录指针移
到下一条记录,进行下一轮循环判断,否则执行命
令组后,记录指针下移一条记录,再进行下一轮循
环判断。
Visual FoxPro
40
使用说明:
(1) 对指定范围内满足条件的记录执行命令组。若
省略范围,则默认为 ALL。
(2) SCAN语句自动把记录指针移向下一个符合指定
条件的记录,并执行同样的命令组。
(3) LOOP语句和 EXIT语句的功能与前面的当型循
环语句相同 。
Visual FoxPro
41
例 对学生表,分别统计少数民族男、女学生的人数。
CLEAR
STORE 0 TO x,y
USE 学生
SCAN FOR 少数民族否
IF 性别 ="男 "
x=x+1
ELSE
y=y+1
ENDIF
ENDSCAN
"少数民族男生有,"+STR(x,2)+"人 "
"少数民族女生有,"+STR(y,2)+"人 "
USE
RETURN
Visual FoxPro
42
9.4.4 程序举例
例 某集团公司下属 6个分公司,各分公司均已建立
了各自的人事档案表,表结构相同,表文件名分别
为 rsda1.dbf,rsda2.dbf,…, rsda6.dbf。现要求统
计各公司会计师、经济师和其他人员的人数。
点击查看程序请
Visual FoxPro
43
9.5.1 子程序、过程和函数
1.子程序
(1)子程序的结构。 在 Visual FoxPro程序文件中,可
以通过 DO命令调用另一个程序文件,此时,被调
用的程序文件就称为子程序。子程序的结构与一般
的程序文件一样,而且也可以用 MODIFY
COMMAND命令来建立、修改和存盘,扩展名也
默认为,PRG。
子程序和其他程序文件的惟一区别是其末尾或返回
处必须有返回语句。
9.5 程序的模块化
Visual FoxPro
44
命令格式:
RETURN [TO MASTER|TO <程序文件名 >|<表达
式 >]
命令功能:
中止一个程序、过程或用户定义函数的执行,返回
到上一级调用程序、最高级调用程序、另外一个程
序或者命令窗口。
Visual FoxPro
45
使用说明:
①若程序是被另一个程序调用的,遇到 RETURN时,
则自动返回到上级调用程序。如果是在最高一级主
程序中,遇到 RETURN时,则返回到命令窗口。
②选用 TO MASTER子句时,则返回到最高一级调
用程序,即在命令窗口下,调用的第一个主程序。
③在程序最后,如果没有 RETURN命令,则程序运
行完后,将自动默认执行一个 RETURN命令,但过
程文件除外。
Visual FoxPro
46
④ 执行 RETURN命令时,释放本程序所建立的局部
变量,恢复用 PRIVATE隐藏起来的内存变量。
⑤ TO <程序名 >表示将控制权交给指定的程序。
⑥ RETURN <表达式 >表示将表达式的值返回调用
程序,用于自定义函数。
Visual FoxPro
47
(2) 子程序的调用。 子程序调用命令与主程序执行
命令相同,其 格式 都为:
DO <程序文件名 >|<过程名 > [WITH <参数表 >]
其中,WITH <参数表 >子句指定传递到程序或过程的
参数,在 <参数表 >中列出的参数可以是表达式、内
存变量、常量、字段名或用户定义函数。可把参数
放在圆括号中,各参数用逗号分隔。传递给一个程
序的参数最多为 24个。
Visual FoxPro
48
(3) 子程序的嵌套调用。 主程序可以调用子程序,
子程序还可以调用另外的子程序,这就是子程序的
嵌套调用。实际上,子程序和主程序都是相对的,
任何一个程序可以调用其它程序,也可以被其他程
序调用。每个被调用程序的末尾或返回处都要加上
RETURN命令。
一个程序或子程序遇到调用子程序命令就转去执行
子程序,而本程序的余下部分要等从子程序返回后
才得以继续执行。
如果在某一个子程序的 RETURN命令中使用 TO
MASTER短语,则从此子程序直接返回到第一级主
程序,其间子程序 DO命令以下的命令均不执行。
在主程序中也可以使用 RETURN命令,它将清除内
存变量,使程序退回到命令窗口。 RETURN命令也
可以作为每个程序的结束标志。
Visual FoxPro
49
2.自定义函数
(1)自定义函数的结构。 一个自定义函数实际上就是
一个子程序,惟一的差别是在 RETURN语句后带有
表达式,以指出函数的返回值。
自定义函数的格式:
[FUNCTION <函数名 >]
[PARAMETERS <参数表 >]
<命令组 >
RETURN [<表达式 >]
Visual FoxPro
50
使用说明:
①若不写 FUNCTION <函数名 >选项,则表明该自
定义函数是一个独立的程序文件。若写上该选项,
则表明该自定义函数不能作为一个独立的程序文件,
而只能放在某程序中。
②如果自定义函数名与 Visual FoxPro的内部函数名
相同,系统只承认内部函数,因此不能用内部函数
名来命名自定义函数。
③若自定义函数中包含自变量,程序的第一行必须
是参数定义命令 PARAMETERS。
Visual FoxPro
51
④ 自定义函数除了可以作为一个函数被其它程
序调用外,还可用 DO <文件名 >的形式来执行,
在这种情况下,它不是作为函数,而是作为程
序或过程来运行,它的 RETURN语句中的 <表
达式 >相应地不起作用。
⑤自定义函数的数据类型取决于 RETURN语句
中 <表达式 >的数据类型。如果省略 <表达式 >,
则返回,T.。
Visual FoxPro
52
(2)自定义函数的调用。 自定义函数的调用形式是:
<函数名 >(<自变量表 >)
其中,自变量可以是任何合法的表达式,自变量的
个数必须与自定义函数中 PARAMETERS语句里的
变量个数相等,自变量的数据类型也应符合自定义
函数的要求。
Visual FoxPro
53
例 定义一个判断 n是否素数的函数,然后调用该函
数求 2~ 1000内的全部素数。
*prime.prg判断 n是否素数的函数
PARAMETERS n
flag=.T.
k=INT(SQRT(n))
j=2
DO WHILE j<=k,AND,flag
IF MOD(n,j)=0
flag=.F.
ENDIF
j=j+1
ENDDO
RETURN flag
Visual FoxPro
54
*main.prg调用该函数求 2~ 1000内的全部素数
FOR m=2 TO 1000
IF prime(m)
m
ENDIF
ENDFOR
CANCEL
Visual FoxPro
55
3.过程与过程文件
(1)过程的结构。 过程的一般格式是:
PROCEDURE <过程名 >
[PARAMETERS <参数表 >]
<命令组 >
RETURN
Visual FoxPro
56
使用说明:
①每一个过程均以 PROCEDURE开始,以 RETURN
结束。每个过程实际上是一个独立的子程序或一个
用户定义函数。
② PROCEDURE <过程名 >用于过程的第一条语句,
它标识了每个过程的开始,同时定义了过程名。
③过程如果以 RETURN <表达式 >作为结束语句,那
么该过程既可用 DO <过程名 >的形式执行,又可当
做一个合法的自定义函数,可供随时调用。
Visual FoxPro
57
例 使用带传递参数的过程调用方式计算三角形面积
SET TALK OFF
area=0
STORE,T,TO rep
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
Visual FoxPro
58
rep=.F.
ENDDO
DO sub WITH x,y,z,area
"Area="+STR(area,6,2)
RETURN
PROCEDURE sub
PARAMETER a,b,c,s
p=(a+b+c)/2
s=SQRT(p*(p-a)*(p-b)*(p-c))
RETURN
Visual FoxPro
59
(2)过程文件。 一个过程可以以文件形式单独存在,
也可以将多个过程合并到一个文件中,这个文件称
为过程文件。在过程文件中,每个过程仍然是独立
的,可以单独调用。
由于过程文件是将许多过程集中起来以一个文件的
形式存储在磁盘上的,当打开一个过程文件时,该
过程文件中的所有过程即同时被打开,关闭一个过
程文件时,过程文件中的所有过程也同时被关闭,
从而大大减少访问磁盘的次数,提高程序运行速度
过程文件也是程序文件,同其它程序文件一样,
可以用 MODIFY COMMAND命令或其它文字编辑
软件进行编辑。
Visual FoxPro
60
例 假设有三个过程,p1,p2,p3,把它们组织到过程
文件 proc.prg中。
* proc.prg过程文件
PROCEDURE p1
"过程 p1"
RETURN
PROCENURE p2
"过程 p2"
RETURN
PROCEDURE p3
"过程 p3"
RETURN
Visual FoxPro
61
(3)过程文件的打开与关闭。 在过程文件被打开之前,
过程文件中所包含的过程是不能被任何程序调用的,
因此,在调用过程前,先要打开过程文件。
命令格式:
SET PROCEDURE TO [<过程文件名 >]
命令功能:
打开一个过程文件。
Visual FoxPro
62
使用说明:
①任一时刻只能有一个被打开的过程文件,因此,每
次打开过程文件时自动关闭先前打开的过程文件。过
程文件被打开后,它所包括的过程便可被其它程序调
用。调用时与子程序一样,仍使用 DO命令。
②打开过程文件命令在主程序中使用,一般应放在程
序的前部,循环的外面,至少应放在调用过程文件中的过程命令之前。
③也可把打开过程文件的主程序与过程合在一起,组
成一个磁盘文件。但主程序必须在文件中的开始位置,
这样才能在主程序中直接调用过程。
④过程文件使用完后,要及时关闭,以释放它们占用
的内存空间。关闭过程文件可以使用下列两条命令:
SET PROCEDURE TO
CLOSE PROCEDURE
Visual FoxPro
63
9.5.2 内存变量的作用域
1,全局内存变量
全局内存变量是指在上、下各级程序中都有效的内
存变量。全局变量就像在一个程序中定义的变量一
样,可以任意改变和引用,当程序执行完后,其值
仍然保存。若欲清除这种变量,必须用 RELEASE
命令。定义全局变量需用下面的命令 。
Visual FoxPro
64
命令格式 1:
PUBLIC <内存变量表 >|ALL|ALL LINK <通配符
>|ALL EXCEPT <通配符 >
命令格式 2:
PUBLIC [ARRAY] <数组名 >(<下标上界 1>[,<下标
上界 2>])[,<数组名 >(<下标上界 1>[,<下标上界 2>]),…]
命令功能:
定义全局内存变量或数组。
Visual FoxPro
65
使用说明:
① <内存变量表 >中可以包含普通变量,也可以包含
数组变量。
②任何全局内存变量或数组必须先定义,后赋值。
反之,如果程序中已给一个内存变量或数组赋值,
或者已用 DIMENSION建立了数组,再用 PUBLIC
将其定义为全局变量或数组将产生错误。
③定义后尚未赋值的全局变量其值为逻辑值,F.。
④使用 ALL选择项时,定义所有内存变量;使用
ALL LINK <通配符 >时,定义所有变量名与 <通配
符 >匹配的内存变量;使用 ALL EXCEPT <通配符 >
时,定义所有变量名不与 <通配符 >匹配的内存变量。
<通配符 >中允许用?和 *。
Visual FoxPro
66
⑤ 全局变量在程序结束时不释放,即使主程序也是
这样。
⑥当进入下一级子程序时,已在上级由 PUBLIC说
明过的与之同名的内存变量可以用 PRIVATE命令
暂时隐藏起来,作为本级程序的局部变量使用。待
本级子程序结束返回上一级程序后,便释放它们作
为本级程序的局部变量特性,恢复它们全局变量的
特性和内容。
⑦在命令窗口中建立的所有内存变量或者数组自动
定义为全局型。
⑧命令格式 2可以定义数组,其规则与 DIMENSION
命令相同 。
Visual FoxPro
67
2.局部内存变量
局部内存变量只能在定义它的程序及其下级程序中
使用,一旦定义它的程序运行结束,它便自动被清
除。也就是说,在某一级程序中定义的局部变量,
不能进入其上级程序使用,但可以到其下级程序中
使用,而且当在下级程序中改变了该变量的值时,
在返回本级程序时被改变的值仍然保存,本级程序
可以继续使用改变后的变量值。
Visual FoxPro
68
例 分析下列程序的执行情况
*主程序 main.prg
r=100
DO sub
p
RETURN
*子程序 sub.prg
p=2*3.14*r
RETURN
Visual FoxPro
69
3.隐藏内存变量
命令格式:
PRIVATE <内存变量表 >|ALL|ALL LIKE <通配符
>|ALL EXCEPT <通配符 >
命令功能:
隐藏当前程序中指定的内存变量或数组。
Visual FoxPro
70
使用说明:
① <内存变量表 >指出需要隐藏的内存变量。
②对 PRIVATE中内存变量的修改并不影响上级程序
中与之同名的内存变量的值。此命令只对本级程序
及以下各级子程序有效,当返回到上级程序时,被
PRIVATE隐藏的当前程序中的内存变量自动被删除
③在它们被隐藏期间,程序就不能再调用这些被隐
藏的上级内存变量,但实际上它们仍然存在,一旦
含有 PRIVATE内存变量的程序结束后,被
PRIVATE隐藏起来的哪些以前建立的同名的上级内
存变量自动恢复以前的内容和状态。
Visual FoxPro
71
例 写出下列程序的输出
r=100
p=10
DO sub
p
RETURN
PROCEDURE sub
PRIVATE p
p=2*3.14*r
RETURN
Visual FoxPro
72
9.5.3 调用子程序时的数据传递
1.利用变量的作用域实现数据传递
合理地利用前面介绍的内存变量作用域特性,可以
实现调用子程序时的数据传递。
例 计算矩形面积的程序。
* main.prg主程序
gao=8
kuan=6
c=0
DO sub
c
CANCEL
* sub.prg子程序
c=gao*kuan
RETURN
Visual FoxPro
73
2.利用参数实现数据传递
命令格式:
PARAMETERS <内存变量表 >
命令功能:
指定子程序中的局部变量名,并由这些局部变量接
收上级程序中用 DO…WITH < 参数表 >传递来的参
数,将其依次赋给 <内存变量表 >中的各局部变量,
也可以回送子程序运行的结果。
充当传递数据的主程序中的内存变量也称作实际参
变量。子程序 PARAMETERS中与之相对应的参变
量称形式参变量。
Visual FoxPro
74
使用说明:
(1) 该命令必须放在本级程序的首行。
(2) 必须和 DO…WITH 配合使用。 <内存变量表 >中
变量的个数要与上级程序中的 WITH <参数表 >中的
参数个数相同。各变量用逗号分隔,最多能传递 24
个参数。
(3) 变量类型自动与上级程序中的参数相匹配。
Visual FoxPro
75
(4) 参数传递有两种方式:值传递和地址传递。
如果使用值传递方式,则子程序中参数变化后
的值不回传给上级调用程序。如果使用地址传
递方式,则子程序中参数变化后的值要回传给
上级调用程序。常量和表达式只能使用值传递
方式,内存变量既可以使用值传递方式,又可
以使用地址传递方式。使用值传递方式的变量
要用括号括起来,使用地址传递方式的变量不
加括号。如果不允许子程序改变传递参数变量
的值,应该使用值传递方式。如果允许子程序
改变传递参数变量的值,则要使用地址传递方
式。
Visual FoxPro
76
(5) 在自定义函数中,仍然使用 PARAMETER语句
接收上级调用程序传递来的参数。不过,在自定义
函数中,默认的参数传递方式是值传递方式。要改
变参数的传递方式,需要使用命令:
SET UDFPARMS TO VALUE|REFERENCE
该命令用于设置参数传递方式。选择 VALUE,按
值传递方式传递参数,选择 PREFERENCE,按地
址传递方式传递参数。
Visual FoxPro
77
例 写出下列程序的输出
SET TALK OFF
x=1
y=3
DO sub WITH x,(y),5
x,y
RETURN
PROCEDURE sub
PARAMETER a,b,c
a=a+b+c
b=a+b-c
RETURN
Visual FoxPro
78
程序调试就是确定程序出错的位置,然后加以改
正,一直到达到预定的设计要求为止。程序调试往往
是先分模块调试,当各模块都调试通过以后,再联合
起来进行调试,通过联调后,便可试运行,试运行无
误即可投入正常使用。
9.6.1 程序调试概述
9.6 程序调试
Visual FoxPro
79
程序的错误有两类,语法错误和逻辑错误。
语法错误 相对容易发现和修改,当程序运行遇到这类
错误时,Visual FoxPro会自动中断程序的执行,并弹
出编辑窗口,显示出错的命令行,给出出错信息,这
时可以方便地修改错误。
逻辑错误 就不那么容易发现了,这类错误系统是无法
确定的,只有由用户自己来查错。这时往往需要跟踪
程序的执行,在动态执行过程中监视并找出程序中的
错误。
Visual FoxPro
80
9.6.2 调试器窗口
选择, 工具, 菜单中的, 调试器, 命令或在命令窗口
输入 DEBUG命令, 系统打开调试器窗口 。 在 Visual
FoxPro调试器窗口中, 选择, 窗口, 菜单中的相应
命令可有选择地打开 5个子窗口:跟踪, 监视, 局
部, 调用堆栈和调试输出 。 要关闭子窗口, 只需单
击窗口右上方的关闭按钮 。
Visual FoxPro
81
1,跟踪窗口
跟踪窗口用于显示正在调试执行的程序文件 。 要
打开一个需要调试的程序, 可从调试器窗口的
,文件, 菜单中选择, 打开, 命令, 然后在打开
的对话框中选定所需的程序文件 。 被选中的程序
文件将显示在跟踪窗口里, 以便调试和观察 。
Visual FoxPro
82
跟踪窗口左端的灰色区域会显示某些符号, 常见的符
号及其意义如下:
?,指向调试中正在执行的代码行 。
●, 断点 。 可以在某些代码行处设置断点, 当程序执
行到该代码行时, 中断程序执行 。
可以控制跟踪窗口中的代码是否显示行号, 方法是:
在 Visual FoxPro系统, 选项, 对话框的, 调试, 选
项卡中选择, 跟踪, 单选按钮, 然后设置, 显示行
号, 复选框 。
Visual FoxPro
83
2,监视窗口
监视窗口用于监视指定表达式在程序调试执行过程中
的取值变化情况 。 要设置一个监视表达式, 可单击
窗口中的, 监视, 文本框, 然后输入表达式的内容,
按回车键后表达式便添入文本框下方的列表框中 。
当程序调试执行时, 列表框内将显示所有监视表达
式的名称, 当前值及类型 。
双击列表框中的某个监视表式就可对它进行编辑 。 右
键单击列表框中的某个监视表达式, 然后在弹出的
快捷菜单选择, 删除监视, 可删除一个监视表达式 。
在监视窗口中可以设置表达式类型的断点 。
Visual FoxPro
84
3,局部窗口
局部窗口用于显示模块程序 ( 程序, 过程和方法程序 )
中的内存变量 ( 简单变量, 数组, 对象 ), 显示它
们的名称, 当前取值和类型 。
可以从, 位置, 下拉列表框中选择指定一个模块程序,
下方的列表框内将显示在该模块程序内有效 ( 可视 )
的内存变量的当前情况 。
单击局部窗口, 然后在弹出的快捷菜单中选择, 公
共,,, 局部,,, 常用, 或, 对象, 等命令, 可
以控制在列表框内显示的变量种类 。
Visual FoxPro
85
4,调用堆栈窗口
调用堆栈窗口用于显示当前处于执行状态的程序, 过
程或方法程序 。 若正在执行的程序是一个子程序,
那么主程序和子程序的名称都会显示在该窗口中 。
模块程序名称的左侧往往会显示一些符号, 常见的符
号及其意义如下:
调用顺序序号,序号小的模块程序处于上层, 是调用
程序 。 序号大的模块程序处于下层, 是被调用程序,
序号最大的模块程序也就是当前正在执行的模块程
序 。
当前行指示器 ( ?), 指向当前正在执行的行所在的
模块程序 。
从快捷菜单中选择, 原位置, 和, 当前过程, 命令可
以控制上述两个符号是否显示 。
Visual FoxPro
86
5,调试输出窗口
可以在模块程序中设置一些 DEBUGOUT命令, 其格
式是:
DEBUGOUT <表达式 >
当模块程序调试执行到此命令时, 会计算出表达式的
值, 并将计算结果送入调试输出窗口 。
为了区别于 DEBUG命令, 命令动 DEBUGOUT至少要
写出 6个字母 。
若要把调试输出窗口中的内容保存到一个文本文件里,
可以选择调试器窗口, 文件, 菜单中的, 另存输出,
命令, 或选择快捷菜单中, 另存为, 命令 。 要清除
该窗口中的内容, 可选择快捷菜单中的, 清除, 命
令 。
Visual FoxPro
87
9.6.3 设置断点
在调试器窗口可以设置以下 4种类型的断点:
类型 1,在定位处中断 。 可以指定一代码行, 当程序
调试执行到该代码时中断程序运行 。
类型 2,如果表达式值为真则在定位处中断 。 指定一
代码行以及一个表达式, 当程序调试执行到该行代
码时如果表达式的值为真, 就中断程序运行 。
类型 3,当表达式值为真时中断 。 可以指定一个表达
式, 在程序调试执行过程中, 当该表达式值改成真
时中断程序运行 。
类型 4,当表达式值改变时中断 。 指定一个表达式,
在程序调试执行过程中, 当该表达式值改变时中断
程序运行 。
不同类型断点的设置方法大致相同, 也有一些区别 。
Visual FoxPro
88
1,设置类型 1断点
在跟踪窗口中找到要设置断点的那行代码, 然后双击
该行代码左端的灰色区域, 或先将光标定位于该行
代码中, 然后按 F9键 。 设置断点后, 该代码行左端
的灰色区域会显示一个实心圆点 。 用同样的方法可
以取消已经设置的断点 。
也可以在, 断点, 对话框中设置该类断点, 其方法与
设置类型 2断点的方法类似 。
Visual FoxPro
89
2,设置类型 2断点
在调试器窗口中, 选择, 工具, 菜单上的, 断点, 命
令, 打开, 断点, 对话框, 如图 9.8所示, 从, 类型,
下拉列表中选择相应的断点类型 。 在, 定位, 框中
输入适当的断点位置, 例如 lpp,2表示在模块程序
lpp的第 2行处设置断点 。 在, 文件, 框中指定模块
程序所在的文件 。 文件可以是程序文件, 过程文件,
表单文件等 。 在, 表达式, 框中输入相应的表达式 。
单击, 添加, 按钮, 将该断点添加到, 断点, 列表
框里, 单击, 确定, 按钮 。
Visual FoxPro
90
“断点”
对话框
Visual FoxPro
91
与类型 1断点相同, 类型 2断点在跟踪窗口的指定位置
上也有一个实心点 。 要取消类型 2断点, 可以采用
与取消类型 1断点相同的方法, 也可以先在, 断点,
对话框的, 断点, 列表中选择断点, 然后单击, 删
除, 按钮 。 后者适合于所有类型断点的删除 。
在设置该类断点时, 如果觉得, 定位, 框和, 文件,
框的内容不大好指定, 也可以采用下面的方法进行:
在所需位置上设置一个类型 1断点, 在, 断点, 对话
框的, 断点, 列表框内选择该断点, 重新设置类型
并指定表达式 。 单击, 添加, 按钮, 添加新的断点,
选择原先设置的类型 1断点, 单击, 删除, 按钮 。
Visual FoxPro
92
3,设置类型 3断点
在调试器窗口中, 选择, 工具, 菜单上的, 断点, 命
令, 打开, 断点, 对话框 。 从, 类型, 下拉列表中
选择相应的断点类型, 在, 表达式, 框中输入相应
的表达式, 单击, 添加, 按钮, 将该断点添加到
,断点, 表列框里 。
Visual FoxPro
93
4,设置类型 4断点
如果所需的表达式已经作为监视表达式在监视窗口中
指定, 那么可在监视窗口的列表框中找到该表达式,
然后双击表达式左端的灰色区域 。 这样就设置一个
基于该表达式的类型 4断点, 灰色区域上会有一个
实心圆点 。
如果所需的表达式没有作为监视表达式在监视窗口中
指定, 那么可以采用与设置类型 3断点相似的方法
设置该类断点 。