1.96k likes | 2.16k Views
Chongqing University of Arts & Sciences. Visual Foxpro 程序设计. 第 6 章结构化与面向对象程序设计基础. 程序是一组能够完成特定任务的命令序列的集合。这些命令按照一定的逻辑顺序有机地结合在一起,并以文件形式存储在磁盘上,这种文件称为程序文件或命令文件, VFP 中其扩展名为 .PRG 。执行程序时,计算机按程序的逻辑顺序自动执行程序文件中的命令。与在 VFP 的命令窗口逐条输入命令相比,采用程序方式的好处有: 可利用编辑器方便地输入、编辑和保存程序。 可采用多种方式、多次运行程序。
E N D
Chongqing University of Arts & Sciences Visual Foxpro 程序设计
程序是一组能够完成特定任务的命令序列的集合。这些命令按照一定的逻辑顺序有机地结合在一起,并以文件形式存储在磁盘上,这种文件称为程序文件或命令文件,VFP中其扩展名为.PRG。执行程序时,计算机按程序的逻辑顺序自动执行程序文件中的命令。与在VFP的命令窗口逐条输入命令相比,采用程序方式的好处有:程序是一组能够完成特定任务的命令序列的集合。这些命令按照一定的逻辑顺序有机地结合在一起,并以文件形式存储在磁盘上,这种文件称为程序文件或命令文件,VFP中其扩展名为.PRG。执行程序时,计算机按程序的逻辑顺序自动执行程序文件中的命令。与在VFP的命令窗口逐条输入命令相比,采用程序方式的好处有: 可利用编辑器方便地输入、编辑和保存程序。 可采用多种方式、多次运行程序。 可以实现程序代码的复用。 6.1 结构化程序设计的基本概念 6.1.1 程序
【例6.1】编写程序文件exam6_1.prg实现例4.31。 *显示学生选课成绩表xkcjb.dbf中当前记录的学号、课程号和成绩字段的值 CLOSE ALL &&关闭所有打开的文件 SELECT 2 USE dab &&选择2号工作区打开 dab表 SELECT C USE kcb &&选择3号工作区打开kcb表 USE xkcjb IN 5 &&在5号工作区打开xkcjb表 ? xkcjb.学号,b.姓名,xkcjb.课程号,xkcjb->成绩 CLOSE ALL &&关闭所有打开的文件 RETURN
在命令窗口中执行MODIFY COMMAND exam6_1命令后,弹出代码编辑窗口,在该窗口中输入上述程序代码并保存。在命令窗口输入:DO exam6_1,程序执行结果为: 20050010 001 38.0 从该例子可以看出:程序代码保存在一个程序文件exam6_1.prg中,可以多次执行。
1)算法的概念及特点 要编制一个程序,必须首先构建解决问题的算法。所谓算法(Algorithm)就是对解决问题所采用的方法和步骤的描述。 6.1.2 算法及算法的表示 【例6.2】输入3个数,找出其中的最大值并输出。 分析:假设这3个数分别用a、b、c表示,最大值用max表示。由于计算机一次只能比较2个数,首先可以将a和b进行比较,把其中大的数放入max中,再将max与c比较,又将大的数放入max中,最后将max输出。此时max中的值就是a、b、c中的最大值。
可以将求解这一问题的算法描述为: 第1步:输入a、b、c。 第2步:将a、b中大的一个数放入max中。 第3步:将c与max中大的数放入max中。 第4步:输出max。 从该例子可以看出,算法是对一个问题的解决方法和步骤的描述,是一个有穷规则的集合。一个算法应该具有以下特点: ①确定性。一个算法给出的每个计算步骤都必须是准确的、无二义性。在【例6.2】中每一个步骤的含义都是确定的。
②有穷性。一个算法必须在执行有穷多个计算步骤后终止。在【例6.2】中执行4个步骤后问题处理结束。②有穷性。一个算法必须在执行有穷多个计算步骤后终止。在【例6.2】中执行4个步骤后问题处理结束。 ③有效性。算法中的每一个步骤必须能够有效地执行,并能够得到确定的结果。 ④输入。一个算法可以有0个或1个以上的输入。在【例6.2】中需要输入a、b、c 3个数。 ⑤输出。一个算法有1个或多个的输出,一个算法得到的结果就是算法的输出。在【例6.2】中输出的是max。
任何一个问题能否让计算机处理,关键在于能否设计出合理的算法,有了合适的算法,再使用合适的计算机语言来编写程序。VFP就是一种语言工具。要用VFP编写出高质量的程序,一方面要构建合理的算法,另一方面要掌握VFP的语法规则,它是实现算法的基础。任何一个问题能否让计算机处理,关键在于能否设计出合理的算法,有了合适的算法,再使用合适的计算机语言来编写程序。VFP就是一种语言工具。要用VFP编写出高质量的程序,一方面要构建合理的算法,另一方面要掌握VFP的语法规则,它是实现算法的基础。
2)算法的描述 算法的描述方法有很多,如自然语言、伪代码、流程图等。为直观、准确地表示一个问题的处理方法和步骤,通常采用流程图的方法。流程图是用一些几何图形符号、线条及文字说明来表征一个问题的处理过程。一般采用传统流程图和N-S图来描述算法。实现【例6.2】的算法所对应的传统流程图如图(a)所示、N-S图如图(b)所示。
开始 输入a,b,c 输入a,b,c 将a,b中大的数放在max中 将c,max中大的数放在max中 将a,b中大的数放在max中 输出max 将c,max中大的数放在max中 输出max 开始 (b) (a)
3)3种基本结构的表示 1966年,Bohra和Jacopini提出了程序的3种基本结构:顺序结构、选择(或分支)结构、循环结构,它们构成了实现一个算法的基本单元。 顺序结构:是一种最基本、最简单的程序结构。如下图所示,先执行A,再执行B,A与B按照顺序执行。 A B (a)流程图 (b)N-S图 A B
P T F A B Y N (a)流程图 (b)N-S图 条件p A B • 选择(或分支)结构:根据条件是否成立而执行不同的程序模块。在下图中,当条件P为真时,执行A,否则执行B。即要么执行A,要么执行B。
N 条件P Y A (a)流程图 (b)N-S图 条件P A • 循环结构:是指重复执行某些操作,重复执行的部分称为循环体。如图所示为当型循环结构,当条件P为真时,反复执行A,直到条件P为假时才终止循环。其中A是循环体,A被重复执行的次数称为循环次数。循环结构除当型循环外,还有直到型循环。
结构化程序设计方法是一种自顶向下、逐步求精、模块化的程序设计方法。结构化程序设计方法的思想,就是将给定的一个功能较多的复杂问题合理地划分为若干个较简单的子问题,还可以将这些子问题再分解为若干功能更简单的子任务(可将每个子任务看作一个模块),以便于“分而治之”。如下图表达了一个较复杂问题的模块分解过程。结构化程序设计方法是一种自顶向下、逐步求精、模块化的程序设计方法。结构化程序设计方法的思想,就是将给定的一个功能较多的复杂问题合理地划分为若干个较简单的子问题,还可以将这些子问题再分解为若干功能更简单的子任务(可将每个子任务看作一个模块),以便于“分而治之”。如下图表达了一个较复杂问题的模块分解过程。 问题A 问题B1 问题B2 … 问题Bn 问题C1 问题C2 问题Cn … 6.1.3 结构化程序设计方法概述
在模块划分时,应该尽可能地保证数据的独立性和模块功能的唯一性。也就是说,各模块间的耦合性要尽量弱,即一个模块最好像是一个黑盒子,模块间的数据交换要尽量少;模块的内聚性要尽量强,即每个模块只完成单一的功能。 采用结构化程序设计方法的好处是:可以使每个模块功能明确,模块间的关系简单、清晰(即可读性强),每个模块内部的修改尽可能不影响其他模块(即独立性好),同时每个模块的正确性容易验证(即可维护性好)。 在VFP中,程序模块化是通过编写子程序、过程、函数来实现的。
在VFP中,建立和编辑程序文件可以采用多种文本编辑工具实现,这些文本编辑工具可以是VFP系统提供的内部编辑器,也可以是其他常用文本编辑软件。一般在代码编辑窗口中编辑程序代码。在VFP中,建立和编辑程序文件可以采用多种文本编辑工具实现,这些文本编辑工具可以是VFP系统提供的内部编辑器,也可以是其他常用文本编辑软件。一般在代码编辑窗口中编辑程序代码。 在VFP系统环境下,建立和编辑程序文件有多种方法,在此主要介绍以下3种方式。 6.2 程序文件的建立、编辑、修改与执行 6.2.1 程序文件的建立、编辑与修改
1)在项目管理器中创建程序文件 如果要让程序包含在一个项目文件中,可在项目管理器中建立程序文件。 在上图所示的【项目管理器】中,选择【代码】选项卡中的“程序”项,单击【新建】按钮,进入代码编辑窗口,输入程序内容,如右图所示。
2)用菜单方式新建程序文件 在【文件】菜单中选择【新建】菜单选项,在出现的【新建】对话框中选择“程序”文件类型,再单击【新建文件】按钮即可进入代码编辑窗口编辑程序代码。 如果要修改已有的程序文件,则在【文件】菜单中选择【打开】菜单项,这时弹出一个包含文件列表的对话框。在【文件类型】列表框中选择“程序”,然后在文件列表中选定要修改的程序文件,单击【确定】按钮即可。
3)用命令方式新建程序文件 格式:MODIFY COMMAND [<文件名>]|? 例如,在命令窗口中输入“MODIFY COMMAND search ”命令(如图6.8所示),即可打开代码编辑窗口。如果程序文件不存在,系统就自动建立一个指定名字的新程序文件;如果文件已存在,则将打开该程序文件。
用上述3种方法之一创建程序文件后,必须在代码编辑完毕时,保存文件。其方法是选择【文件】菜单下的【保存】或【另存为】命令进行保存;也可以利用“Ctrl+W”组合键进行保存,程序将保存在当前盘的当前路径下(注意:“Ctrl+Q”组合键放弃存盘)。用上述3种方法之一创建程序文件后,必须在代码编辑完毕时,保存文件。其方法是选择【文件】菜单下的【保存】或【另存为】命令进行保存;也可以利用“Ctrl+W”组合键进行保存,程序将保存在当前盘的当前路径下(注意:“Ctrl+Q”组合键放弃存盘)。
程序文件创建之后便可执行,执行程序文件的方法有:程序文件创建之后便可执行,执行程序文件的方法有: ①若程序文件包含在一个项目中,则在【项目管理器】中,打开【代码】选项卡,展开“程序”项,选定程序文件,单击【运行】按钮。 ②在【程序】菜单中选择【运行】菜单项,在弹出的对话框中选定要运行的程序文件,单击“运行”按钮。 ③在【命令】窗口中,输入命令:DO <程序名> [WITH <参数表>]。 6.2.2 执行程序文件
输入/输出处理是计算机和用户打交道的接口,是程序设计过程中不可缺少的组成部分。处理过程中的原始数据或用户的要求都需要通过输入语句来输入,而处理结果又通过各种形式的输出语句来输出。在VFP中用于输入、输出的命令很多,在此只介绍几个常用的命令。输入/输出处理是计算机和用户打交道的接口,是程序设计过程中不可缺少的组成部分。处理过程中的原始数据或用户的要求都需要通过输入语句来输入,而处理结果又通过各种形式的输出语句来输出。在VFP中用于输入、输出的命令很多,在此只介绍几个常用的命令。 6.3 程序中常用命令 6.3.1 基本的输入/输出命令
1)INPUT命令 格式:INPUT [<提示信息>] TO <内存变量> 功能:在屏幕上显示[<提示信息>],并等待用户通过键盘输入表达式,再把表达式的值赋给指定的<内存变量>。 例如:s=75 input to a ? "a=",a 执行上述命令,若输入的内容为s+20,则输出结果为: a=95 这表明变量a接收的是表达式的值。
2)ACCEPT命令 格式: ACCEPT [<提示信息>] TO <内存变量> 功能:该命令和INPUT类似,不同的是它会把输入内容作为字符串常量赋值给指定的<内存变量>。 例如,把上例中的input改成accept: s=75 accept to b ? "b=",b 执行上述命令,若输入的内容为s+20,则输出结果为: b=s+20 这表明变量b接收的是字符串“s+20”。 说明:这两个命令中的<提示信息>可以缺省。当提示信息缺省的时候,则直接等待用户输入。
3)WAIT命令 格式:WAIT [[<提示信息>] TO <内存变量>] [WINDOW [AT <行>,<列>]][NOWAIT][CLEAR |NOCLEAR][TIMEOUT<数值表达式>] 功能:该命令的作用是暂停程序的执行,直到用户按任意键或单击鼠标或等待输入一个字符(可存入指定的内存变量)或在指定时间内继续程序的执行。
说明:在该命令中,若选用WINDOW,则会出现一个用于显示提示信息的WAIT提示窗口,通常位于主窗口的右上角。若需指定提示窗口的位置时,可使用AT实现;若同时选用NOWAIT和WINDOW,则程序不等待用户按键就继续执行;若选用NOCLEAR,则不关闭提示窗口,直到执行下一条WAIT WINDOW或WAIT CLEAR为止;若选用TIMEOUT,则在超过设定等待时间后程序自动继续执行。 例如:若在主窗口的10行、20列处显示提示信息“输入无效,请等待重新输入…”,10秒钟后自动关闭提示窗口,程序继续执行。可使用命令:WAIT“输入无效,请等待重新输入…”WINDOW TIMEOUT 10 AT 10,20。
4)基本输出命令?|?? 格式:?|??<表达式1>,[<表达式2>…] 功能:计算给定的一个或多个表达式的值,并将结果显示在屏幕上。 说明:“?”表示在当前光标的下一行输出,而“??”表示在当前光标位置处输出。
在程序中,有一些专门用于程序开始和结束、对程序进行注释以及环境设置的命令,常用的有:在程序中,有一些专门用于程序开始和结束、对程序进行注释以及环境设置的命令,常用的有: 1)注释命令 为了提高程序的可读性,编写程序时可在程序中适当加上一些注释。注释命令在执行时不做任何操作,也不影响程序的功能。 格式1:NOTE [<注释内容>] 格式2:&& [<注释内容>] 格式3:* [<注释内容>] 功能:用于在程序中加入说明,以增加程序的可读性。 说明:NOTE 和*命令用于行首注释,而&& 命令通常用于行尾注释。 6.3.2 程序文件中的辅助命令
2)程序结束命令 VFP的应用程序可以根据需要终止执行并返回命令窗口,返回操作系统或返回到调用它的上一级程序或主程序。 格式1:CANCEL 功能:结束当前 Visual FoxPro 程序的执行。 格式2:RETURN [TO MASTER] 功能:结束当前程序的执行,返回到调用它的上一级程序。带TO MASTER选项表示直接返回到主程序。 格式3:QUIT 功能:关闭所有文件,退出VFP系统,返回到操作系统。
3)清屏命令 命令格式:CLEAR 功能:清除屏幕内容。 4)SET TALK ON/OFF 功能:控制非输出性的结果是否在屏幕上显示出来。系统默认值为ON。 5)SET SAFETY ON/OFF 功能:确定在改写已有文件前,是否显示提示对话框。系统默认值为ON。
顺序结构始终按照程序中语句的先后顺序逐条执行。顺序结构始终按照程序中语句的先后顺序逐条执行。 输入h,f x = ( 4*h-f ) / 2 y = ( f-2* h ) / 2 输出s 6.4 VFP程序的三种基本结构 6.4.1 顺序结构 【例6.3】鸡兔同笼,已知鸡兔的总头数为h ,总脚数为f ,求鸡兔各有多少只? 鸡兔同笼问题的算法如图所示。
其程序文件exam6_3.prg的代码为: input “请输入鸡兔总头数:”to h input “请输入鸡兔总脚数:”to f x=(4*h-f)/2 &&x为鸡的只数 y=(f-2*h)/2 &&y为兔的只数 ?”共有鸡:”,x ?”共有兔:”,y cancel
6.4.2 选择结构 应用程序在进行数据处理时需要根据不同的条件选择执行不同的操作,使程序的流程根据不同条件来决定程序的走向,这种程序结构称为选择结构。在VFP中是用IF…ELSE…ENDIF和DO CASE…ENDCASE来实现的。
1)IF语句 格式: IF <条件表达式> <语句序列1> [ELSE <语句序列2>] ENDIF 功能:执行该语句时,若条件表达式的值为.T.,则执行<语句序列1>,否则执行<语句序列2>,然后再执行ENDIF之后的语句,如图所示。 条件表达式 T F 语句序列2 语句序列1 执行ENDIF之后的语句
说明: 在IF语句中,ELSE选项可缺省,此时在如上图中去掉<语句序列2>即可。当ELSE缺省时,如果条件表达式为.F.,则执行ENDIF后面的语句。 IF和ENDIF必须成对出现,否则程序将无法执行。 该语句可以嵌套使用,但是在嵌套使用时不能出现交叉现象。
【例6.4】 输入球的半径,计算球的体积。 其程序文件exam6_4.prg的代码为: clear input "请输入球的半径:" to r if r>0 v=(4/3)*3.1416*r^3 ? "球的体积是:",round(v,2) &&保留2位小数 else messagebox("输入半径不能为负数!") endif cancel
【例6.5】判断某一年是否是闰年。 分析:假如年份用year表示,判断year是否是闰年的方法是:year能够被400整除或year能够被4整除并且不能够被100整除 (用vfp表示的逻辑表达式为year/4=int(year/4) and year/100<>int(year/100) or year/400=int(year/400))。
其程序文件exam6_5.prg的代码为: clear input "请输入年份:" to year if year/4=int(year/4) and year/100<>int(year/100) or year/400=int(year/400) ?str(year,4)+"年是闰年" else ?str(year,4)+"年不是闰年" endif return 提示:判断一个整数M能否被另一个整数N整除,一般采用3种方法,即:判断MOD(M,N)是否等于0或INT(M/N)是否等于M/N或M%N是否等于0,若等于,则表明M能被N整除。
2)多路分支语句 格式: DO CASE CASE <条件表达式1> <语句序列1> [CASE <条件表达式2> <语句序列2> … CASE <条件表达式N> <语句序列N>] [OTHERWISE <语句序列Q>] ENDCASE
功能:从第一个CASE的条件开始判断,若<条件表达式I>(I=1、2、3…n)的值为.T.,则执行<语句序列I>(I=1、2、3…n),然后执行ENDCASE之后的语句。所以在一个DO CASE结构中,最多只能执行一个CASE语句后面的语句序列。如果所有CASE语句后的条件表达式的值均为.F.,则执行OTHERWISE之后的<语句序列Q>。OTHERWISE子句可以缺省,此时如果所有条件表达式的值均.F.,就退出该结构执行EDNCASE语句后面的语句。 说明: ①DO CASE、CASE <条件表达式I>、OTHERWISE和ENDCASE必须各占一行。 ②DO CASE和ENDCASE必须成对出现。 ③语句序列中可以嵌套各种控制结构的命令语句。
【例6.6】计算分段函数的值 分析:这是一个多分支结构的问题,实现方法很多,下面给出其中的2种。
方法1:用CASE语句实现 input "输入x的值:" to x do case case x<0 f=2*x-1 case x=0 f=4*x otherwise f=7*x-5 endcase ?"f(",x,")=",f return
方法2:用IF的嵌套结构实现 input "输入x的值:" to x if x<=0 if x<0 f=2*x-1 else f=4*x endif else f=7*x-5 endif ?"f(",x,")=",f return
【例6.7】编写程序显示当前月份的季节。 其程序文件exam6_7.prg的代码为: yue=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 messagebox("当前季节为:"+jj+"季") return
【例6.8】在学生选课成绩表xkcjb.dbf中,输入学生学号,根据该学生的成绩判断学生表现。若成绩≥85分输出“优秀”,若在70~85分输出“良好”,若在60~70分输出“及格”,60分以下则输出“不及格”。【例6.8】在学生选课成绩表xkcjb.dbf中,输入学生学号,根据该学生的成绩判断学生表现。若成绩≥85分输出“优秀”,若在70~85分输出“良好”,若在60~70分输出“及格”,60分以下则输出“不及格”。 其程序文件exam6_8.prg的代码为: use xkcjb accept "请输入学生的学号:" to xh locate for 学号=xh
if not found() ? "学号输入错误!" else do case case 成绩>=85 ?xh+"的成绩为:优秀" case 成绩>=70 and 成绩<85 ?xh+"的成绩为:良好" case 成绩>=60 and 成绩<70 ?xh+"的成绩为:及格" otherwise ?xh+"的成绩为:不及格" endcase endif use return
循环是按照给定的条件去重复执行一段具有特定功能的程序。循环结构是一种重要的程序结构。在VFP中提供了DO WHILE…ENDDO、FOR…ENDFOR、SCAN…ENDSCAN三种循环处理命令。 1)DO WHILE循环 命令格式: DO WHILE <条件表达式> <语句序列> ENDDO 功能:当执行DO WHILE语句时,如果表达式的值为.T.,则执行<语句序列>,否则结束该循环,执行ENDDO之后的语句。 假 条件 真 语句序列 ENDDO之后的语句 6.4.3 循环结构
开始 I=1,s=0 I<=100 s=s+I I=I+1 输出s I=1 s=0 N I<=100 Y 输出s s=s+I I=I+1 结束 (a)传流程图 (b)N-S图 【例6.9】计算s=1+2+3+...+100 求解该问题的算法所对应的传统流程图和N-S图如图所示。
程序文件exam6_9.prg的代码为:s=0 i=1 do while i<=100 s=s+I I=I+1 enddo ?”s=“,s cancel