FoxPro For Windows http://cc.synu.edu.cn 1
FoxPro程序设计
第 7讲 子程序、过程、自定义函数
FoxPro For Windows http://cc.synu.edu.cn 2
FoxPro程序设计
学生管理系统程序 数据录入 数据维护
按学号查询 按姓名查询 按组合条件查询
数据查询 打印报表
学生管理系统
主程序
子程序
子程序
主程序调用子程程序,子程又调子程,嵌套最多 32层。
子程序
FoxPro For Windows http://cc.synu.edu.cn 3
FoxPro程序设计
子程序
子程序的建立:
MODI COMM (*.prg)
子程序返回主程序的命令:
RETURN [TO MASTER]
子程序调用:
DO<子程序名 > [WITH<参数表 >]
主程序
子程序 1
子程序 3
子程序 2
FoxPro For Windows http://cc.synu.edu.cn 4
FoxPro程序设计
【 例 】 现有一个主程序 MAIN和二个子程序 SUB1.PRG和 SUB2.PRG.
*MAIN.PRG
'# # # #1'
DO SUB1
'# # # #2'
DO SUB2
'# # # #3'
RETURN
复杂的信息管理系统,通常由主程序调用若干子程序完成。
子程序 都是以文件方式 独立存盘 的,调用时读入内存,因此影
响运行速度。有没有更好的办法呢?
*SUB1.PRG
'$ $ $ $1‘
RETURN
*SUB2.PRG
'$ $ $ $2‘
RETURN
# # # #1
$ $ $ $1# # # #2
$ $ $ $2
# # # #3
FoxPro For Windows http://cc.synu.edu.cn 5
FoxPro程序设计
过程文件, 把一个个分散的子程序组合成一个大的文件。
执行时,用打开过程文件命令一次调入内存。
过 程, 过程文件中的每一个子程序叫做一个过程。
过程与过程文件
1.过程的定义
PROCEDURE <过程名 >
[PARAMETERS <形式参数表 >]
<语句序列 >
RETURN
说明:
?过程与子程序的区别就在于过程是以 PROCEDURE命令开头。
?过程名字母、下划线,<=10字符。
?过程文件由一个或多个过程组成,并放于扩展名,prg的磁盘文件中。
?过程文件中各个过程的排列顺序任意。
FoxPro For Windows http://cc.synu.edu.cn 6
FoxPro程序设计
2.过程调用
必须先打开过程文件,才可以调用过程文件中的过程。
打开过程文件:
SET PROCDURE TO [<过程文件名 >]
调 用 过 程:
DO <过程名 > [WITH <参数表 >]
&&实际参数
关闭过程文件:主程结束前必须关闭过程文件
SET PROCDURE TO
CLOSE PROCEDURE
FoxPro For Windows http://cc.synu.edu.cn 7
FoxPro程序设计
【 例 5.31】 调用过程文件
*主程序 Main.prg *过程文件 [gcwj.prg]
set talk off proc gc1
clear? '这是过程 1,过程名为 gc1'
‘这是主程序!’ retu
set proc to gcwj
do gc1 proc gc2
do gc2? '这是过程 2,过程名为 gc2'
close proc retu
retu
这是主程序!
这是过程 1,过程名为 gc1
这是过程 2,过程名为 gc2
程序执行后的显示结果:
FoxPro For Windows http://cc.synu.edu.cn 8
FoxPro程序设计
3.参数传递
只有定义过程时先定义参数,过程调用时才可向被调用过程传递参数。
说明:
? PARA后的参数叫形式参数(形参);
? DO…WITH 中的参数叫实际参数(实参)。
? 形参和实参按顺序一 一对应,类型相同,可以是常量、变量,表达式。
? 传递时是将计算后的实参值传递给形参。
参数定义:
[PARAMETERS <形式参数表 >]
带参调用的命令:
DO <过程名 > [WITH <参数表 >]
说明:
?PARAMETERS 语句必须是 PROCEDURE语句后第一个可执行语句。
?参数表中可以包括 1至 24个参数,各参数间用逗号隔开。
FoxPro For Windows http://cc.synu.edu.cn 9
FoxPro程序设计
【 例 5.32】 编写把输入的汉字串按每字一行的形式输出的程序。
***主程序 MAIN.PRG
SET TALK OFF
SET PROC TO PROTEST &&打开过程文件
ACCEPT "请输入一个汉字串," TO str
DO Vertica WITH str &&带参 Str调用过程 vertica
SET PROC TO &&关闭过程文件
SET TALK ON
RETURN
***过程文件 PROTEST.PRG
PROC Vertica &&定义过程,vertica
PARA s &&定义形参 s
start=1
slen=LEN(s)
DO WHILE start < slen
SUBS(s,start,2)
start=start+2
ENDDO
RETURN &&返回到调用程序
FoxPro For Windows http://cc.synu.edu.cn 10
FoxPro程序设计
【 例 5.33】 调用过程文件,计算圆的面积并输出。
*主程序 MJ.PRG
SET TALK OFF
SET PROC TO YMJ
s=0
INPUT "请输入圆的半径," TO r
DO S1 WITH s,r &&带参 s,r 调用过程 S1
DO S2
SET PROC TO
SET TALK ON
RETURN
**过程文件 YMJ.PRG &&过程文件名,YMJ.PRG
PROC S1 &&过程名,S1
PARAMETERS x,r &&定义形参 s x
x=3.14159*r*r r r
RETURN
PROC S2 &&过程名,S2
s
RETURN
FoxPro For Windows http://cc.synu.edu.cn 11
FoxPro程序设计
函数是能返回值的子程序。
FoxPro提供了 200多个系统函数,自己建立的函数称自定义函数。
1、函数的定义:
[FUNCTION <函数名 >]
[PARAMETERS <参数表 >]
<语句序列 >
RETURN <表达式 >
自定义函数
。函数说明语句 FUNCTION可省略,程序名即为函数名。
。函数名命名方法同过程名,但不能和系统函数同名。
。参数说明语句 PARAMETERS <参数表 >
。函数返回语句 RETURN <表达式 >,将表达式的值作为函数值返回。
FoxPro For Windows http://cc.synu.edu.cn 12
FoxPro程序设计
2、函数的调用
<自定义函数名 > ( [<参数表 >])
=
)!(!
!
nmn
m
?
n
m C
【 例 5.34】 编写计算 K!的函数 f 【 例 5.35】 利用自定义函数 f求 Cmn的值。
*自定义函数 F.PRG *Cmn.PRG
FUNCTION F &&可省略 SET TALK OFF
PARA k INPUT "m=" to m
T=1 INPUT "n=" to n
FOR I=1 TO K Cmn=f(m)/(f(n)*f(m-n))
T=T*I?Cmn
ENDFOR RETU
RETU T &&返回值 T
FoxPro For Windows http://cc.synu.edu.cn 13
FoxPro程序设计
? 参数定义相同:
用 PARA语句说明,且为定义语句后的第一语句;
? 调用不同:
调用函数,直接调用函数名,括号中是实际参数。
调用过程,do...with<para>,with后是实际参数。
? 函数有返回值 retu <expr>,过程无返回值。
辨析:过程、函数
FoxPro For Windows http://cc.synu.edu.cn 14
FoxPro程序设计
练习:
【 例 】 子程序调用
*B.PRG
*A1+A2+A3=?
STORE 2 TO A1,A2,A3
A1=A1+A2 &&A1=4
DO B1
A1+A2+A3
RETU
*B1.PRG
A2=A2+2 &&A2=4
DO B2
A1=A1+1
RETU
* B2.PRG
A3=A3+2 &&A3=4
RETU TO MASTER
B
B1
B2
FoxPro For Windows http://cc.synu.edu.cn 15
FoxPro程序设计
【 例 】 过程调用
*y=1*2*3*4=?
SET TALK OFF
SET PROC TO SP && 打开过程文件 SP
S=0
DO SP1 WITH 5,S && 带参 5,0调用 SP1
S
SET PROC TO
RETU
*SP.PRG
PROC SP1
PARA X,Y && X=5,Y=0
N=1
Y=1
DO WHIL N<X
Y=Y*N && Y=1*1*2*3*4
N=N+1
ENDD
RETU
FoxPro For Windows http://cc.synu.edu.cn 16
FoxPro程序设计
【 例 】 调用自定义函数
*主程序
*16
SET TALK OFF
X=5
Y=SQRT(6*X+6) && 6
Z=2*JC(X)+JC(Y) && 调用自定义函数 JC
Z &&Z=2*5+6
SET TALK ON
RETU
*自定义函数,JC.PRG
FUNC JC
PARA K && X K,Y K
S=0
FOR I=1 TO K
S=S+1 && S=0+1+1+1+1+1
ENDF
RETU S
FoxPro For Windows http://cc.synu.edu.cn 17
FoxPro程序设计
【 例 】 写出程序运行结果
SET TALK OFF
C="ABCDEFG"
N=1
DO WHILE N<7
SUBSTR(C,7-N,1)
N=N+1
ENDDO
RETURN
* 程序中?命令输出的结果是 ____。
F
E
D
C
B
A
FoxPro For Windows http://cc.synu.edu.cn 18
FoxPro程序设计
【 例 】 写出程序运行结果
SET TALK OFF
CLEAR
X=0
DO WHILE X<5
Y=0
SPACE(X)
DO WHILE Y<10
STR(Y,1)
Y=Y+1
ENDDO
X=X+1
ENDDO
RETURN
0123456789
0123456789
0123456789
0123456789
0123456789
FoxPro For Windows http://cc.synu.edu.cn 19
FoxPro程序设计
【 例 】 写出程序的运行结果
SET TALK OFF
STORE 0 TO X,Y
DO WHILE,T.
X=X+1 &&x=0+1+1+1+1+1
Y=Y+X &&y=0+1+2+3+4+5
IF X>=5
EXIT
ENDIF
ENDDO
X,Y
当程序执行到?命令时,X与 Y的值分别为 ____。
FoxPro程序设计
第 7讲 子程序、过程、自定义函数
FoxPro For Windows http://cc.synu.edu.cn 2
FoxPro程序设计
学生管理系统程序 数据录入 数据维护
按学号查询 按姓名查询 按组合条件查询
数据查询 打印报表
学生管理系统
主程序
子程序
子程序
主程序调用子程程序,子程又调子程,嵌套最多 32层。
子程序
FoxPro For Windows http://cc.synu.edu.cn 3
FoxPro程序设计
子程序
子程序的建立:
MODI COMM (*.prg)
子程序返回主程序的命令:
RETURN [TO MASTER]
子程序调用:
DO<子程序名 > [WITH<参数表 >]
主程序
子程序 1
子程序 3
子程序 2
FoxPro For Windows http://cc.synu.edu.cn 4
FoxPro程序设计
【 例 】 现有一个主程序 MAIN和二个子程序 SUB1.PRG和 SUB2.PRG.
*MAIN.PRG
'# # # #1'
DO SUB1
'# # # #2'
DO SUB2
'# # # #3'
RETURN
复杂的信息管理系统,通常由主程序调用若干子程序完成。
子程序 都是以文件方式 独立存盘 的,调用时读入内存,因此影
响运行速度。有没有更好的办法呢?
*SUB1.PRG
'$ $ $ $1‘
RETURN
*SUB2.PRG
'$ $ $ $2‘
RETURN
# # # #1
$ $ $ $1# # # #2
$ $ $ $2
# # # #3
FoxPro For Windows http://cc.synu.edu.cn 5
FoxPro程序设计
过程文件, 把一个个分散的子程序组合成一个大的文件。
执行时,用打开过程文件命令一次调入内存。
过 程, 过程文件中的每一个子程序叫做一个过程。
过程与过程文件
1.过程的定义
PROCEDURE <过程名 >
[PARAMETERS <形式参数表 >]
<语句序列 >
RETURN
说明:
?过程与子程序的区别就在于过程是以 PROCEDURE命令开头。
?过程名字母、下划线,<=10字符。
?过程文件由一个或多个过程组成,并放于扩展名,prg的磁盘文件中。
?过程文件中各个过程的排列顺序任意。
FoxPro For Windows http://cc.synu.edu.cn 6
FoxPro程序设计
2.过程调用
必须先打开过程文件,才可以调用过程文件中的过程。
打开过程文件:
SET PROCDURE TO [<过程文件名 >]
调 用 过 程:
DO <过程名 > [WITH <参数表 >]
&&实际参数
关闭过程文件:主程结束前必须关闭过程文件
SET PROCDURE TO
CLOSE PROCEDURE
FoxPro For Windows http://cc.synu.edu.cn 7
FoxPro程序设计
【 例 5.31】 调用过程文件
*主程序 Main.prg *过程文件 [gcwj.prg]
set talk off proc gc1
clear? '这是过程 1,过程名为 gc1'
‘这是主程序!’ retu
set proc to gcwj
do gc1 proc gc2
do gc2? '这是过程 2,过程名为 gc2'
close proc retu
retu
这是主程序!
这是过程 1,过程名为 gc1
这是过程 2,过程名为 gc2
程序执行后的显示结果:
FoxPro For Windows http://cc.synu.edu.cn 8
FoxPro程序设计
3.参数传递
只有定义过程时先定义参数,过程调用时才可向被调用过程传递参数。
说明:
? PARA后的参数叫形式参数(形参);
? DO…WITH 中的参数叫实际参数(实参)。
? 形参和实参按顺序一 一对应,类型相同,可以是常量、变量,表达式。
? 传递时是将计算后的实参值传递给形参。
参数定义:
[PARAMETERS <形式参数表 >]
带参调用的命令:
DO <过程名 > [WITH <参数表 >]
说明:
?PARAMETERS 语句必须是 PROCEDURE语句后第一个可执行语句。
?参数表中可以包括 1至 24个参数,各参数间用逗号隔开。
FoxPro For Windows http://cc.synu.edu.cn 9
FoxPro程序设计
【 例 5.32】 编写把输入的汉字串按每字一行的形式输出的程序。
***主程序 MAIN.PRG
SET TALK OFF
SET PROC TO PROTEST &&打开过程文件
ACCEPT "请输入一个汉字串," TO str
DO Vertica WITH str &&带参 Str调用过程 vertica
SET PROC TO &&关闭过程文件
SET TALK ON
RETURN
***过程文件 PROTEST.PRG
PROC Vertica &&定义过程,vertica
PARA s &&定义形参 s
start=1
slen=LEN(s)
DO WHILE start < slen
SUBS(s,start,2)
start=start+2
ENDDO
RETURN &&返回到调用程序
FoxPro For Windows http://cc.synu.edu.cn 10
FoxPro程序设计
【 例 5.33】 调用过程文件,计算圆的面积并输出。
*主程序 MJ.PRG
SET TALK OFF
SET PROC TO YMJ
s=0
INPUT "请输入圆的半径," TO r
DO S1 WITH s,r &&带参 s,r 调用过程 S1
DO S2
SET PROC TO
SET TALK ON
RETURN
**过程文件 YMJ.PRG &&过程文件名,YMJ.PRG
PROC S1 &&过程名,S1
PARAMETERS x,r &&定义形参 s x
x=3.14159*r*r r r
RETURN
PROC S2 &&过程名,S2
s
RETURN
FoxPro For Windows http://cc.synu.edu.cn 11
FoxPro程序设计
函数是能返回值的子程序。
FoxPro提供了 200多个系统函数,自己建立的函数称自定义函数。
1、函数的定义:
[FUNCTION <函数名 >]
[PARAMETERS <参数表 >]
<语句序列 >
RETURN <表达式 >
自定义函数
。函数说明语句 FUNCTION可省略,程序名即为函数名。
。函数名命名方法同过程名,但不能和系统函数同名。
。参数说明语句 PARAMETERS <参数表 >
。函数返回语句 RETURN <表达式 >,将表达式的值作为函数值返回。
FoxPro For Windows http://cc.synu.edu.cn 12
FoxPro程序设计
2、函数的调用
<自定义函数名 > ( [<参数表 >])
=
)!(!
!
nmn
m
?
n
m C
【 例 5.34】 编写计算 K!的函数 f 【 例 5.35】 利用自定义函数 f求 Cmn的值。
*自定义函数 F.PRG *Cmn.PRG
FUNCTION F &&可省略 SET TALK OFF
PARA k INPUT "m=" to m
T=1 INPUT "n=" to n
FOR I=1 TO K Cmn=f(m)/(f(n)*f(m-n))
T=T*I?Cmn
ENDFOR RETU
RETU T &&返回值 T
FoxPro For Windows http://cc.synu.edu.cn 13
FoxPro程序设计
? 参数定义相同:
用 PARA语句说明,且为定义语句后的第一语句;
? 调用不同:
调用函数,直接调用函数名,括号中是实际参数。
调用过程,do...with<para>,with后是实际参数。
? 函数有返回值 retu <expr>,过程无返回值。
辨析:过程、函数
FoxPro For Windows http://cc.synu.edu.cn 14
FoxPro程序设计
练习:
【 例 】 子程序调用
*B.PRG
*A1+A2+A3=?
STORE 2 TO A1,A2,A3
A1=A1+A2 &&A1=4
DO B1
A1+A2+A3
RETU
*B1.PRG
A2=A2+2 &&A2=4
DO B2
A1=A1+1
RETU
* B2.PRG
A3=A3+2 &&A3=4
RETU TO MASTER
B
B1
B2
FoxPro For Windows http://cc.synu.edu.cn 15
FoxPro程序设计
【 例 】 过程调用
*y=1*2*3*4=?
SET TALK OFF
SET PROC TO SP && 打开过程文件 SP
S=0
DO SP1 WITH 5,S && 带参 5,0调用 SP1
S
SET PROC TO
RETU
*SP.PRG
PROC SP1
PARA X,Y && X=5,Y=0
N=1
Y=1
DO WHIL N<X
Y=Y*N && Y=1*1*2*3*4
N=N+1
ENDD
RETU
FoxPro For Windows http://cc.synu.edu.cn 16
FoxPro程序设计
【 例 】 调用自定义函数
*主程序
*16
SET TALK OFF
X=5
Y=SQRT(6*X+6) && 6
Z=2*JC(X)+JC(Y) && 调用自定义函数 JC
Z &&Z=2*5+6
SET TALK ON
RETU
*自定义函数,JC.PRG
FUNC JC
PARA K && X K,Y K
S=0
FOR I=1 TO K
S=S+1 && S=0+1+1+1+1+1
ENDF
RETU S
FoxPro For Windows http://cc.synu.edu.cn 17
FoxPro程序设计
【 例 】 写出程序运行结果
SET TALK OFF
C="ABCDEFG"
N=1
DO WHILE N<7
SUBSTR(C,7-N,1)
N=N+1
ENDDO
RETURN
* 程序中?命令输出的结果是 ____。
F
E
D
C
B
A
FoxPro For Windows http://cc.synu.edu.cn 18
FoxPro程序设计
【 例 】 写出程序运行结果
SET TALK OFF
CLEAR
X=0
DO WHILE X<5
Y=0
SPACE(X)
DO WHILE Y<10
STR(Y,1)
Y=Y+1
ENDDO
X=X+1
ENDDO
RETURN
0123456789
0123456789
0123456789
0123456789
0123456789
FoxPro For Windows http://cc.synu.edu.cn 19
FoxPro程序设计
【 例 】 写出程序的运行结果
SET TALK OFF
STORE 0 TO X,Y
DO WHILE,T.
X=X+1 &&x=0+1+1+1+1+1
Y=Y+X &&y=0+1+2+3+4+5
IF X>=5
EXIT
ENDIF
ENDDO
X,Y
当程序执行到?命令时,X与 Y的值分别为 ____。