第 5 章 程序
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
基础
前面介绍过 VFP 的工作方式有两类,一类为交互式工作方式,另一类为自
动工作方式。交互式工作方式是直接在命令窗口执行命令或用菜单及工具栏按钮
执行命令。自动工作方式是用编写的程序或用各种生成器生成程序文件再执行。
交互式工作方式在前几章已用到过,它的特点是简单方便易掌握。但对于较为复
杂的问题用这种方式解决效率很低,重复使用的命令需要一条条重复输入,有时
甚至无法实现。而自动工作方式它可以通过已编制好的文件程序命令自动成批执
行,它使复杂的问题得到解决。VFP 支持结构化与面向对象的两种方式的程序设
计,结构化程序设计是面向对象程序设计的基础,因此本章介绍结构化程序设计、
面向对象程序设计在后继章节中介绍。
5.1 程序文件的建立、修改、执行
5.1.1 程序
程序是能够完成一定任务命令的有序集合。将程序以文件形式存放到硬盘上
的文件称为程序文件。程序文件默认的扩展名为“.prg”。
5.1.2 程序文件的建立
建立程序文件有三步:
(1)打开程序编辑器;
(2)在程序编辑器中输入并编辑程序;
(3)保存程序。
1. 用界面方式建立程序
(1)打开程序编辑器。文件菜单→新建或使用工具栏中的新建按钮→打开新建
对话框→在文件类型→程序→新建文件,打开程序编辑器。
(2)在程序编辑器中输入并编辑程序。
(3)保存程序文件。文件→保存或使用工具栏上的保存按钮或 Ctrl+W,打开
另存对话框→输入文件名→保存
2.用命令方式建立程序文件
格式:MODIFY COMMAND [<文件名> | ?]
功能:打开程序编辑器,用于建立或修改程序文件。
说明:(1)若无选项,将打开程序编辑器指定一个初始名为 X.PRQ 的程序,
当编辑器关闭时,则另存为其它名。(2)打开对话框,选一个已存在的程序文件
名或输入一个新的程序文件名。
5.1.3 程序文件的修改
修改文件也需三步:
(1)打开要修改的程序文件。
(2)在编辑器中修改程序文件。
(3)保存修改后的程序文件。
1.打开程序文件
(1)文件→打开,打开对话框→在文件类型列
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
框选择程序→在文件列表框中
选择要修改的程序文件→确定。
(2)在程序编辑器中修改程序文件。
(3)保存已修改的程序文件。
2.用命令方式修改程序文件
修改程序文件的命令与文件建立命令相同。
5.1.4 程序文件的执行
1.用界面方式执行程序文件
程序→运行,打开运行对话框→从文件列表框中选择需要运行的程序文件。
或在程序编辑器打开时单击工具栏中的运行按钮。
2.用命令方式执行程序文件
格式:DO <文件名>
功能:执行指定文件名的程序文件
5.1.5 程序的书写
规则
编码规则下载淘宝规则下载天猫规则下载麻将竞赛规则pdf麻将竞赛规则pdf
一个程序是由若干行组成,每行由回车键(Enter)结束.
1.命令行:一个命令可以写在一行也可以分多行书写,分行书写时应该在
行末尾加续行号,VFP 续行号为“;”然后以回车键结束本行。
2.命令的注释:VFP 注释有&&,*,NOTE 三种,是非执行命令。
格式 1:&& [<注释内容>]
格式 2:* [<注释内容>]
格式 3:NOTE [<注释内容>]
功能:为程序注释,为非执行语句。
说明:格式 1 为行尾注释,即可写在命令行的尾部。格式 2 与格式 3 为行首
注释,即以*和 NOTE 开始的行都为注释。
例 5.1 在学生库中,查找 VFP 与 C 的成绩大于 90 分的学生的学号,姓名以
及课程 VFP 与 C 语言的成绩。
程序设计:
*查询程序 p5_1.prg
open database 学生 &&打开学生数据库
select 学生.学号, 学生.姓名, 学生成绩.vfp, 学生成绩 f.c;
where 学生.学号=学生成绩.学号 and 学生.学号=学生成绩 f.学号 and;
学生成绩.vfp>=90 AND 学生成绩 f.c>=90; &&命令分行书写要加分号
from 学生, 学生成绩, 学生成绩 f && select 命令结束
close database all && 关闭数据库
执行结果:
图 5.1 例 5.1 执行结果
5.1.6 调试命令与辅助命令
1.SET TALK 命令
格式:SET TALK ON | OFF
功能:设置命令在执行过程中的状态信息,ON 为显示命令(是默认值),
OFF 为不显示命令。
如:copy files 学生.* TO *.*命令,若命令设为 ON 则会显示复制过程中复制
的几个文件的信息。若命令设置为 OFF 则无信息。
2. CANCEL 命令
格式:CANCEL
功能:终止程序运行,清除所有私有变量,返回到命令窗口,有关私有变量
的概念在本章后面将会详细介绍。
3.RETURN 命令
格式:RETURN
功能:结束当前程序执行返回到调用它的上级程序,若无上级调用程序则返
回到命令窗口。
4.QUIT 命令
格式:QUIT
功能:退出 VFP 系统,返回 WINDOWS 操作系统。
5.2 输入与输出命令
5.2.1 输入命令
1. INPUT 命令
格式:INPUT [<字符表达式>] TO [<内存变量>]
功能:用来从键盘输入数据,回车后将数据赋给内存变量。
说明: (1)<字符表达式>为提示信息。
(2)输入的数据可为,常量,变量,表达式。
(3)输入 C,L,D 型常量时要用定界符。
例 5.2 编程查找指定姓名,学号,性别,数学成绩。
程序设计:
*p5_2.prg
open database 学生
input "输入姓名:" to xm
select 学生.学号, 学生.姓名, 学生成绩.数学 from 学生, 学生成绩;
where 学生.姓名=xm and 学生成绩.学号=学生.学号
close database all
return
执行结果:
图 5.2 例 5.2 执行结果
2.ACCEPT 命令
格式:ACCEPT [<字符表达式>] TO [<内存变量>]
功能:从键盘输入字符串数据,赋给内存变量。
说明: (1)<字符表达式>为提示信息。
(2)输入的字符串不需加定界符,否则会将定界符作为字符串的一部
分。
(3)若不输入数据,将空串赋给变量。
3.WAIT 命令
格式:WAIT <字符表达式>] TO [<内存变量>] [WINDOW IAT <行,列>]
[NOWAIT ] [CLEAR|NOCLEAR][TIMEOUT<数值表达式>]
功能:暂停程序运行,字符表达式为提示信息,待小键盘输入一个字符赋给
内存变量,程序继续执行。
说明: (1)省略[<字符表达式>]则显示默认信息,按任意键继续…。
(2)[TO <内存变量>]中内容为空串,省略此项,输入字符不保存。
(3)[WINDOIAT<行,列>]提示信息窗口在屏幕上的位置,省略 AT<
行,列>信息将显示在屏幕的右上角。
(4)[NOWAIT ]不等待输入直接往下执行。
(5)CLEAR 清除提示信息窗口,NOCLEAR 不清除提示信息窗口,
直到执行一条 WAIT WINDOW 命令或 WAIT CLEAR 命令为止。
(6)[TIMEOUT<数值表达式>]由数值表达式指定等待输入的秒数。若
超出秒数,则不等待自动往下执行。
例 5.3 WAIT 的应用
*p5_3.prg
wait "继续? " to x window time 10
执行结果:
图 5.3 例 5.3 执行结果
5.2.2 输出命令
在前面曾介绍了?和??输出命令,下面再介绍一条可以完成输入输出两个功能
命令。
格式:@<行,列> [SAY <表达式>] [GET <变量名>] [DEFAULT <表达式>]
功能:在屏幕的指定行列输出表达式的值并修改内存变量的值。
说明:(1)<行,列>,行自上而下编号,列自左至右编号,编号从 0 开始,
行列可以使用小数精确定位。
(2)省略 SAY 选项 GET 变量值在行列指定位置开始显示,若选 SAY 选项,
先显示表达式的值,然后再显示 GET 变量值。
(3)GET 中的变量必须右初值或用[DEFAULT<表达式>]中的<表达式>命令定
值。
(4)GET 选项必须用 READ 命令操作。
例 5.4 编程:查找学生成绩大于等于指定成绩的或数学大于等于指定分数
的学生学号,姓名,入学成绩,数学成绩。
程序设计:
*p5_4.prg
clear
open database 学生
@ 10,10 say "输入入学成绩:" get yc default 0
@ 10,10 say "输入数学分数:" get sf default 0
read
@ 10, 10 say "指定入学成绩为:"+str(yc)+"指定数学分" +str(sf)
select 学生.学号, 学生.姓名, 学生.入学成绩, 学生成绩.数学;
from 学生, 学生成绩 where 学生.入学成绩>=yc and 学生成绩.数学>=SF;
and 学生.学号=学生成绩.学号
close database all
return
执行结果:
图 5.4 例 5.4 执行结果
5.3 程序的基本结构
程序设计一般采用顺序,条件,循环这三种基本结构,这三种结构贯穿于整
个程序的设计中。
5.3.1 三种基本结构与算法
结构化程序设计一般采用顺序、选择、循环 3 种基本结构,为了能使读者对
这 3 种结果有一个直观的理解,介绍一下程序的流程框图(见图 5.5)。
开始与结束 准备 判断 联系
流线 输入输出
图 5.5 流程框图
流程框图的作用是可以直观的描述出程序的走向,下面用流程框图介绍 3
种基本结构:
1. 顺序结构
顺序结构,就是程序是按语句排列的先后顺序来执行。如图 5.6 所示,先执
行 A,再执行 B。
A
B
5.2 图顺序结构
2.选择结构
条件为真执行一部分语句,否则执行另一部分语句。如图 5.7(a)图所示。若
条件为真执行 A,否则执行 B。
真
假
B
条件
A
图 5.7(a) 普通选择结构
在选择结构中还有一种称为多分支选择结构,如图 5.7(b)所示。依次判断条
件,若条件 1 为真执行 A1,否则判断条件 2,若条件 2 为真执行 A2……若所有
所有条件为假,执行 An。
真
真
真
假
假
假
条件 1
条件 2
条件 n
A1
A2
An
图 5.7(b) 多分支选择结构
3.循环结构
当条件为真执行循环体,否则结束循环,如图 5.8 所示。若条件为真执行循
环体 A,否则结束循环执行下一语句。
A
条件
真
假
5.8 图循环结构
这三种结构经常贯穿于程序设计之中,望读者能在理解的基础上熟练运用。
4.算法
算法就是一种解决问题的方法。它必须满足以下条件:
(1)输入。具有 0 个或多个输入的外界量。
(2)输出。至少有一个数据输出,他是程序执行后的结果。
(3)有穷性。每条指令的执行次序必须是有限的。
(4)确定性。每条指令的含义必须是明确的,无歧义的。
(5)可行性。每条指令执行的时间都必须是有限的。
算法一般采用流程框图、自然语言、计算机语言、数学语言、
规定
关于下班后关闭电源的规定党章中关于入党时间的规定公务员考核规定下载规定办法文件下载宁波关于闷顶的规定
的符号等
方式描述。
例 5.5 请写出圆面积的算法。
设圆面积为 s,半径为 r,则面积 s = 3.14*r*r。
算法:
(1)定义 s,r 为 N 型变量并赋初值 0;
(2)输入 r 值;
(3)计算 s = 3.14*r*r ;
(4)输出 s;
(5)结束
例 5.6 求 的值 ∑=
100
1n
n
分析:即求 1+2+……+100 的值。用 n 表示每一项,n 的初值为 1,终值为
100。由于每一项的前一项增加 1,就有 n = n+1。求和用 s,s初值为 0,只要 n<=100,
重复做 s = s + n,n = n + 1,知道 n >100,输出 s 值。
算法:
(1)定义 s = 0,n = 1 它们都为 N 型;
(2)判断 n<=100,为真做 1)、2)步,否则转到(3)步
1)s=s+ n
2)n = n + 1 转(2)步 ;
(3)输出 s;
(4)结束。
有了算法,就可以根据算法将程序写出来。当然有些简单问题可以不用写算
法直接写出程序。
一般来说我们解决问题遵循以下几步;一、分析问题;二、写出算法;三、
根据算法写出程序;四、将程序输入计算机即建立程序文件;五、调试执行;六、
输出结果。
5.3.2 顺序结构程序设计
由顺序结构特点可知,例 5.1-5.3 程序使顺序结构的程序设计,看下面的例子。
例 5.7 求圆面积。此例的算法再例 5.5 已经给出,现在给出程序。
程序设计:
*P5_7.prg
s=0
r=0
input "输入 r:" to r
s=3.14*r*r
?" s=", s
return
执行结果:
输入 r: 10
s=314.00
5.3.3 选择结构程序设计
VFP 对于普通选择结构与多分支选择结构都有相应的实现命令
1. 普通选择结构: IF [ELSE] ENDIF
格式:IF <条件>
<命令行列 1>
[ELSE]
<命令行列 2>
ENDIF
功能:当条件成立时执行命令序列 1,否则执行命令序列 2。当不包含 else
时,条件成立执行命令序列 1,否则执行 ENDIF 后的语句。
说明:IF~ENDIF 必须成对出现,此语句可以嵌套使用条件的逻辑表达式
执行框图
真
假
条件
命令序列 2
ENDIF
命令序列 1
图 5.9 IF~ENDIF 执行框图
例 5.8 编程:当 R>=0 时计算圆面积否则输出不合题意。
程序设计:
*P5_8.prg
set talk off
s=0
r=0
input "输入 r:" to r
if r>0
s=pi( )*r*r
?"s=", s
else
?"r<0 不合题意!"
endif
?"程序结束"
return
执行结果: 输入 r:10
s= 314.16
程序结束
执行结果:
输入 r: -10
r<0 不合题意!
执行结束
例 5.9 编程:输入学号在学生表中查询学生姓名,学生成绩,若没有找到输
出无此学生。
程序设计:
*P5_9.prg
clear
open database 学生
use 学生 && 可以不写
INPUT "输入学号:" TO XH
LOCATE FOR 学号=XH
IF found()
?"学号:"+学号+space(2)+"姓名:"+姓名+ space(2)+str(入学成绩, 3)
ELSE
?"无此学生"
ENDIF
close database
return
执行结果 :
2.多分支选择结构 : DO Case ~ ENDCase 命令
格式:
DO CASE
CASE <条件 1>
<命令序列 1>
CASE <条件 2>
<命令序列 2>
……
CASE <条件 n>
<命令序列 n>
[OTHERWISE]
<命令序列 n+1>
ENDCASE
功能:依次判断条件是否成立,若某个条件成立,则执行对应的语句序列,
然后执行 ENDCase 的后面语句,若所有条件都不成立,如有 OTHERWISE 就执
行语句序列 n+1,否则执行 ENDCase 下面语句。
说明: (1)条件为逻辑表达式。
(2)DO Case 与 ENDCase 必须成对出现。
真
假
真
真
假
条 件
条 件
条 件
条 件
条件序列 1
条件序列 2
条件序列 n
条件序列 n+1
图 5.10 DO CASE~ENDCASE 执行框图
例 5.10 输入学生姓名,成绩,给出分数的等级,学生成绩为百分制,成绩
的等级情况为:90-100 为优秀,70-89 为良好,60-69 为及格,0-59 为不及格。
程序设计:
*P5_10.prg
cj=0
dj=""
input "输入学生姓名:" to xm
input "输入学生成绩:" to cj
do case
case cj>=90 and cj<=100
dj="优秀"
case cj>=70 and cj<=89
dj="良好"
case cj>=60 and cj<=79
dj="及格"
case cj>=0 and cj<=59
dj="不及格"
otherwise
dj="输入错误"
endcase
?xm, cj, dj
return
执行结果:
输入学生姓名: “李明”
输入学生成绩: 91
李明 91 优秀
5.3.4 循环结构程序设计
VFP 有三种循环结构,它们是:DO WHILE~ENDDO,FOR~ENDFOR,
SCAN~ENDSCAN 命令。
1. DO WHILE~ENDDO 命令
格式:
DO WHILE <条件>
<命令序列 1>
[LOOP]
<命令序列 2>
[EXIT]
<命令序列 3>
END DO
功能:
①当条件成立时,执行 DO While 与 END DO 之间的命令,也称循环体。
②程序执行到 END DO 时自动返回到 While<条件>处重新判断条件是否
成立,以决定是否循环。
③当条件不成立时,结束循环,执行 END DO 下面命令。
说明:
1、DO While 与 END DO 必须成对出现。
2、LOOP 命令时,结束本次循环,自动返回 DO While 处重新判断条
件。
3、遇到 EXIT 命令时,就结束循环,执行 END DO 下面命令。
假
真
条 件
命令序列 1
LOOP
命令序列 2
EXIT
命令序列 3
图 5.11 DO WHILE~ENDDO 执行框图
例 5.11 求 的值 ∑=
100
1n
n
此题在例 5.6 中以给出算法。
程序设计:
*P5_11.prg
s=0
n=1
DO WHILE n<=100
s=s+n
n=n+1
ENDDO
?"s=", s
return
执行结果:
s=5050
例 5.12 对 100 个任意数求和,要求等于大于 0 的数求和,小于 0 的数求和,
当输入 0.001 时,不论时候到 100 个数都停止输入。将结果输出。
分析:这是一个循环问题,设求和变量 S 初值为 0 用 N 控制循环,次数取 1
到 100。在循环体内输入 X,n=n+1 判断 X<0 为真进入第一次循环。X<0 为假。
判断 X=0.001 为真结束循环。X=0.001 为假计算 S=S+X,然后重复循环。
算法:
1、 s=0,n=1
2、 判断 n<=100 若为真做 1)否则做 3
1) 输入 x,n=n+1 若 x<0 转 2
2) 判断 x=0.001 为真转 3
3) s=s+x
4) 转 2
3、 输出 s
4、 结束
程序设计:
*P5_12.prg
s=0
n=1
do while n<=100
input "x:" to x
n=n+1
if x<0
loop
endif
if x=0.0001
exit
endif
s=s+x
enddo
?"s=",s
return
执行结果:
x: 5
x: 7
x: 0.0001
s= 12
2.FOR~ENDFOR 命令,此命令通常也称记数循环命令
格式:
FOR <循环变量>=<初值> TO <终值> [STEP <步长>]
<循环体>
ENDFOR | EXIT
功能:先把初值赋给循环变量,再判断循环条件是否成立。若不成立就结束
循环,执行循环后面的命令,若条件成立,就执行循环体,循环再执行一此,循
环变量自动增加一个步长。再判断循环变量是否成立,以判断是否执行循环体。
说明:1)循环变量为内存变量,初值,终值,步长为数值表达式。
2)当步长大于 0 时,循环条件为<循环变,循环变量无增量,将死循环,步
长默认值为 1。
3)在循环体内可以改变循环变量,但这会改变循环次数。
4)在循环体内可以包括,LOOP 和 EXIT。当遇到 LOOP 时,本次循环结束,
循环变量增加一个步长值,进入下一次循环,当遇到 EXIT 时,结束循环,执行
下面的命令。
执行框图:
假
真
<循环变量>=<初值>
循环条件
命令序列 1
LOOP
命令序列 2
EXIT
命令序列 3
<循环变量>=<循环变量>+<步长>
图 5.12 FOR~ENDFOR| EXIT 执行框图
例 5.13 循环求求 的值,即求 1+2+…n. ∑=
n
i
i
1
程序设计:
*P5_13.prg
s=0
input "输入 n:" to n
for i=1 to n
s=s+i
endfor
?" s=", s
return
执行结果:
输入 n: 100
s=5050
3.SCAN~ENDSCAN 命令。
用于对表操作的循环命令。通常也称表扫描循环命令。
格式:
SCAN [<范围>] [FOR <条件>] [WHILE <条件>]
<循环体>
ENDSCAN
功能:在当前表的指定范围内,记录指针自动移到满足条件 1 或条件 2 的记
录上,执行循环体,然后再将记录指针自动移动到下一个满足条件 1 或条件 2
的记录上再一次执行循环体直至超出范围。默认范围为表中所有记录。
说明:1、循环体内可包含 LOOP 与 EXIT 命令,当遇到 LOOP 命令时,结
束本次循环返回到 SCAN 处进入下一次循环。当遇到 EXIT 时,结束循环,执行
ENDScan 后面的命令 。
例 5.14 逐条显示,学生表中入学成绩等于 490 分的学生,学号,姓名,入
学成绩,并统计人数。
*P5_14.prg
clear
n=0
open database 学生
use 学生
scan for 入学成绩>=490
display 学号, 姓名, 入学成绩
n=n+1
endscan
close database
?"n=", n
return
执行结果:
记录号 学号 姓名 入学成绩
4 105010104 赵文学 500
记录号 学号 姓名 入学成绩
5 105010105 刘美文 680
记录号 学号 姓名 入学成绩
6 105010201 张小峰 650
记录号 学号 姓名 入学成绩
7 105010202 王艳丽 620
记录号 学号 姓名 入学成绩
8 105010203 刘英 510
记录号 学号 姓名 入学成绩
9 105020101 王雪梅 600
记录号 学号 姓名 入学成绩
10 105020102 李德勇 660
n= 7
4.循环的嵌套
在循环命令的循环体中包含了其他循环。循环嵌套就是指多重循环。VFP 的
三种循环可以互相嵌套。
例 5.15 输出乘法表:
分析:由于乘法表是 9 行,第一行为一列,第二行为二列,….,设 i,j 变量,
i 控制行作为外循环变量,j 控制列作为内循环变量。乘法表为 9 行,i 初值为 1,
终值为 9,步长为 1,由于第 j 行有 i 列所以,j 的初值为 1,终值为 i,步长为 1。
计算 i*j。
*P5_15.prg
FOR i=1 TO 9
FOR j=1 TO i
??str(j, 2)+'*'+str(i, 2)+spac(2)+"="+str(i*j, 3)
ENDFOR
?
ENDFOR
RETURN
执行结果:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=65 6*9=54 7*9=63 8*9=72 9*9=81
5.4 多模块程序结构
多模块程序结构是将一个大的程序划分为一个主调程序和几个被调程序。通
常将主调程序称为主程序模块,被调程序称为子程序模块。这是软件开发使用的
普遍方法。它的好处在于可以将大型复杂的问题分解为小而简单的问题去解决符
合人的思维方式,可以将不同的模块分配给几个人同时开发。,从而可以缩短程
序开发周期。由于子程序模块可以多次被调用又可以相互调用,提高代码的重用
率,也便于软件修改与维护,VFP 和其他计算机开发工具一样具有多模块程序功
能,它实现子程序模块有三种方式。第一种方式为子程序,第二种为过程,第三
种为自定义函数。他们三者主要区别是:子程序无返回值,而过程和自定义函数
有返回值。
5.4.1 子程序,过程,自定义函数
1.子程序
(1)子程序的基本概念:
VFP 中的子程序是一个程序文件、它可以独立的存放在磁盘中,它与主程序
的主要区别是:主程序只能调用其他程序而不能被其他程序调用,子程序既能被
主程序调用也能被其他子程序调用,而且多个子程序可以相互调用。
(2)子程序的书写形式:
[PARANETES<形参表>]
<命令序列>
RETURN [TO MASTER | TO <程序文件名>]
说明:1)[PARANETES<形参表>]这些形参用于接收 DO 命令发送的实参值。
当返回调用程序时把这些形参值回送给形参表中的形参。多个形参之间用逗号隔
开。
2)RETURN[ TO MASTER | TO <程序文件名>]子句若不包含在程序中,子
程序返回调用程序中调用命令的下一行。调用程序继续执行。若包含 TO
MASTER 时,是在子程序嵌套调用时,直接返回最外层的主程序。若包含 TO <
程序文件名>时,子程序返回到指定的程序文件。
(3)子程序的调用
格式:DO <文件名> [WITH <实参表>]
功能:调用由文件名指定的程序。
说明:1)实参表中实参是传给子程序的,实参可为常量,变量,表达式。若
实参个数少于形参个数,多余的形参值取逻辑假(.F.)。若实参个数多于形参个数,
系统提示错误信息。
2)实参为常量或一般表达式时,系统将其值传给对应形参变量,称为值传递。
若实参为变量,系统把实参也传给形参,此时形参与实参实际上是同一个变量,
称为地址传递或引用传递。
(4)子程序的调用过程。
如图:5.13,图 5.14,图 5.15 所示:
主程序 子程序 1
DO 子程序 RETURN
图 5.13 无嵌套子程序调用
主程序 子程序 1 子程序 2
DO 子程序 1 DO 子程序 2
RETURN RETURN TO MASTER
图 5.14 有嵌套直接返回主程序
主程序 子程序 1 子程序 2
DO 子程序 1 DO 子程序 2 DO 子程序 3
RETURN
RETURN RETURN TO 子程序
图 5.15 有嵌套子程序,返回指定程序
例 5.16 用主程序与子程序方式求长方形的面积,请用传参数和不传参数两
种方法做。
(1)用不传参数的方法做
*P5_16_1.prg
clear
DO CZ1
return
* CZ1.prg
x=0
y=0
s=0
INPUT "输入长:" TO x
INPUT "输入宽:" TO y
S=x*y
? " s=", s
return
执行结果:
输入长:10
输入宽:20
s= 200
(2)传参数的方法做
*P5_16_2.prg
x=0
y=0
s=0
INPUT "输入长:" TO x
INPUT "输入宽:" TO y
DO CZ2 WITH x, y, s
?"s=", s
return
* CZ2.prg
PARAMETERS a, b, c
c=a*b
return
执行结果:
输入长:10
输入宽:20
s= 200
2.过程
(1)过程的概念:
过程和子程序的作用基本是一样的,调用关系也相同,主要区别是:过程可
以和主程序存在同一个文件中,也可以独立的,一个或多个过程存在一个文件中,
而一个文件只能有一个子程序,多个子程序要存在多个文件中。子程序可直接调
用,而过程如果与主调程序存在一个文件中,必须通过打开过程文件才可以调用。
使用完再将过程文件关闭。子程序无返回值,过程有返回值。
(2)过程的书写格式
格式:
PROCEDURE< 过程名>
[PARAMETERS<形参表>]
<命令行列>
[RETURN<表达式>]
[ENDPROC]
说明:
1)[RETURN<表达式>]子句作用是返回表达式的值,若只有 RETURN 将返回
逻辑真。若无此子句过程结果处自动执行一条隐含的 RETURN 命令。
2)[ENDPROC]子句表示过程结束,一般可不选。
3)过程与子程序一样可以嵌套调用。
(3)过程文件的打开
格式:SET PROVEDURE TO [<过程文件名列表>][ADDITIVE]
功能:打开由过程文件名列表指定的过程文件,过程名列表是用逗号分隔的
过程文件名。
说明:1)无任何选项将关闭所有打开的过程文件。
2)前选 ADDITIVE,在新打开过程文件时并不关闭后来打开的过程文件。
(4)关闭过程文件
格式 1:RELEASE PROCEDURE <过程文件名列表>。
格式 2:CLOSE PROCEDURE 。
功能:格式 1 用于关闭过程文件列表中的过程文件。格式 2 用于关闭所有过
程文件。
(5)过程的调用
格式 1:DO <过程名> [WITH <形参表>]
格式 2:<过程名>()
功能:格式 1 调用由<过程名>指定的过程。WITH 子句含义与子程序段中的
WITH 子句含义相同。格式 2 不用传递参数直接调用。
(6)过程的调用过程
过程的调用过程与子程序的调用过程类似,请参看子程序调用过程。
例 5.17 求长方形面积用过程方法做。请用主程序与过程存放一个文件做,
再用主程序与过程不存放在一个文件做。再用调用格式 2 方法做。
(1)主程序与过程存放在一个文件中。
*P5_17_1.prg
x=0
y=0
s=0
input "输入 x:" to x
input "输入 y:" to y
do P1 with x,y,s
?"s=", s
return
PROCEDURE P1
PARAMETERS a, b, c
c=a*b
return
执行结果:
输入 x:10
输入 y:20
s= 200
(2)主程序与过程不存放在一个文件中。
*P5_17_2.prg
SET PROCEDURE TO f1
x=0
y=0
s=0
input "输入 x:" to x
input "输入 y:" to y
DO P1 WITH x, y, s
?"s=", s
ClOSE PROCEDURE
RETURN
*f1.prg
PROCEDURE P1
PARAMETERS a, b, c
c=a*b
return
执行结果:
输入 x:10
输入 y:20
s= 200
(3)用调用格式 2 做。
* P5_17_3.prg
x=0
y=0
s=0
s=p1()
?"s=", s
return
PROCEDURE P1
input "输入 x:" to x
input "输入 y:" to y
s=x*y
return s
执行结果:
输入 x:10
输入 y:20
s= 200
例 5.18 传递数组的应用。
*p5_18.prg
clear
dimension a(5)
FOR i=1 TO 5
a(i)=i
ENDFOR
s=0
DO P1 WITH a, s
FOR i=1 TO 5
??a(i), space(2)
ENDFOR
?"s=", s
RETURN
PROCEDURE P1
PARAMETERS b, s
FOR i=1 TO 5
b(i)=2*b(i)
s=s+b(i)
ENDFOR
RETURN
执行结果:
2 4 6 8 10
s= 30
3.自定义函数
(1)函数的概念:
函数与子程序,过程一样,是一个独立的子模块,调用关系也相同,它的程
序段要和主调程序存在同一个文件中,它一经定义使用方式的调用与标准函数相
同。它可以有参数传递,可以有返回值。
(2)函数的书写格式
FUNCTION 函数名
[PARAMETERS <形参表>]
<命令序列>
[RETURN [表达式]]
[ENDFUNC]
说明:[RETURN [表达式]]子句是返回函数的值,若无表达式 RETURN 返回
逻辑真。若不选此子句在函数结束处自动执行一条隐含的 RETURN 命令。
ENDFUNC 是表示函数的结束,一般不选用。
(3)函数的调用
格式:函数名([<实参表>])
功能:调用由函数名指定的字定义函数。
(4)函数的执行过程
函数也可以嵌套,它与子程序,过程类似,可参看子程序执行过程。
例 5.19 求长方形的面积用自定义函数做。
* P5_19.prg
clear
x=0
y=0
s=0
input "输入 x:" to x
input "输入 y:" to y
s=f(x, y)
?" s=", s
return
function f
parameters a, b
c=a*b
return c
执行结果:
输入 x:10
输入 y:20
s= 200
5.4.2 变量的作用域
1.基本概念
变量的作用域:就是变量在程序中的有效区域。在多模块程序结构中,在一
个模块中定义的变量不一定在另一个模块中有效。VFP 按变量的作用域将变量分
为公有(public)变量,私有(private)变量,局部(local)变量三种。公有变量是在任
何模块中都能使用的变量,即它的有效区是整个程序,它必须是先经过 public
定义为公有才能使用。私有变量是在本模块及属于各层模块中有效,凡是没有经
过 public 与 local 定义的或用 private 定义的变量都是私有变量。局部变量它的有
效区域只限于本模块,它要用 local 定义。
2.公有,私有,局部变量的意义
(1)公有变量的意义
格式:public <内存变量表>
功能:定义<内存变量表>指定的变量为公有变量。
(2)私有变量的定义
格式:private <内存变量表>
功能:定义<内存变量表>指定的变量为私有变量。
(3)局部变量的定义
格式:local <内存变量表>
功能:定义<内存变量表>指定的变量为局部变量。
例 5.21 公有,私有,局部变量的应用。
*P5_21.prg
clear
public a,b,c
a=1
b=2
c=3
d=5
local e
e=6
do P1
?"在全程序中:"
?"a=", a, "b=", b, "c=", c, "d=", d, "e=", e
return
procedure P1
private a
a=20
local c, e
f=6
e=30
c=100
?"在 p1 中:"
?"a=", a, "b=", b, "c=", c, "d=", d, "e=", e, "f=", f
do p2
return
procedure p2
?"在 p2 中:"
?"c=", c
return
执行结果:
在 P1 中
a= 20 b= 2 c= 100 d= 5 e= 30 f=6
在 P2 中
c=3
在主程序中
a= 1 b= 2 c= 3 d= 5 e=6
5.4.3 程序的调试
在软件开发中,在对软件进行测试时,一般常见的错误分为两种,一种为语
法错,一种为逻辑错误。语法错误在测试过程中,开发工具系统能立刻发现,并
显示出错误信息,开发者也容易加以改正,很容易发现,但对于逻辑错误来说测
试就困难一些。例如:算法乘法的程序,把乘号误写为加号,程序在测试中一切
正常,但运算结果是错误的,这种逻辑型错误就不那么容易发现。这就给测试工
作带来一定难度。针对这类问题 VFP 开发工具为开发者提供了调试器,调试器
它可以完成对被测程序的跟踪,设断点,监视,跟踪输出结果等功能。方便快捷
协助开发者找到逻辑错误的位置达到改正逻辑错误的目的。
现在对调试器作一介绍。
1. 打开调试器
工具→调试器或命令窗口中输入 debug 命令打开调试器,如图 5.16 所示:
图 5.16 调试器
它有文件,编辑,工具,窗口,帮助 5 个主菜单,一个工具栏,工具栏中从
左至右为打开,继续执行,取消,跟踪,单步,跳出,运行到光标处,跟踪窗口,
监视窗口,局部窗口,调用堆栈窗口,输出窗口,切换,断点,清除所有断点,
断点对话框,切换编辑日志,切换事件跟踪按钮。
2. 调试器工作环境
调试器有跟踪,监视,局部,输出,调用堆栈 5 个窗口。这些窗口都可以通
过窗口菜单调出来。
1)跟踪窗口
用于打开,显示被测试的程序,打开被测试程序:文件→打开,打开对话框
选择所需程序。
2)监视窗口
用于指定表达式在程序测试执行过程中其值的变化情况。
3)局限性
用于显示模块程序中内存变量的名称,取值和类型。
4)调用堆栈窗口
用于显示当前处于执行状态的程序,过程和方法。若正在执行的是一个子程
序,则显示主程序与子程序的名称。
5)输出窗口
用于显示由 DEBUGOUT〈表达式〉命令,指定的表达式的值,一般用于程
序调试过程中数据的显示。
3.断点类型
断点设置的位置一般是程序编写有误的部分,设置断点后可以逐行进行跟踪
监视。断点类型有四种,接下来分别介绍四种类型及设置方法。断点的设置必须
是在调试器打开的情况下实现的。
(1)类型 1
类型 1 为在定位处中断。可通过在跟踪窗口双击需设置断点的程序行的左端
灰色区域。可以看到在该程序行前出现红色圆点,表明断点设置成功。取消断点
的方法与设置断点的方法相同。
(2)类型 2
如果表达式为逻辑真,则在定位处中断。设置方法:
工具→断点,打开断点对话框(如图 5.17)→在类型下拉列表框中选出对应
的类型→在定位文本框中输入断点的位置→在文件文本框中指定文件,文件可为
程序文件,过程文件等。→在表达式框中输如需要显示的表达式→添加→确定。
如输入程序 1,6 表示程序 1 中第 6 行设置断点。设置完毕后将在跟踪窗口中显
示断点。
图 5.17 断点对话框
(3)类型 3
当表达式为真时中断,设置方法为:工具→断点→在类型下拉列表框选相应
类型→在表达式框中输入相应的表达式→添加→确定。
(4)类型 4
当表达式的值改变时中断。设置方法为:工具→断点→在类型下拉列表框中
选相应的断点类型→在表达式框中输入相应的表达式→添加→确定。若所需表达
式已在监视窗口中指定,则在该表达式前显示断点。
例 5.22 编写一个程序求 1—20 之间能被 3 整除的数,然后用调试器进行调
试。设类型 1 与类型 3 断点。
程序:
*P5_21.prg
clear
for i=1 to 20
if i/3=int(i/3)
debugout i
?i
endif
endfor
调试程序步骤:
1.在调试器窗口中打开程序 P5-21.prg
(1)打开调试器窗口:工具→调试器
(2)将程序显示在跟踪窗口中:文件→打开,在打开窗口中选 P5-21.prg→确
定
2、设断点
(1)双击程序第 6 行左侧出现断点标识,类型 1 设置完成。
(2)工具→断点→在类型下拉列表框中选对应类型→在表达式框中输入:
i/3=int(i/3)→添加→确定
3.设置监视表达式
在监视窗口中的监视文本框中输入 i/3=int(i/3)确定。
4.开始调试
调试→运行→在断点中断时重复点击继续执行命令按钮。本题可出现 6 次中
断。
在实际应用中,一个程序在调试时设置断点的类型要根据具体情况而定。
5.执行结果:
3
6
9
12
15
18
5.5 程序设计应用举例
例 5.23 求 n!
分析:n!为计算 1×2×…n 的积。设 n!的结果为 t,t 的初值为 1,表示每
一项的变量为 i,i 的初值为 1。当 i<=n 时,反复执行 t=t*i,i=i+1,当 i>n 时循
环结束,输出 t 的值。
算法:
1、 定义 t=1,i=1
2、 输入 n 的值
3、 i<=n 成立执行(1),(2)步,否则转到第 4 步
(1)t=t*i
(2)i=i+1
(3)转 3
4、 输出 t
5、 结束
程序:
*P5_22.prg
t=1
i=1
input "输入 n:" to n
do while i<=n
t=t*i
i=i+1
enddo
?t
执行结果:
输入 n:=3
6
例 5.24 输入任意整数,求它的所有因子。
分析:设 n 为任意整数,i 为 1-n 之间整数,判断 MOD(n, i)=0 为真,说明
n 能被 i 整除,i 为 n 的一个因子,否则 i 不是 n 的因子。
*P5_23.prg
input "输入 n:" To n
for i=1 to n
if MOD(n, i)=0
?i
endif
endfor
return
执行结果:
输入 n:10
1
2
5
10
例 5.25 输入任意数,判断它是否为素数。
分析:n为任意数,判断n是否为素数的方法利用n被 2~ n 中任意一个整数
的方法,若都不能整除则n为素数。设循环变量i,整型变量j。j= n ,用i产生 2-j
间的整数,在循环体内判断n%i=0 是否为真,若为真,说明n能被i整除,n就不
是素数,结束循环;若为假则继续循环。循环结束后判断i>j是否为真,为真说
明n为素数,否则n不是素数。
为什么要用 i>j 作为最后的判断条件?这是因为若 n 能被 i 整除,此时的 i
一定小于等于 j,如果在循环之内 n 没有被 i 整除,,那么最后一次循环时要做
i=i+1,然后循环才能结束,所以循环结束后 i 一定大于 j。
程序:
*P5_24.prg
clear
n=0
input "输入 n:" to n
j=sqrt(n)
for i = 2 to j
if n%i=0
EXIT
endif
endfor
if i >j