版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章结构化程序设计基础9.1程序文件9.2程序方式下的几个基本命令9.3程序的基本结构9.4过程9.5内存变量作用域9.6预处理语句练习九
9.1程序文件
9.1.1程序文件的概念
使用计算机的命令,为解决一个问题而设计的命令的有序集合称为计算机程序,存放程序的文件称为程序文件。在高级语言中,程序分为源程序、目标程序和可执行程序。其中,源程序又称为源代码,是用ASCII字符编写的程序;目标程序和执行程序都是二进制代码。计算机并不能直接执行源代码,必须将它用编译器进行编译得到目标程序,然后还得通过连接器将目标代码与系统函数等相连接,最后方可生成可执行代码。
9.1.2源程序文件的建立、编辑与运行
建立源程序文件是整个程序运行方式中最关键也是最难的一步。VFP9.0自带了程序编辑器,可供用户直接在集成环境中编写源程序。打开VFP9.0程序编辑器的方法和打开其它设计器的方法一样分为命令方式和菜单方式两种。
1.命令方式打开程序编辑器
无论是创建还是修改源程序文件,都应在程序编辑器中进行,打开程序编辑器的命令是MODIFYCOMMAND。
【命令格式】
MODIFYCOMMAND[FileName|?][NOEDIT][NOMENU][NOWAIT]
[RANGEnStartCharacter,nEndCharacter]
[[WINDOWWindowName1]
[IN[WINDOW]WindowName2|INSCREEN]]
[ASnCodePage][SAVE]
【功能】
该命令用于打开一个文本编辑窗口,以便创建或修改源程序文件。
【参数和子句说明】
● FileName:指定要打开或创建的程序的文件名。源程序文件的缺省扩展名是“.prg”。该命令允许使用通配符“*”和“?”,此时与通配符相匹配的每一个源程序文件都将在各自的编辑窗口被打开。如果文件名缺省,则最初以“程序1.prg”命名的源程序文件将被打开。当用户关闭窗口时,可以将程序另存为其它的文件名。
● ?、NOEDIT、NOWAIT、ASnCodePage:与前面各命令含义相同。
● NOMENU:删除VFP系统菜单条的格式菜单标题,从而避免改变字体等。● RANGEnStartCharacter,nEndCharacter:当编辑窗口打开时,指定所选字符的范围。nStartCharacter为开始位置,nEndCharacter为结束位置。
● WINDOWWindowName1:指定编辑窗口的特性。例如,如果窗口是用DEFINEWINDOW中的FLOAT选项创建的,则它可以移动。窗口不需要被激活或可见,但必须被定义。
● IN[WINDOW]WindowName2:指定被打开窗口的父窗口。编辑窗口并不呈现父窗口的特性但不能移到父窗口之外。如果父窗口被移动,则编辑窗口将随之移动。为了访问编辑窗口,父窗口必须首先用DEFINEWINDOW命令定义,并且必须是可见的。● INSCREEN:当编辑窗口被以INWINDOW子句放置在一个辅助窗口中时,如果要在VFP主窗口打开它,可通过INSCREEN字句指定。
● SAVE:允许编辑窗口打开后其它窗口被激活。如果缺省SAVE,当其它窗口被激活时编辑窗口将被关闭。SAVE在命令窗口下无效。
注意,尽管参数很多,然而最常用的最简格式是:
MODIFYCOMMANDprg_FileName
例9.1
编写一个求球表面积和球体积的程序“qiu.prg”。
MODIFYCOMMANDqiu
在程序编辑器中输入如图9.1所示的程序内容,完成之后用【Ctrl+W】或【Ctrl+End】或【×】存盘,若要放弃,可按下【Esc】或【Ctrl+Q】。
观察该源程序的各条命令,发现这些命令除INPUT和RETURN外,都是前面交互式下学过且比较熟悉的命令。INPUT命令是在程序方式下的三个交互式输入语句之一,RETURN命令在这里仅表示程序的结束。对于这些命令,除严格按照第2章所讲的命令书写格式进行书写外,还需特别强调的是:图9.1程序编辑窗口
(1)在书写源程序时,必须严格执行“一行最多写一句”的原则。
(2)一句可以占多行,用分号“;”作为续行符,它应出现在上一行的末尾。
(3)除在字符串内部根据需要可用全角标点符号外,其它情况下一律使用英文半角标点符号。
(4)一个源程序文件只能包含一个程序,否则始终只执行程序文件中的第一个程序。
(5)养成良好的源程序书写习惯,采用缩进方式编写源程序,以便程序调试和交流。
(6) VFP程序对于字母并不区分大小写,然而为了方便程序的调试与美观,最好所有系统的保留字全部大写,而参数则一律小写。所幸的是VFP9.0遇到保留字时自动会转换为大写字符,且以蓝色给出,参数则不改变大小写方式并以黑色给出,因此用户只要在小写状态下放心编程即可。
(7)源程序写完后应及时存盘。
2.菜单方式打开程序编辑器
利用菜单法打开程序编辑器的步骤同于打开其它设计器,即→“文件”→“新建…”→“程序”→【新建】。
3.程序的三大板块
不管程序复杂还是简单,一个程序大体都可以分为三大板块。
(1)程序初始化板块。在这个板块中,一般将完成对程序运行环境的设置和变量的初始化工作,如例9.1中的“CLEAR”语句。最常用到的是一系列的SET语句。
(2)程序主体板块。该板块用来完成本程序的任务。如例9.1中从“input”开始到“?'球的体积':”语句之间的语句都是程序的主体语句。
(3)系统环境设置恢复板块。该板块的任务是当程序所预定的任务完成后,在结束程序运行之前,将系统环境恢复到原设置状态,常用的命令有关闭文件、一系列SET语句、程序结束语句等。
当然,在程序中也应包含若干个注释语句,以增加程序的可读性,如例9.1中的第1句“*这是一个求球的表面积和体积的程序”。
4.程序文件的运行
程序的执行分为两种情形。
(1)编辑状态下运行程序。单击工具栏上的运行按钮,即可运行正在编辑的程序。
(2)执行已存盘的程序。有两种方式:
● 在命令窗口使用DO命令:
DOProgramName
● 使用菜单:→“程序”→“运行”↓运行,选择或输入要运行程序的文件名,→【运行】。
例9.2
运行求球表面积和球体积的程序“qiu.prg”。
DOqiu
如通过键盘输入半径5,则会立即得到相应的结果。如果程序中某处有错误,系统将停留在该句,并指出错误的原因,供用户调试源程序时参考。9.2程序方式下的几个基本命令
程序中的基本命令是指在程序方式下的交互式输入命令、注释命令、环境设置命令等。
9.2.1交互式输入命令
交互式输入命令是指程序运行时当执行到该条命令时,程序就会停留在该处且光标不断闪动,等候用户从键盘上输入有关的值。在VFP中,这类命令有三条:WAIT、INPUT、ACCEPT。
1.单字符输入命令(WAIT)
【命令格式】
WAIT[cMessageText][TOVarName][WINDOW[ATnRow,nColumn]]
[NOWAIT][CLEAR|NOCLEAR][TIMEOUTnSeconds]
【功能】
该命令用于显示信息文本并暂停VFP程序的执行,直到用户按任意键或单击鼠标左键或超过时限。其最大的特点是只要按下任意键无需按回车键即可继续向下执行。
【参数和子句说明】
● cMessageText:指定等待时的提示信息,最长255个字符。如果缺省,则将显示系统提供的“按任意键继续……”。VFP会将对象引用自动转换为字符串“对象”。如果指定表达式的运算结果是一个非字符型数据,则系统自动使用TRANSFORM()函数将它转换为字符型数据。
● TOVarName:指定将用户所按键的字符存放在一个字符型内存变量中,若缺省此子句则不保存按键的值。
● WINDOW[ATnRow,nColumn]:该选项可以将所要显示的信息显示在一个窗口中,该窗口默认的位置为屏幕的右上角,可使用[ATnRow,nColumn]子句指定窗口显示的位置。● TIMEOUTnSeconds:用来设定WAIT命令等待的时间,单位为秒。如果超过限定时间,即使用户没做任何操作,程序也将继续向下运行WAIT语句下面的程序语句。
● NOWAIT:意义同前。
● CLEAR:在程序中,将移去VFP系统窗口或从VFP主窗口移去WAIT的信息窗口。例如,如果使用了SETTALKWINDOW,则索引、排序等将被控制在VFP窗口中。如果此时按任意键或移动鼠标,则窗口将被交互式移去。该关键字仅在程序中有效。
● NOCLEAR:指定将WAIT信息窗口保留在VFP主窗口中,直到WAITCLEAR或其它的WAITWINDOW命令执行或者一个VFP系统信息被显示为止。
例9.3WAIT命令练习。
*Lwait.prg这是一个WAIT命令的练习程序
CLEAR
WAIT"欢迎学习VisualFoxPro9.0!"WINDOW;
ATSROWS()/2,SCOLS()/2TIMEOUT2
?"VisualFoxPro9.0是一个微机上使用最广泛的关系型数据库系统。"
RETURN执行该程序,当执行到WAIT命令时,将在屏幕中心位置出现一个窗口,并有提示信息:“欢迎学习VisualFoxPro9.0!”,此时用户只要按下键盘上的任意一个键或单击鼠标,或不做任何操作等待2秒,程序将继续执行并显示出:“VisualFoxPro9.0是一个微机上使用最广泛的关系型数据库系统。”
注意本程序中的SROWS()、SCOLS()函数,它们分别返回VFP主窗口的行数和列数。
2.字符串输入命令(ACCEPT)
【命令格式】
ACCEPT[cMessageText]TOcMVarName
【功能】
通过键盘输入一个字符串并按回车键后,该命令将把输入的字符串赋给指定的内存变量cMVarName,并使程序继续执行下面的语句。
【参数及子句说明】
● cMessageText:指定的提示信息文本。缺省时不予提示。
● TOcMVarName:指定写入的字符型内存变量,不得缺省。
注意:由键盘输入字符串时无需加定界符。如加了定界符,则定界字符也算作字符串的一部分。
例9.4
观察下列程序Laccept.prg的运行结果。
*Laccept.prg这是一个ACCEPT命令的练习程序
CLEAR
ACCEPT“请输入要查询的表的名字:”TObmz
SELECT*FROM&bmz&&这是宏替换函数的一个重要用途
RETURN
程序运行时,若用户从键盘上输入“xsjbqkb”,按回车键后,则会显示出“xsjbqkb.dbf”的所有信息。
3.表达式输入命令(INPUT)
【命令格式】
INPUT[cMessageText]TOMVarName
【功能】
该命令与ACCEPT功能类似,但它接收由键盘上输入的表达式运算的结果。
【参数说明】
● cMessageText:提示信息文本,缺省时无提示。
● TOMVarName:指定要写入表达式值的内存变量的名字。
例9.5
设计一个INPUT语句的练习程序。
*Linput.prg这是一个INPUT命令的练习程序
CLEAR
A="xs"
B="cjb"
INPUT"请输入表名并置表达式:A+B:"TOdbfname
SELECT*FROM&dbfname
RETURN
程序运行时,用户按提示从键盘输入字符串:
a+b
就会得到xscjb.dbf的查询结果。9.2.2其它命令
1.设置会话状态命令(SETTALKON|OFF|WINDOW[WindowName]|NOWINDOW)
VFP9.0的一个特点是命令执行时会在屏幕上显示命令执行的有关信息,称为“会话(TALK)”。会话方式可以帮助用户了解命令执行的情况,但频繁显示执行信息与输出语句的输出结果相互夹杂,既使得屏幕显得凌乱不堪,又会严重降低程序的执行速度。用户通过SETTALK命令设置会话状态,可有效解决此问题。● ON:(缺省值)允许将会话设置到VFP窗口、系统信息窗口、图形状态窗口或者用户自定义的窗口。
● OFF:在上述窗口中关闭会话。
● WINDOW[WindowName]:指定要打开或关闭会话的用户自定义窗口名。
● NOWINDOW:直接在VFP窗口关闭或打开会话。
2.设置系统提供保护状态命令(SETSAFETYON|OFF)
当用户向VFP9.0发出修改、删除、清表等涉及到文件安全的命令时,系统给出一个文件操作确认提示窗口,向用户提供下一步操作的选择。是否需要该提示窗口,可通过SETSAFETYON|OFF命令来设置,默认为ON。ON表示需要,OFF表示不需要。
3.设置默认路径命令(SETDEFAULTTOPath)
本命令用来设置VFP用户此次上机的缺省路径,参数Path为要设置的缺省路径。
例9.6
设用户的文件夹为d:\xxvfp9,请将该文件夹设置为本次VFP的缺省路径。
SETDEFAULTTOd:\xxvfp9
此后,在本次VFP运行期间,只要文件名中无路径前缀,则一定指d:\xxvfp9文件夹中的文件。
4.系统提示信息窗口MESSAGEBOX()函数
MESSAGEBOX()函数是VFP9.0提供的一个固定格式的系统窗口。
【函数格式】
MESSAGEBOX(eMessageText[,nDialogBoxType][,cTitleBarText][,nTimeout])
【功能】
该函数用于显示一个用户定义的对话窗口,并根据所按的键返回一个对应的数值。
【参数说明】
● eMessageText:设定对话窗口中要出现的提示信息。用户也可以设定一个有效的VFP函数、对象或数据类型来替代eMessageText。文本最多1024个字符。非字符型数据将被使用TRANSFORM()函数自动转换成字符型数据。● nDialogBoxType:设定出现在对话框中的按钮和图标、缺省按钮及对话框特性。它由三部分组成:
nDialogBoxType=n1+n2+n3
如果nDialogBoxType缺省,等价于将n1、n2、n3都设置为0。
表9.1给出了nDialogBoxType的三个分量的取值及意义。
nDialogBoxType的三个分量既可以用表达式的形式给出,也可以用结果值的形式给出。例如,既可写为2+32+256,又可写为290,因为290只能唯一地被解释为2+32+256。它们都表示对话框应具有下面的特征:有【终止】、【重试】、【忽略】三个按钮;信息框显示为问号图标;第二个按钮【重试】为缺省按钮。● cTitleBarText:设定对话框标题。如果缺省,则以“MicrosoftVisualFoxPro”为标题。
● nTimeout:设置一个在清除信息文本前未从键盘或鼠标输入数据时,以毫秒为单位的信息窗口的显示时间。用户可设定一个有效的超时值。如果该值小于1,则等价于缺省超时设置——不设置超时时限。
● 函数的返回值为用户按下按钮的编号,其含义为:1——【确定】、2——【取消】、3——【终止】、4——【重试】、5——【忽略】、6——【是】、7——【否】、-1——未击任何键。
例9.7
设置一个如图9.2所示的信息提示窗口。要求有【是】、【否】、【取消】三个按钮,缺省按钮为【是】,信息图标为信息号。
?MESSAGEBOX("这是一个信息框的演示例子",3+64+0,"演示实例")
结果即如图9.2所示。在单击【是】时会返回按钮【是】的标号6。
注意:如增加一个超时参数值2000,但在该时限内并未按任何键,则超时后信息框自动消失,且返回-1。图9.2信息对话框
5.终止程序运行命令
终止程序运行的命令有三条:RETURN、CANCEL、QUIT。
● RETURN:用来结束正在执行的过程,并返回到上级主调过程的调用处,如果RETURN所在的过程本身就是主程序,则返回VFP窗口。
● CANCEL:中断正在执行的程序,返回到VFP窗口下,并清除所有的私有和局部内存变量。
● QUIT:终止程序运行后,将清除所有用户内存变量,关闭所有文件,退出VFP,并返回到Windows状态。
6.注释语句
注释语句用于在程序中插入注释文本,以提高程序的可读性。它可以采用以下两种格式:
(1)整行注释:
*cNoteText
或NOTEcNoteText
(2)命令行末尾加注释说明:
Command&&cNoteText
7.CLEAR命令
在前面的各章节中,都接触过CLEAR命令,下面给出它的完整格式。
【命令格式】
CLEAR[ALL|CLASSClassName|CLASSLIB
ClassLibraryName
|DEBUG|DLLS[cAliasNameList]|EVENTS|ERROR|FIELDS
|GETS|MACROS|MEMORY|MENUS|POPUPS|PROGRAM
|PROMPT|READ[ALL]|RESOURCES[FileName]|TYPEAHEAD|WINDOWS]
【功能】
该命令用于从内存中释放指定的项目。
【参数及子句说明】
● ALL:除系统变量、编译程序缓冲区、对象类型变量外,关闭其余的所有文件、变量、窗口、菜单,将工作区号置为1。
● CLASSClassName:释放类定义。
● CLASSLIBClassLibraryName:释放包含在可视化类库中的所有类定义。
● DEBUG:释放调试器中的所有断点,并且将调试器窗口存储到它们默认的位置。● DLLS[cAliasNameList]:释放用DECLARE-DLLcAliasNameList所声明的外部共享库。
● EVENTS:停止用READEVENTS命令所开始的事件处理过程。当CLEAREVENTS执行后,程序将继续执行READEVENTS紧后面的程序。
● ERROR:重新设置VFP错误结构,如同没有错误发生。
● FIELDS:释放用SETFIELDS生成的一个列表,并且执行SETFIELDSOFF。
● GETS:释放所有的@…GET控制。
● MACROS:释放所有的键盘宏,包括任何SETFUNCTION键分配。● MEMORY:释放除系统内存变量外的所有的公共内存变量、私有内存变量和数组。
● MENUS:释放所有的菜单定义。
● POPUPS:释放所有用DEFINEPOPUP所生成的弹出式菜单定义。
● PROGRAM:释放编译程序缓冲区。
● PROMPT:释放用@…PROMPT命令生成的条菜单。
● READ[ALL]:向后兼容。已被CLEAREVENTS代替。
● RESOURCES[FileName]:指定释放隐藏的位图、图形、字型、光标或图标文件。如果文件名缺省,则这些类型的所有文件将被释放。● TYPEAHEAD:删除键盘缓冲区。当用户想避免输入一个字段或避免在字段或提示显示前就响应提示时,该参数非常有用。
● WINDOWS:释放用户自定义的窗口定义和从VFP主窗口或活动的用户自定义窗口清除窗口。使用SAVEWINDOW命令可以把窗口定义存储到一个文件或备注型字段中,以便后面使用。使用CLEARWINDOWS也可以释放访问表单的任何系统变量。
● 当所有子句和参数全部缺省时,表示清除当前窗口的显示,使光标移到窗口左上角。
8.窗口的定义
【命令格式】
DEFINEWINDOWWindowName1
FROMnRow1,nColumn1TOnRow2,nColumn2
|ATnRow3,nColumn3SIZEnRow4,nColumn4
[IN[WINDOW]WindowName2|INSCREEN|INDESKTOP[NAMEObjectName]
[FONTcFontName[,nFontSize[,nFontCharSet]]][STYLEcFontStyle]
[TITLEcTitleText]
[DOUBLE|PANEL|NONE|SYSTEM|cBorderString]
[CLOSE|NOCLOSE][FLOAT|NOFLOAT][GROW|NOGROW][MDI|NOMDI]
[MINIMIZE|NOMINIMIZE][ZOOM|NOZOOM][ICONFILEFileName1]
[FILLcFillCharacter|FILLFILEFileName2]
[COLORSCHEMEnSchemeNumber|COLORColorPairList]]
【功能】
该命令用于生成窗口并设置窗口属性。
【参数和子句说明】
● WindowName1:指定要创建的窗口的名字。
● FROMnRow1,nColumn1TOnRow2,nColumn2:设定窗口在VFP主窗口中的位置及大小。nRow1,nColumn1为左上角的位置坐标;nRow2,nColumn2为右下角的位置坐标。
● ATnRow3,nColumn3SIZEnRow4,nColumn4:设定自定义窗口的位置和大小。其中,nRow3,nColumn3设定窗口左上角的位置坐标;nRow4,nColumn4设定窗口的行数和列数。
● IN[WINDOW]WindowName2:设定将用户自定义的窗口放置的父窗口。子窗口不得移出父窗口。● INSCREEN:指定将自定义的子窗口放置在VFP主窗口中。这是缺省选项。
● INDESKTOP:指定自定义的子窗口放置在VFP主窗口之外的Windows桌面上。
● NAMEObjectName:生成一个可访问窗口对象。
● FONTcFontName[,nFontSize[,nFontCharSet]]:设置窗口中要放置的文本的字形与字号。cFontName为字形名;nFontSize为字号,单位为磅,缺省时为9磅。用户可以使用nFontCharSet指定一个脚本语言。关于有效的脚本语言值,请参看GETFONT()函数。
● STYLEcFontStyle:设定窗口文本的修饰类型。其中,B为粗体,I为斜体,N为常规,Q为不透明,-为删除线,T为透明,U为下划线。
● TITLEcTitleText:设置窗口标题,该标题在窗口标题栏中居中。
● DOUBLE|PANEL|NONE|SYSTEM|cBorderString:设置窗口的边框式样。其缺省值是单线框。表9.2给出了它们各自的作用。DOUBLE或用户边框字符串cBorderString可生成一个宽边框的窗口。带有CLOSE、FLOAT、CROW、ZOOM、MINIMIZE子句,甚至在不包含SYSTEM窗口定义子句的情况下,也会在窗口设置适当的控制。● GROW|NOGROW、FLOAT|NOFLOAT、MDI|NOMDI:分别为是否允许使用键盘或鼠标改变窗口大小、移动窗口、生成一个用户自定义的MDI(Multi-DocumentInterface,多文档界面)自适应窗口。
MDI是一个规范,它允许有多文档窗口并定义它们的结构和行为。如果缺省MDI,则生成的窗口不是MDI自适应窗口。当MDI自适应窗口最大化时,有三大特点:一是窗口将采用VFP主窗口的尺寸。窗口控制将不出现,而弹出式菜单的图标将出现在VFP系统菜单栏中。 窗口的存储按钮也被放置在VFP系统菜单栏。二是窗口标题被放置在VFP标题栏中,并且用一个连接号和VFP标题分开。三是如果激活了别的MDI自适应窗口,它将自动最大化。● MINIMIZE|NOMINIMIZE、ZOOM|NOZOOM、CLOSE|NOCLOSE:是否有最小化、最大化、关闭按钮。
● ICONFILEFileName:设定窗口被最小化时要显示的图标。此时,在DEFINEWINDOW中必须包含MINIMIZE关键字。注意,只能指定一个图标(.ico)文件,而不能是位图(.bmp)文件。
● FILLFILEFileName2:设定窗口的背景。它可以是一个位图(.bmp)文件。
● COLORSCHEMEnSchemeNumber:设定用户自定义窗口的颜色的调色板编号。调色板的编号是1~24。在VFP中,第13、14、15号调色板专留给内部使用,用户不要使用它们。如果缺省,窗口的颜色将由1号调色板来控制。● COLORColorPairList:设定用户自定义窗口的颜色对。ColorPairList既可以颜色代码设置,又可以使用RGB()函数。
在RGB(n1,n2,n3,n4,n5,n6)函数中,n1、n2、n3用于设置前景的红、绿、蓝三色强度,n4,n5,n6用于设置背景的红、绿、蓝三色强度,它们各自的取值范围都是0~255,0为最弱,255为最强即高亮度。
9.窗口的启动
窗口定义完后,只有激活才能显示。
【命令格式】
ACTIVATEWINDOWWindowName1[,WindowName2...]
|ALL[IN[WINDOW]WindowName3|INSCREEN
[BOTTOM|TOP|SAME][NOSHOW]
【功能】
该命令用于显示并激活用户自定义窗口或VFP系统窗口。
【参数和子句说明】
● WindowName1[,WindowName2...]:要激活并显示的窗口名字的列表。
● ALL:指定所有的窗口都将被激活。最后激活的窗口是当前窗口。
● IN[WINDOW]WindowName3:指定父窗口的名字。
● INSCREEN:在VFP主窗口放置并激活一个窗口。● BOTTOM|TOP|SAME:设置被激活的窗口与先前激活的窗口的相关位置。缺省时,当窗口被激活时将出现在最顶层。BOTTOM将窗口放置在最底层;TOP将窗口放置在所有窗口之前;SAME激活窗口但不影响它的前后次序。
● NOSHOW:将激活并直接输出到窗口,但并不显示窗口。
10.窗口的释放
窗口使用结束后要及时释放,否则会占用大量的内存。
1)令格式1
【命令格式】RELEASEWINDOW[WindowNameList]
【功能】从内存中删除用户自定义窗口或VFP系统窗口。
【参数说明】WindowNameList:要删除的窗口名。如果缺省,则仅删除活动的用户自定义窗口。
2)命令格式2
【命令格式】CLEARWINDOWS
【功能】从内存中删除所有的用户自定义窗口。可以使用SAVEWINDOW命令把窗口定义保存到一个文件或备注型字段中,以便后面使用。CLEARWINDOWS命令在前面CLEAR命令中已讲解。
例9.8
一个窗口应用的综合示例。
*Lwindow.prg这是一个窗口应用的综合示例。
DEFINEWINDOWmywin1FROM2,2TO10,25;
TITLE"迎奥运"SYSTEM;
COLORRGB(255,255,0,255,0,0);
CLOSEMINIZOOMFLOATGROW;
FONT"隶书",24STYLE"UB"
DEFINEWINDOWmywin2AT2,30SIZE6,40;
TITLE"庆国庆"DOUBLE;
COLORRGB(255,,,,,)FONT"楷体",14FLOAT
GROW
@2,2SAY'福娃轻歌迎奥运,'&&在mywin1窗口第2行第三列起显示
@row()+1,2SAY'神州曼舞闹健身!'
ACTIVATEWINDOWmywin2
@2,2SAY"科学发展政策好,和谐社会民心安!"
RETURN
执行的结果如图9.3所示,读者可分析前两个窗口的异同点。图9.3窗口程序执行结果9.3程序的基本结构
与其它结构化程序设计语言相同,VFP9.0程序也有三种基本结构,即顺序结构、选择结构和循环结构。本节分别介绍这三种结构及特点。
程序设计时,应首先根据题意绘制出程序的流程图再在流程图的基础上编写出源程序。流程图分为传统的流程图、N-S图等。N-S图是由Nassi和Shneiderman提出的一种符合结构化程序设计原则的图形描述工具。本书的结构流程图按N-S图给出。9.3.1顺序结构
顺序结构是程序设计中最简单的基本结构,其特点是:在这种结构中,按照编程时各条命令书写的先后顺序依次逐条执行。前面所设计的几个程序全部是顺序结构程序,只不过当时并未提及这个概念而已。
顺序结构的流程图如图9.4所示。图9.4顺序结构N-S图9.3.2选择结构
选择结构是另一种常见的程序结构,其特点是:根据所给定的选择条件C的逻辑表达式为真(即分支条件成立)与否,而决定执行程序哪个分支中的语句序列,并且遵循“分支再多,仅选一路”的原则,执行完所选分支的语句序列后再执行该选择结构后面的程序。
1.IF…ELSE…ENDIF结构(双路分支选择结构)
1)语句结构与流程图
双路分支选择结构的语句结构如下,其流程图如图9.5
所示。
IFlExpression[THEN]
Statements1
[ELSE
Statements2]
ENDIF图9.5双路分支选择结构N-S图
2)语句功能
程序运行至IF语句时,首先判断条件C的逻辑表达式lExpression的值,当为.T.时,执行程序段Statements1,否则执行Statements2。无论执行Statements1还是Statements2,执行完后均执行ENDIF后的语句。
注意:如果无ELSE部分,则当逻辑表达式结果为.T.时,执行程序段Statements1,否则,继续执行后续程序。
例9.9
根据选择1或2查询“xsjbqkb.dbf”或“xsxkb.dbf”的全部信息。
*Lif.prg,选择结构语句练习
CLEAR
INPUT
"请输入查询选择(1或2):"TOcx
IFcx=1
SELECT*FROMxsjbqkb
ELSE
SELECT*FROMxsxkb
ENDIF
RETURN
2.DOCASE…ENDCASE结构(多路分支结构)
在VFP9.0程序设计中,当条件分支超过两个时,用IF语句虽然也能完成,但往往会造成IF语句的多层嵌套,使程序的清晰度降低。此时用DOCASE…ENDCASE语句效果要好得多。
1)语句结构与流程图
多路分支结构的语句结构如下,其流程图如图9.6所示。
DOCASE
CASElExpression1
Statements1
CASElExpression2
Statements2
…
CASElExpressionn
Statementsn
[OTHERWISE
Statementsn+1]
ENDCASE图9.6多路分支结构N-S图
2)语句功能
程序在执行DOCASE命令时,依次判断各表达式是否满足,若某个条件成立,就执行相应的程序段,执行完后转向执行ENDCASE后续的语句程序,仍然贯彻“分支再多,仅走一路”的原则。
例9.10
假设奖金jj与税率r之间存在着如下对应关系:
Jj≤2000
r=0%
2000<jj≤3000 超过2000的部分 r=5%
3000<jj≤5000 超过3000的部分 r=8%
5000<jj≤10000 超过5000的部分 r=10%
JJ>10000 超过10000的部分 r=15%设计一个程序“Lcase.prg”,要求用随机数发生器生成一个[600,30000]之间的奖金数,求出所应交纳的税金。将程序运行10次,将每次运行的结果都添加到事先已建好的表文件jiangjin(应发Y,税金Y,实发Y)中,最后浏览该表。
*Lcase.prg,用来计算奖金及税金
CLEAR
SETSAFETYOFF
CREATETABLEjiangjin(应发Y,税金Y,实发Y)
ZAP
jj=INT(RAND()*29401+600)
jds1=50
&&奖金为3000元时应缴纳的税金
jds2=50+160
&&奖金为5000元时应缴纳的税金
jds3=50+160+500&&奖金为10000元时应缴纳的税金
DOCASE
CASEjj<=2000
Sj=0
CASEjj<=3000
Sj=(jj-2000)*0.05
CASEjj<=5000
Sj=jds1+(jj-3000)*0.08
CASEjj<=10000
Sj=jds2+(jj-5000)*0.1
OTHERWISE
Sj=jds3+(jj-10000)*0.15
ENDCASE
INSERTINTOjiangjinVALUE(jj,sj,jj-sj)
RETURN
连续将该程序运行10次,然后浏览jiangjin.dbf,结果如图9.7所示。图9.7Lcase.prg运行结果9.3.3循环结构
在程序设计中,经常会遇到要求程序反复做某件相同的事情,这就需要使用循环结构来完成。它可以避免重复同一程序段代码的书写,简化程序,提高效率。在VFP9.0中,提供了FOR…ENDFOR|FOREACH…ENDFOR、DO
WHILE…ENDDO、SCAN…ENDSCAN三种循环结构。但实际上,它们都属于先判定型循环,即先判定循环条件是否成,然后再决定是否执行循环体内的语句序列,成立则执行,不成立则退出循环。从这一点出发,它们的N-S图应该是相似的。
1. FOR循环1(FOR…ENDFOR|NEXT)
对于事先可算出循环次数的循环,使用FOR…ENDFOR|NEXT循环将使程序显得较为简洁。
1)语句结构及流程图
FOR…ENDFOR|NEXT循环的语句结构如下,其流程图如图9.8所示。
FORVarName=nInitialValueTOnFinalValue[STEPnIncrement]
Statements
[EXIT]
[LOOP]
ENDFOR|NEXT图9.8FOR…ENDFOR|NEXT循环N-S图
2)功能
FOR…ENDFOR|NEXT循环用于执行一个确定了重复次数的命令集。其中,FOR称为FOR循环开始语句,ENDFOR|NEXT称为FOR循环结束语句,夹在它们中间的命令序列称为循环体。
3)参数和子句说明
● VarName:循环计数器变量名。
● nInitialValue、nFinalValue:循环计数器的初值、终值,它仅允许使用数值型数据。
● STEPnIncrement:设置计数器值递增或递减的步长值。nIncrement为负数表示计数器值递减,为正数表示计数器值递增,缺省时为1。● Statements:循环体内要执行的VFP命令序列。
● EXIT:循环断路语句。当循环碰见该命令时,立即将控制转移到循环体外执行ENDFOR紧下面的命令。它可以出现在循环体内的任何位置。
● LOOP:循环短路语句。当循环碰见该命令时,立即停止执行LOOP和ENDFOR之间的语句而将控制转移到FOR子句,使计数器自动更新。
● ENDFOR|NEXT:循环的结束语句。
FOR循环体内的VFP命令序列一直执行到碰见ENDFOR或NEXT语句或LOOP语句。然后,计数器变量的值按步长值递增或递减,再将更新后的计时器值与循环终值比较。当步长为正数时,如果计数器值小于或等于终值则继续执行循环体,否则退出循环转而去执行ENDFOR(或NEXT)后面的第1条命令。当步长为负数时,如果计数器值大于或等于终值则继续执行循环体,否则退出循环转而去执行ENDFOR(或NEXT)后面的第1条命令。注意:循环计数器的初值nInitialValue、终值nFinalValue、步长值nIncrement仅在开始时读入。如果在循环体内改变计数器的值,将会影响到要执行的循环次数。但在FOR循环体内改变循环终值却并不影响循环次数。循环次数的计算公式为:
例9.11
修改例9.10,用FOR循环实现10次数据插入,最后浏览jiangjin.dbf。
*Lfor.prg
SETSAFETYOFF
CLEARALL
CREATETABLEjiangjin1(应发Y,税金Y,实发Y)
ZAP
RAND(1)&&为RAND()函数提供了一个大于0的种子值
jds1=50
jds2=50+160
jds3=50+160+500
FORi=1TO10
jj=INT(RAND()*29401+600)
DOCASE
CASEjj<=2000
Sj=0
CASEjj<=3000
Sj=(jj-2000)*0.05
CASEjj<=5000
Sj=jds1+(jj-3000)*0.08
CASEjj<=10000
Sj=jds2+(jj-5000)*0.1
OTHERWISE
Sj=jds3+(jj-10000)*0.15
ENDCASE
INSERTINTOjiangjin1VALUE(jj,sj,jj-sj)
ENDFOR
BROWSE
USE
RETURN
运行结果如图9.9所示。和例9.10不同,本程序每次运行都将获得相同的结果,请读者自己分析其原因。图9.9Lfor.prg运行结果
2. FOR循环2(FOREACH…ENDFOR)
1)命令格式
FOREACHVar[ASType[OFClassLibrary]]INGroup
[FOXOBJECT]
Statements
[EXIT]
[LOOP]
ENDFOR|NEXT[Var]
2)功能
对于VFP数组中的每一个元素或连接,FOREACH…ENDFOR循环都执行一组命令。
3)参数
● Var:一个内存变量或数组元素,用来依次引用Group
中的每一个元素。
● Type:一个基础类、类名或类型库。
● ClassLibrary:用Type参数指定的基础类、类名或类型库。
● Group:一个VFP数组、一个OLE数组、一个VFP连接或一个OLE连接。
● FOXOBJECT:指定变量或数组元素,仅包含在本VFP项目中。
● Statements:指定对组内的每一个元素要执行的VFP命令集。
● EXIT、LOOP:同FOR循环1中的参数。
例9.12
首先用FOR…ENDFOR循环随机生成100个10~99之间的整型数,把它们存在一个数组arr中,然后用FOREACH循环予以显示。
*Lforeach.prg这是一个使用FOREACH循环的例子
CLEAR
DIMENSIONarr(100)
RAND(1)
FORi=1TO100
arr(i)=INT(RAND()*90)+10
ENDFOR
?SPACE(5)
i=0
FOREACHvarINarr&&注意此句的格式
??str(var,2)+"
"
i=i+1
IFi%20=0THEN
?SPACE(5)
ENDIF
ENDFOR
RETURN
运行结果如图9.10所示。图9.10Lforeach.prg执行结果
3. DOWHILE…ENDDO结构
已知循环次数,用FOR…NEXT语句当然简单,但对于仅知循环结束条件而循环次数不能事先确定的循环,就只能用DOWHILE…ENDDO循环来解决问题。
1)语句结构及流程图
DOWHILE循环的语句结构如下,其流程图如图9.11所示。
DOWHILElExpression
Statements
[EXIT]
[LOOP]
ENDDO图9.11DOWHILE循环N-S图
2)功能
DOWHILE循环用于执行条件循环体内的命令集。
3)结构说明
● 程序执行DOWHILE语句时,首先计算循环条件逻辑表达式lExpression的值,当值为真(.T.)时,执行循环体,否则结束循环,转向执行ENDDO紧后面的程序。
● 循环体中可插入循环短路语句LOOP及循环断路语句EXIT。
● 循环体中一般存在一条改变循环变量值的语句,使得在某一时刻循环条件不再成立(lExpression的值为.F.),以便结束循环。否则应存在一个EXIT语句,保证循环能正常结束。如若不然将形成死循环,必须避免发生这种错误。
例9.13
已知ex函数的泰勒级数表示为:
编写一个程序“Ldowhile.prg”求ex的近似值,要求当最后一项的值小于10-6时,程序结束。
*Ldowhile.prg求EXP(x)的近似值
CLEAR
esp=10^-6 &&收敛精度
e=1 &&对EXP(x)赋初值1
n=1 &&n代表级数的项,第1项n=1
input“请输入x的值:”tox
t=x/n &&级数第1项的值
DOWHILEt>esp
e=e+t
n=n+1
t=t*x/n&&级数第n项的值为第(n-1)项的值t再乘以x/n
ENDDO
?“EXP(”+ALLTRIM(STR(x))+“)=”+LTRIM(STR(e,10,5))
RETURN
运行本程序,如对x输入1,则会得到下面的结果:
EXP(1)=2.71828
请读者认真分析程序中的输出语句
?"EXP("+ALLTRIM(STR(x))+")="+LTRIM(STR(e,10,5))
的书写格式,相信会对深刻理解和掌握输出表达式有所启迪。
4.表扫描循环(SCAN…ENDSCAN)
VFP专门提供了用于数据表记录逐条处理的循环结构SCAN…ENDSCAN,使用它不但可以缩短程序代码,节省存储器空间,还可以有效地加快循环执行速度。
1)语句结构
SCAN…ENDSCAN循环的语句结构如下,其流程图如图9.12所示。
SCAN[Scope][FORlExpression1][WHILElExpression2]
[NOOPTIMIZE]
Statements
[LOOP]
[EXIT]
ENDSCAN图9.12SCAN循环N-S图
2)功能
SCAN…ENDSCAN循环在当前选定的表中移动记录指针,并且对满足给定条件的每一条记录逐条执行循环体内的命令序列。
3)参数和子句说明
● SCAN:表扫描循环结构的开始语句。
● ENDSCAN:SCAN循环过程结束语句。
● 其它各参数的含义均和前面各命令中的意义相同。当范围和条件子句全部缺省时,指全部记录。
例9.14
为表“xscjb.dbf”增加一个字段“名次I”,然后编写一个程序“Lscan.prg”,对总分从高到低进行排序,总分最高者为第1名,总分相同者名次并列。
*Lscan.prg是一个SCAN循环的例子,用于学生考试成绩排名次
CLEAR
CLOSEall
USExscjb
INDEXON-总分TOzfpx&&注意思考为何索引表达式写为“-总分”
GOTOP
zf=总分&&将逻辑排序后的首条记录——总分字段值最高者的总分值赋给变量zf
mc=1&&名次变量,首先为之赋1,以表示第一名
SCAN
IFzf>总分&&如果当前记录的总分字段值小于前一条记录总分字段值
mc=mc+1&&则名次应低一名,否则名次并列
zf=总分
ENDIF
REPLACE名次WITHmc
ENDSCAN
SELECTxsjbqkb.学号,姓名,总分,名次FROMxsjbqkb,xscjb;
ORDERBY名次ASCWHERExscjb.学号=xsjbqkb.学号
USE
RETURN
运行结果如图9.13所示。图9.13Lscan.prg运行结果9.3.4基本结构的嵌套
无论是选择结构还是循环结构,都可以进行嵌套从而组成更复杂的程序结构。所谓基本结构嵌套,是指在一个大的循环或选择结构内完整地包含了一个或多个循环或选择结构,而且它们可以混合嵌套。单纯的循环嵌套称为多重循环,单纯的选择嵌套称为多重选择。事实上,不管是选择结构还是循环结构,都自然而然地嵌套了顺序结构。
不管是哪一种嵌套,都应遵循下面的规则:
①嵌套只能包含而不得交叉。
②基本结构的开始与结束语句就近配对。③控制只能由内层转出而不能由外层转入。
实际上只要符合第(1)条,第(2)条就一定满足。
例9.15
已知在ASCII编码中,汉字在计算机中的机内码是以两个字节存储一个汉字的,机内码和外码中的区位码有着简单的对应关系:
高字节=区码+160
低字节=位码+160
在区位码中,汉字按一个94行94列的矩阵进行编码,行代表区码,列代表位码。区位码分为两个大区:
第一大区:1~15区,用来存放图形字符。其中,1~9区存放通用的标准图形字符;10~15区存放自定义图形字符。第二大区:16~94区,用来存放汉字。其中,16~55区共40个区存放一级汉字;56~87区存放二级汉字;88~94区为自定义汉字区。
编写一个程序“Lembed.prg”,输出16~87区的全部6763个汉字。要求:
(1)每个区必须另换一行输出。
(2)每行输出47个汉字,每个汉字间有一个空格。
(3)每个区的汉字输出完后,间隔0.5秒再输出下一个区的汉字。
*Lembed.prg打印汉字字库中的所有汉字
CLEAR
_Screen.FontSize=10st1="打印汉字字库"
st2="打印一级汉字字库"
st3="打印二级汉字字库"
?st1AT(SCOLS()-LEN(st1))/4Font"隶书",24Style"UB"&&注意该句格式
?st2AT(SCOLS()-LEN(st2))/2.5Font"楷体",16Style"UB"
FORqn=16TO87
IFqn=56THEN
?
?st3AT(SCOLS()-LEN(st3))/2.5Font"楷体",16Style"UB"ENDIF
IFqn=16ORqn=56THEN
?
?"位号"
FORi=1TO47
??STR(i,2)+""
ENDFOR
ENDIF
qm=CHR(qn+160) &&计算高字节的内码
?"第"+STR(qn,2)+"区"
wn=1DOWHILEwn<=94
wm=CHR(wn+160) &&计算低字节的内码
hz=qm+wm &&高字节前低字节后组成汉字
??hz+“” &&输出汉字
IFwn%47=0THEN &&每行输出47个汉字
IFwn/47=1
?'47+'
ENDIF
ENDIF
wn=wn+1
ENDDO
INKEY(0.5)
&&当一个区的94个汉字显示完毕后,
暂停0.5秒
NEXTqn
RETURN
运行后部分区(第16区~第20区)的汉字输出结果如图9.14所示。图9.14Lembed.prg运行的部分结果9.4过程
在设计程序中经常会遇到同一段功能相对独立的程序被多次使用的情况。在VFP中可以把重复使用的代码段或功能独立的代码段设计成能被其它程序调用的独立程序模块,这种程序模块称为过程。
过程存在着调用和被调用的逻辑关系。在程序设计中,把被其它过程调用的过程称为被调过程,相对地把调用其它过程的过程称为主调过程。
主调过程和被调过程的概念是相对的。对于一个过程,相对于上级主调过程它是被调过程,而相对于被它所调的下级过程它又是主调过程。VFP允许过程的嵌套调用,最深可以嵌套调用128层。在程序中,存在着一个特殊的过程,它只调用其它过程而不被其它任何过程所调用,这个特殊的过程称为主程序。主程序在整个程序中处于主导地位,是整个程序的入口程序,程序的运行将从它开始。前面曾经提到,如果一个程序文件中写有多个程序,则仅执行第一个程序,其原因就是这些程序是独立的,没有相互调用的关系。
根据过程的存储位置,把过程分为四种不同的类型:独立程序文件过程、程序文件过程、过程文件过程和存储过程。独立程序文件过程是一个个独立的 .prg文件,创建的方法同于程序文件,用DO命令进行调用。它的缺点是当程序运行时,需要反复访问磁盘,其运行速度较慢,在FoxBase中使用比较普遍,在VFP中已很少使用,无须再作介绍。9.4.1定义过程
不管是程序文件过程、过程文件过程还是存储过程,都要先定义过程然后才能调用过程。过程定义的命令格式有以下两种。
【命令格式1】
PROCEDURE|FUNCTIONProcedureName
[LPARAMETERSparameter1[,parameter2],...]
Statements
[RETURN[eExpression]]
[ENDPROC|ENDFUNC]
【命令格式2】
PROCEDURE|FUNCTIONProcedureName([parameter1[ASpara1type]
[,parameter2[ASpara2type]],...])
[ASreturntype]
Statements
[RETURN[eExpression]]
[ENDPROC|ENDFUNC]
【功能】
过程定义命令用于定义一个过程。其中用FUNCTION定义的过程又称为用户自定义函数。
【参数和子句说明】
● PROCEDURE|FUNCTIONProcedureName:指定自定义过程的开头处和过程的名字。
● LPARAMETERSparameter1[,parameter2],...:指定从主调过程传递数据到定义过程的局部变量或数组。也可用PARAMETERS代替LPARAMETERS,此时会从主调过程传递数据到定义过程的私有变量或数组。这些变量参数称为形参。最大允许的形参个数是26个。● ([parameter1[ASpara1type][,parameter2[ASpara2type]],...]):指定从主调用过程传递数据到函数过程的局部变量或数组。可以使用AS子句说明变量的数据类型。
● ASreturntype:定义返回值的数据类型。
● Statements:过程体内VFP命令序列。
● RETURN[eExpression]:返回程序运行控制到主调过程或其它过程。eExpression可以指定一个返回值。注意,RETURN可以出现在过程体的任何地方,以便将控制返回到主调过程或别的过程以及返回一个值。如果过程中没有RETURN命令,VFP当过程退出时会自动隐含执行了一个RETURN。如果RETURN命令不包含返回值或者隐含执行RETURN,VFP都将返回逻辑真.T.。
● ENDPROC|ENDFUNC:过程结构的结束语句。该关键字是可选择的,如无此关键字,则当过程碰到其它的PROCEDURE|FUNCTION命令或到达本过程结尾时,也会自动认为本过程定义结束。9.4.2程序文件过程
程序文件过程是指过程与主程序在同一文件中,位于主程序之后,每个过程都以PROCEDURE|FUNCTION语句开头,以ENDPTROC|ENDFUNC结束的过程。
程序文件过程的特点是,当程序文件打开时,这些过程就全部自动打开,当程序运行结束时,它们都将自动关闭,因而运行速度高。但过多的此类过程会使程序文件显得过于冗长。不过对于初学者,由于所编写的程序并不太长,因此使用程序文件过程将显得非常方便。
例9.16
编写带有一个定义求阶乘过程的程序文件,用来计算1~20内各整数的阶乘。
*Lprgproc.prg本程序是程序文件过程实例,用于求1~20内各整数的阶乘
CLEAR
FORi=1TO20
s=factorial(i)&&过程调用语句
?STR(i,2)+“!=”+LTRIM(STR(s,20))
ENDFOR
RETURN
*主程序结束,下面是求阶乘的过程factorrial
FUNCTIONfactorial(mASI)ASN
f=1
FORj=1tom
f=f*j
ENDFOR
RETURNf
ENDFUNC
运行结果如图9.15所示。注意,主程序中的facto
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业赞助合同范本
- 会展活动合同范本及使用指南
- FOB贸易合同履行地点合同
- 二手车买卖广告合同书
- 临时工劳动合同医疗护理
- 乐器行业劳动合同模板
- 人力资源公司租赁协议草稿
- 3D打印个人机械租赁协议书
- 人力资源专员简化版劳动合同
- 付款协议书推动社会事业发展
- 离心压缩机设计-曼透平
- 北京市通州区2024届高三上学期期中质量检测数学试题 含解析
- Unit2 School things Lesson 3 (教学设计)-2024-2025学年人教精通版(2024)英语三年级上册
- 堤溪沱江大桥特别重大坍塌事故工程伦理案例分析
- 住建领域有限空间作业安全管理知识课件
- 2024年新大象版六年级上册科学全册知识点(背诵版)
- 变频器原理及应用
- 从文学到电影智慧树知到期末考试答案章节答案2024年山东大学
- 人教九年级历史上册《探寻新航路》教学课件
- 应急分队人员招聘方案范文
- 幼儿园班级幼儿图书目录清单(大中小班)
评论
0/150
提交评论