第四章程序设计VisualFoxpro程序设计教案.docx
《第四章程序设计VisualFoxpro程序设计教案.docx》由会员分享,可在线阅读,更多相关《第四章程序设计VisualFoxpro程序设计教案.docx(38页珍藏版)》请在冰豆网上搜索。
第四章程序设计VisualFoxpro程序设计教案
第四章程序设计
⏹[教学目的与要求]
掌握结构化程序设计的三种结构控制语句的使用,在编程中能熟练使用程序模块,包括子程序、函数和过程。
学会设计窗口的方法。
⏹[教学内容]
结构化程序设计的三种结构;子程序,函数和过程的概念;窗口的设计。
⏹[教学重点与难点]
结构化程序设计的三种结构;子程序,函数和过程。
补充知识
★★语言基础
●数据类型
数据类型决定了数据的取值范围和可以参加的运算,只有同种类型的数据之间才可以直接运算,否则系统提示“数据类型不匹配”的错误信息。
VFP常用数据类型有:
字符型(C),货币型(Y),数值型(N),日期型(D),日期时间型(T),逻辑型(L),备注型(M),通用型(G)等。
常量和变量
1.常量指一个具体的、不变的值。
不同类型的常量有不同的书写格式。
VFP6.0中只有6种常量:
⑴数值型常量(N)
用来表示数量,它由数字0~9,e,E、一个符号(+或-)和一个小数点(.)组成。
例如:
80,-52.6,3E+9(表示3×109),2e-3(表示2×10-3)等。
⑵字符型常量(C)
用定界符括起来的由键盘上英文字母、空格、数字和汉字等字符组成的字符串。
这里的定界符可以是一对单引号或一对双引号或一对方括号。
例如:
”abcd”,’杨红’,[男]。
注意:
空串和空格串的区别;
⑶逻辑型常量(L)
只有两个值:
真和假。
“真”用.t..T.表示;“假”用.f..F.表示。
⑷日期型常量
格式为:
{^yyyy/mm/dd},{^yyyy-mm-dd},{^yyyy.mm.dd}
⑸日期时间型常量
格式为:
{^yyyy/mm/ddhh:
mm:
ss}
⑹货币型常量
$12.34
2.变量
存放可变数据的内存单元为“变量”,其中存放的数据称为变量的值。
在VFP中有3种变量:
字段变量、用户内存变量和系统内存变量。
系统内存变量由VFP定义;字段变量定义在数据表中;(用户)内存变量多定义在程序中。
每个变量都有一个名称,叫做变量名,VFP通过引用相应的变量名来实现对变量操作。
变量名的命名规则是:
以字母、汉字或下划线开头,后跟字母、汉字、数字下划线等。
例如变量名:
姓名,出生日期,a,x1,x2,sum,delta,pi,max,zdz,stu_name。
给变量命名时最好能“见名知义”。
另外,使用变量名不区分大小写。
⑴字段变量
⑵内存变量
独立于表文件而存在于内存中的存储单元,它可以用来在程序的执行过程中保留中间结果与最后结果。
内存变量的类型包括CDLNTY六种类型,类型取决于它所存放的值。
内存变量与字段变量同名,系统优先处理字段变量,可用前缀m.引用内存变量。
变量的初值:
在程序中若要使用变量,必须在使用之前为变量设定一个初值(以后根据需要还再改变它的值),这一操作可通过赋值语句实现。
赋值语句可以将指定的值赋给该变量。
一般格式为:
a.变量名=表达式
系统计算<表达式>的值,并将结果送入指定的变量。
b.store<表达式>to<内存变量名表>
系统计算<表达式>的值,并将结果送入<内存变量名表>中的各个变量中。
说明:
Ⅰ、计算机先计算右边表达式的值,然后再将该值赋给指定变量。
Ⅱ、不要将赋值号(=)与是数学中的等号混淆,a=5应读作“将数值5赋给变量a”或是“使变量a的值等于5”。
不同于数学表达式,下面两个语句的作用是不同的
x=y
y=x
Ⅲ、不同于C语言,VFP是一种弱类型语言,它允许通过此语句随时定义一个变量,并其值可以随时改变。
x=10&&定义变量x,并赋初值
x=x+10&&将x的值在原来的基础上增10
x=x*x&&将x的值平方后再赋值给x
Ⅳ、z=x+y不能写成x+y=z
Ⅴ、在引用一个变量前必须确保它已经赋值。
x=3
y=x*10
y=z+2&&此时系统提示出错:
找不到变量z
[例1]
usesb
browse
?
名称&&显示字段名称的值
名称=”计算机”&&定义内存变量名称,c型,
?
名称&&显示字段名称的值
?
m.名称&&显示内存变量姓名的值
[例2]
store28.21toa
store“宿州学院”tob
store.t.toc
d=$100
e={^2002.5.10}
store0tox,y,z
数组
运算符和表达式
运算是对数据进行加工的过程,描述各种不同运算的符号称为运算符,如加、减、乘、除,而参与运算的数据称为操作数。
表达式由运算符和配对的圆括号将常数、变量、函数等操作数以合理的形式组合而成的式子。
一、算术运算符及数值表达式
a.算术运算符。
它们运算的含义与数学中基本相同。
+加法、正号
-减法、负号
*乘法,同数学中的×
/除法,同数学中的÷
^或**乘方,同数学中的乘方,如4^3或4**3表示43
%求余,12%5表示12除以5所得的余数2
()括号,只允许出现圆括号
算术运算符在计算时的优先次序是:
()→^**→*/%→+-
b.算术表达式
50*2+(70-6)/8,
a+b/a-b,(a+b)/(a-b)(哪个相当于
?
)
c.注意事项:
算术表达式与数学中的数学表达式写法有所区别,在书写表达式时应当特别注意:
每个符号占1格,所有符号都必须一个一个并排写在同一横线上,不能在右上角或右下角写方次或下标。
例如:
23要写成2^3,
X1十X2要写成X1+X2。
原来在数学表达式中省略的内容必须重新写上。
例如:
2X要写成2*X。
所有括号都用小括号(),且括号必须配对。
例如:
3[x+2(y+z)]必须写成3*(x+2*(y+z))。
要把数学表达式中的某些希腊、拉丁符号,改成VFP中可以表示的符号。
例如:
要把2πr改为2*pi()*r。
例如:
数学的求根公式
应写成(-b+sqrt(b^2-4*a*c))/(2*a)和(-b-sqrt(b^2-4*a*c))/(2*a),这里的sqrt是个数学函数,求数的平方根。
二、字符串运算符及字符表达式
字符串运算符
c1+c2将c1和c2连接形成一个新串。
c1-c2将c1的尾部空格移到c2后在连接成新串。
"ABCl23"+"666xyz"连接后结果为:
"ABCl23666xyz"
"ABC"-"DEFG"连接后结果为:
"ABCDEFG"
三、日期表达式
日期+天数、日期-天数、日期1-日期2
四、关系运算符及关系表达式
用于判定指定的数据是否满足给定的关系,若满足计算的值为.t.;否则结果为.f.
(1)运算符
=等于
>大于
>=大于等于
<小于
<=小于等于
<>或#或!
=不等于
c1$c2判断c1是否包含在c2中
==字符型数据的精确相等
(2)表达式常用于表示条件
?
5>3&&结果为.t.
x=3
?
x=3
store“中国北京”tos1
store“北京”tos2
?
s2$s1&&结果.t.
?
s1$s2&&结果.f.
五、逻辑型运算符及逻辑型表达式
逻辑型运算符将逻辑型数据连接起来的式子。
前面关系运算的结果是逻辑型,因而逻辑型运算符常用于描述较复杂的关系,例如1≤x≤10等。
(1)运算符
①and与操作(.and.)
格式:
条件1and条件2
例如:
x>=1andx<=10
说明:
只有两个条件都为.t.时,结果为.t.(也称条件满足);否则结果为.f.(也称条件不满足)。
②or或操作(.or.)
格式:
条件1or条件2
例如:
x<=-1orx>=1
说明:
两者中只要有一个条件.t.,结果为.t.;否则,结果为.f.
③not条件取反(.not.)
格式:
not条件
例如:
notx>1相当于x<=1
说明:
对条件取反
注意:
复合条件运算符在计算时的优先次序是:
not→and→or
(2)表达式
数学式1≤x≤10
(x>=1)and(x<=10)
a是偶数或是3的倍数
a%2=0ora%3=0
a≤b也可以写成
nota>b或a<=b
任意三个数能否构成三角形的判定条件:
a+b>canda+c>bandb+c>a
year是否闰年:
(year%400=0)or(year%4=0andyear%100<>0)
说明:
一个表达式中出现多种运算,先进行算术运算,再比较大小,最后将比较结果进行复合。
常用函数
在VFP中,算术运算仅提供加减乘除的四则运算,如何求一些复杂的运算(例如正弦、余弦)呢?
学过高数的同学知道有个“泰勒公式”,太复杂!
事实上,为方便用户编程,每种程序设计语言都提供功能强大的系统函数(与数学上的函数没有什么区别)供用户调用,从而避免了一些繁琐的计算。
从程序设计的角度来看,函数是子程序的一种,它能完成一种特定的运算。
函数有三要素:
函数名、逗号分开的参数、函数值。
例如abs(-9),max(9,-3)等。
我们用户在学习使用这些函数时要注意参数的个数、参数的约束条件及函数值的类型,比如date()是无参函数,返回一个日期值;求平方根函数sqrt需要一个参数,并且只能是个非负数。
1.数值函数
函数格式
说 明
abs(n)
求n的绝对值 例如:
abs(-9)的值是9
int(n)
取n的整数部分例如:
int(4.5)的值是4,int(-4.5)的值是-4
sin(n)
cos(n)
对n分别求正弦和余弦值
max(n1,n2,…)
min(n1,n2,…)
求n1、n2…中的最大者例如:
max(9,3)的值是9
求n1、n2…中的最小者例如:
min(9,3)的值是3
sqrt(n)
求n的平方根(n>=0) 例如:
sqrt(9)的值是3
mod(m,n)
求m%n的值,可用%替代。
rand([n])
返回0到1之间的随机数
2.字符函数
函数格式
说 明
len(c)
求字符串c长度。
例如len(“a123bcde”)的值是9。
Len(“奥运会”)的值为6,len(””)的值为0
space(n)
产生含有n个空格的字符串。
例如space(5)得到字符串””。
alltrim(c)
删除字符串c的首尾空格。
substr(c,n[,m])
求子串。
从字符串c中提取从n开始的m个字符的子串。
substr(“abcde”,2,3)结果”bcd”,substr(“abce”,1,1)结果”a”,substr(“abce”,2)结果”bce”。
left(c,n)
right(c,n)
右或左取字符串c的n的字符形成一个新串
upper(c),lower(c)
求字符串c的大写或小写形式的字符串
replicate(c,n)
将指定的c重复n次,形成一个字符串
at(c1,c2)
求串c1在c2中第一次出现的位置;若不出现c2中,返回值为0
3.日期函数
函数格式
说 明
date()
返回系统日当前日期
time()
返回系统日当前时间
year(d)
month(d)
day(d)
对一个日期求四位年份、月份、日数
4.转换函数
转换函数的作用是将某一种数据类型转换成另一种数据类型,以便在一起参加运算。
函数格式
说 明
str([[,n3]])
将数值n1转换成数字字符串(n→c)
val(c)
将字符串c转换成数值型数据(c→n)
asc(c)
求字符串c中首字符的asc值
说明:
”A”~”Z"的asc值是65~90;”a”~”z”的asc值是97~122
chr(n)
根据asc值求对应的字符
ctod(c)
将形如日期的字符串c转换成日期型数据
见例3-36,37,38,39
5.测试函数
函数格式
说 明
eof([n]),bof([n])
判定表文件的记录指针是否到文件头或文件尾
recno([n])
求表文件的当前记录号
reccount([n])
求表文件的总记录个数
found([n])
测试针对表文件的查找是否成功
ctod(c)
将形如日期的字符串c转换成日期型数据
type(“表达式”)
测试表达式的类型例如:
type(“12”)值是n,type(“[12]”)值为c
iif(<条件表达式>,<值1>,<值2>)
测试条件表达式的值,若为.t.,函数的值是<值1>;否则函数的值是<值2>。
说明:
⑴这里的n均指表所在的工作区,缺省时指当前工作区。
⑵type函数形式较特殊。
§4.1程序文件
4.1.1程序文件的建立与执行
一、程序文件(*.prg)的建立与修改
命令格式:
modifycommand<文件名>
说明:
(1)程序文件由VFP命令组成。
文件名前也可以指明路径,如:
modifycommande:
\s12\qh
(2)关闭编辑窗口的方法:
Ctrl+W;Esc;双击控制菜单;关闭按钮
(3)文本编辑窗口也可以编辑由ASCII字符组成的非.PRG文件。
二、程序的运行
命令格式:
Do<文件名>
功能:
执行程序
说明:
Do也可以运行其它程序,<文件名>必须包含扩展名。
三、程序书写规则
1、命令分行
续行符’;’
2、命令注释
独立的注释行是以*开头;注释部分以&&开头。
[例]
*本程序用于修改表的指定记录
setdateUSA&&日期格式设置为MM-DD-YY
四、求解的基本逻辑与程序通用性
1、求解的基本逻辑
输入数据处理数据输出数据
r=3
s=3.14*r*r
?
”圆面积=”,s
2、程序的通用性
4.1.2程序文件中的专用命令
一、程序结尾的专用命令
return:
使程序结束执行,返回到调用它的上级程序继续执行,若无上级程序则返回到命令窗口。
一般缺省。
cancel:
能使程序运行终止,清除程序的私有变量,并返回到命令窗口。
quit:
正常退出VFP,自动保存文件,并删除磁盘中的临时文件,程序终止运行后返回到Windows。
二、输入输出专用命令
命令基本格式:
@<行,列>[say<表达式1>][get<变量名>][default<表达式2>]
(1)<行,列>表示数据在窗口中显示的位置。
(2)say子句用来输出数据,get子句用来输入数据及编辑数据。
(3)get子句中的变量必须具有初值,或用default子句的<表达式>指定初值。
(4)get子句的变量必须用read命令来击活。
[例4-1]编程根据记录号来修改某设备的价格和部门。
*e4-1.prg
clear
usesb
jlh=1
@2,10say“请输入记录号:
”getjlh
read
gojlh
@4,10say“请修改第”+str(jlh,1)+”个设备的数据:
”&&输出提示字符串
@6,10say“价格”get价格
@8,10say“部门”get部门
read
use
三、wait命令
命令格式:
wait[<信息文本>][to<内存变量>][windows[at<行>,<列>]]
[nowait][clear|noclear][timeout<数值表达式>]
说明:
(1)wait命令使VFP程序暂停执行,等用户按任一键后,程序继续执行。
(2)<内存变量>用来保存键入的字符,如果不选to子句,则输入的数据不予保存。
(3)如果缺省<信息文本>,则执行命令后屏幕显示”按任意键继续…”,提示按任一键继续执行。
(4)Windows子句可使主屏幕上出现一个wait提示窗口,位置由wait选项的<行>,<列>来指定。
若缺省at选项,<信息文本>将显示在主屏幕右上角。
(5)若使用nowait选项,系统将不等用户按键,立即往下执行。
(6)clear选项用来关闭提示窗口。
Noclear表示不关闭提示窗口,wait窗口将在执行到下一个wait…window命令时自动关闭。
(7)timeout子句用来设定等待时间(秒数),一旦超时自动往下执行命令。
[例4-2]wait命令输出信息示例
wait“请检查输入内容!
”window
§4.2程序的控制结构
4.2.1顺序结构
按照语句排列顺序的先后执行。
4.2.2分支结构
一、简单的条件语句
语句格式:
if<逻辑表达式>
<语句序列>
endif
[例4-3]将sb.dbf中第一个非主要设备的价格减少10%。
*e4-3.prg
usesb
locatefoenot主要设备
iffound()
display名称,价格
replace价格with价格*(1-0.1)
display名称,价格
endif
use
return
二、带else的条件语句
语句格式:
if<逻辑表达式>
<语句序列1>
else
<语句序列2>
endif
宏代换函数格式:
&<字符型内存变量>[,<字符表达式>]
功能:
替换出字符型内存变量的值。
[例4-4]宏代换示例
m=5
x=”m”&&x为字符型内存变量
?
x&&显示m
?
&x&&显示5,得到了变量x的值。
[例4-5]试编一程序,能打开任意一个表来浏览。
*4-5.prg
@5,10say“请输入表名:
”getbmdefaultspace(10)
read
bm=alltrim(bm)
iffile(“&bm.dbf”)
use&bm
browse
else
wait”该文件不存在!
”window
endif
注意:
VFP不允许直接用变量名作为表名。
还可以用use(bm)。
三、多分支语句
语句格式:
docase
case<逻辑表达式1>
<语句序列1>
case<逻辑表达式2>
<语句序列2>
……
case<逻辑表达式n>
<语句序列n>
[otherwise
<语句序列n+1>]
endcase
[例4-6]显示当前季节程序
*e4-6.prg
yue=month(date())
docase
caseinlist(yue,3,4,5)
jj=”春”
caseinlist(yue,6,7,8)
jj=”夏”
caseinlist(yue,9,10,11)
jj=”秋”
caseinlist(yue,12,1,2)
jj=”冬”
endcase
waitjjwindow
注意:
(1)if和endif必须成对出现;docase和endcase必须成对出现。
(2)采用缩进的书写格式,便于理解和阅读。
(3)表达分支和循环的语句不能在一行写完,必须一行一行的写。
4.2.3循环结构
一、条件循环
语句格式:
dowhile<逻辑表达式>
<语句序列>
enddo
[例4-7]试编一个程序,显示sb.dbf中所有单价超过10000元的设备名称。
*e4-7.prg
usesb
dowhilenoteof()
if价格>10000
?
名称
endif
skip
enddo
use
[例4-8]按9万元以上,1~9万元,1万元以下三级价格分档统计sb.dbf中设备的个数。
*e4-8.prg
store0tok1,k2,k3
usesb
dowhilenoteof()
docase
case价格>90000
k1=k1+1
case价格<10000
k3=k3+1
otherwise
k2=k2+1
endcase
skip
enddo
?
”9万元以上设备个数:
”+str(k1)
?
”1~9万元设备个数:
”+str(k2)
?
”1万元以下设备个数:
”+str(k3)
use
二、步长循环
语句格式:
for<内存变量>=<数值表达式1>to<数值表达式2>[step<数值表达式3>]
<语句序列>
endfor|next
说明:
内存变量称为循环变量;<数值表达式1>称为初值;<数值表达式2>称为终值;<数值表达式3>称为步长,缺省为1。
[例4-9]编写计算s=1+2+3+…+100的程序。
*e4-9.prg
s=0
fori=1to100
s=s+i
next
?
”s=”,s
三、扫描循环
语句格式:
scan[<范围>][for<逻辑表达式1>][<逻辑表达式2>]
<语句序列>
endscan
说明:
scan针对于当前表进行循环。
[例4-10]根据4-7的要求,用扫描循环语句编程。
*e4-10.prg
usesb
scanfor价格>10000
?
名称
endscan
use
四、循环辅助语句
dowhile<逻辑表达式>
…
dowhile<逻辑表达式>
…
Loop
…
exit
…
enddo
enddo
[例4-11]编程计算s=1+2+3+…+100,并求1~100之间的奇数之和。
*e4-11.prg
store0toi,s,t
dowhilei<100
i=i+1
s=s+i
ifint(i/2)=i/2
Loop
endif
t=t+i
enddo
?
”1+2+3+…+100=”,s
?
”1~100奇数和为:
”,t
五、多重循环(循环的嵌套)
[例4-12]在sb.dbf表中找出所有价格超过P的设备的编号、名称与价格,并要求在各输出行下显示一行虚线。
*e4-12.prg
clear
usesb
@5,10say”请输入价格:
”getjgdefault0
read
scan
if价格?
编号+space(3)+名称+space(3)+str(价格,9,2)
?
fori=1to30
?
?
”-“
endfor
endif
endscan
use
§4.3多模块程序
4.3.1子程序
一、调用和返回
调用:
Do
返回:
Return
二、带参数子程序的调用与返回
命令格式:
do<程序名1>[with<参数表>][in<程序名2>]
说明:
(1)<参数表>中的参数可以是表达式,但若是内存变量必须具有初值。
(2)当<程序名1>是in子句<程序名2>中的一个过程时,Do命令调用该过程。
子程序中的参数格式: