第四章 程序设计初步

52
第第第 第第第第第第 第 第第第第 第第第 第第第第第第第 第第第 第第第第第 第第第 第第第第第第

description

第四章 程序设计初步. 第一节 程序文件 第二节 程序的控制结构 第三节 多模块程序 第四节 窗口设计样例. 4.1 程序文件. VFP 程序设计包括结构化程序设计和面向对象程序设 计,但结构化程序设计仍是面向对象程序设计的基础。 4.1.1 程序文件的建立与执行 一、程序文件的建立与修改 MODIFY COMMAND < 文件名 >. 文件名由用户指定,扩展名为 .PRG. 程序文件由 VFP 命令组成. 4.1.1 程序文件的建立与执行. 文件的退出与保存 Ctrl+W: 文件存盘推出 ESC : 若程序文件修改过,将询问“放弃修改吗?” - PowerPoint PPT Presentation

Transcript of 第四章 程序设计初步

第四章 程序设计初步

第一节 程序文件第二节 程序的控制结构第三节 多模块程序第四节 窗口设计样例

4.1 程序文件

VFP 程序设计包括结构化程序设计和面向对象程序设计,但结构化程序设计仍是面向对象程序设计的基础。

4.1.1 程序文件的建立与执行一、程序文件的建立与修改

MODIFY COMMAND < 文件名 >

文件名由用户指定,扩展名为 .PRG

程序文件由 VFP 命令组成

4.1.1 程序文件的建立与执行

文件的退出与保存 Ctrl+W: 文件存盘推出 ESC :若程序文件修改过,将询问“放弃修改吗?” 双击左上角控制菜单:将询问“将所做的更改保存到 *.prg 吗?” 单双击右上角关闭按钮:将询问“将所做的更改保存到 *.prg 吗?” “ 文件”菜单:“保存”、“另存为”或“还原”命令二、程序的执行 DO < 文件名 >

例如: DO MCZZ.QPR && 运行查询程序

默认扩展名为 .PRG ,若为其它类型必须指明扩展名

举例

例 4-3 :设计程序创建数据库 SBSJ{SB,BMDM,DX,ZZ}

creat data sbsjadd tabl sbadd tabl zzadd tabl dxadd tabl bmdmclose data

4.1.1 程序文件的建立与执行

三、程序的书写规则 1 、命令分行 一行只写一条命令,结尾回车 一行写不完,则加续行号“;”回车 2 、命令注释 注释行以“ *” 号开头 一条命令后可加“ &&” 引出注释 例如: * 本程序修改指定记录 SET DATE USA && 日期格式为 MM-DD-YY

4.1.1 程序文件的建立与执行

4.1.2 程序文件中的专用命令

一、程序结尾的专用命令RETURN :使程序结束,返回到上级或命令窗口,准许缺省CANCEL :正常终止,清除程序私有变量,返回到命令窗口QUIT :退出 VFP 系统,自动删去临时文件,返回 WINDO

WS

二、定位输入输出专用命令

@< 行,列 > [SAY < 表达式 1>] [GET < 变量名 >]

[DEFAULT < 表达式 2 >]

数据在窗口显示位置 输出数据 输入及编辑数据

指定变量初值

[P128 例 4-1]

CLEAR && 清屏幕 USE sb jlh=1 && GET 变量必须赋初值 @2,10 SAY " 请输入记录号 :" GET jlh READ GO jlh @4,10 SAY " 请修改第 "+STR(jlh,1)+" 个设备的数据 " * 输出提示字符串 @6,10 SAY " 价格 " GET 价格 * 价格是字段变量 , 已经有初值 @8,10 SAY " 部门 " GET 部门 READ USE

三、 WAIT 命令

暂停程序的运行 , 直到用户输入一个字符 , 也可用于输出一条提示信息

WAIT [< 信息文本 >] [TO < 内存变量 >] [WINDOW [AT < 行 >,< 列 >]]

[NOWAIT] [CLEAR] [NOCLEAR] [TIMEOUT < 数值表达式 >]

保存键入的字符 ,省略 TO 子句不保

省略则显示“按任意键继续… .

不等待用户输入

关闭提示窗口

不关闭提示窗口 , 直到下一个 WAIT 命令自动关闭

WINDOW 子句使屏幕出现一个 WAIT 提示窗口 , 内容由 < 信息文本 > 确定 , 位置有 AT 子

句指定 . 省略 AT 子句则出现在屏幕右上角

TIMEOUT 子句设定等待时间(以秒为单位)

4.2 程序的控制结构

顺序结构:按命令的书写顺序依次执行 分支结构:根据指定条件的当前值在两条基本结构 或多条路径中选择一条执行 循环结构:由指定条件的当前值来控制循 环体中的语句(或命令)序列 是否要重复执行。4.2.1 分支结构 VFP 可用条件语句或分支语句实现分支结构

一、简单的条件语句

IF <逻辑表达式 >

<语句序列 >

ENDIF

[P130 例 4-3] USE sb

LOCATE FOR NOT 主要设备 IF FOUND() && 若查到, FOUND函数返回 .T.

DISPLAY 名称 , 价格 REPLACE 价格 WITH 价格 *(1-0.1)

DISPLAY 名称 , 价格 ENDIF

USE

RETURN

二、带 ELSE 的条件语句

IF <逻辑表达式 >

<语句序列 1>

ELSE

<语句序列 2>

ENDIF

三、宏替换函数

函数格式: &<字符型内存变量 >[.<字符表达式 >] 功能:替换出字符型内存变量的值 [P131 例 4-4] m=5 x="m" ? x && 显示m ? &x && 显示 5 若宏替换函数后还有非空的 <字符表达式 >,则需要

在此 <字符表达式 > 前加“ .” 。

[P131 例 4-5]

clear

@5,10 SAY " 请输入表名: " GET bm DEFAULT SPACE(10)

READ

bm=ALLTRIM(bm) && 删去两端的空格 IF FILE("&bm..dbf") && &bm 后用一个 .来连接 .dbf

use &bm

browse

ELSE

WAIT "该文件不存在,按任意键退出 " WINDOW

ENDIF

三、多分支语句

DO CASE CASE <逻辑表达式 1> <语句序列 1> CASE <逻辑表达式 2> <语句序列 2> …………… CASE <逻辑表达式 n> <语句序列 n> [OTHERWISE <语句序列 n+1>] ENDCASE

[P132 例 4-6]

clear yue=month(date()) &&获取月份 do case case inlist(yue,3,4,5) jj="春 " case inlist(yue,6,7,8) jj="夏 " case inlist(yue,9,10,11) jj="秋 " case inlist(yue,12,1,2) jj="冬 " endcase wait jj window at 8,30 &&当前季节显示在 WAIT 窗口

4.2.2 循环结构

一、条件循环 DO WHILE <逻辑表达式 > <语句序列 > ENDDO [P133 例 4-7] use sb do while not eof() if 价格 >10000 ? 名称 endif skip enddo use

循环条件

循环体

[P134 例 4-8]store 0 to k1,k2,k3use sbdo while not eof() do case case 价格 >90000 k1=k1+1 case 价格 <10000 k3=k3+1 otherwise k2=k2+1 endcase skipenddo ?"9万元以上设备个数: "+str(k1)?"1~9万元设备个数 : "+str(k2)?"1万元以下设备个数: "+str(k3)use

二、步长循环 FOR < 内存变量 >=< 数值表达式 1> TO < 数值表达式 2 > [STEP < 数值表达式 3 >]

<语句序列 >

ENDFOR|NEXT

[P135 例 4-9]

s=0

for i=1 to 100

s=s+i

next

?"s=",s

初值 终值 步长,默认为 1

三、扫描循环

SCAN [< 范围 >] [FOR <逻辑表达式 1>] [WHILE <逻辑表达式 2 >] <语句序列 > ENDSCAN 在 < 范围 >内依此寻找满足 FOR条件或 WHILE 条件的记

录 ,并对找到的记录执行 < 语句序列 > [P135 例 4-10] use sb scan for 价格 >10000 ? 名称 endscan use

四、循环辅助语句

LOOP :使执行转向循环语句的头部继续循环 DO WHILE <逻辑表达式 > …… LOOP …… ENDDO EXIT:立即退出循环,转去执行循环外的语句 DO WHILE <逻辑表达式 > …… EXIT …… ENDDO

[P136 例 4-11]

store 0 to i,s,tdo while i<100 i=i+1 s=s+i if int(i/2)=i/2 loop endif t=t+ienddo?"1+2+3+...+100=",s?"1~100 奇数和为 ",t

五、多重循环

循环体内包含其它循环→循环嵌套 clear use sb @5,10 say "请输入价格: " get jg default 0 read scan &&外循环 if 价格 <jg ?编号 +space(3)+名称 +space(3)+str(价格 ,9,2) ? &&换行 for i=1 to 30 && 内循环 ??"-" endfor endif endscan use

4.3 多模块程序

模块是可以命名的一个程序段,可指主程序、子程序和自定义函数

4.3.1 子程序 一、调用与返回 两个具有调用关系的程序文件,称调用程序为主程序,被调用程序为子程序

主程序遇到 DO 命令,转向子程序执行,称为调用程子程序。

子程序执行到 RETURN语句(或缺省该语句),返回到主程序中的 DO 命令的下一个语句执行,称为返回主程序

二、带参数子程序的调用和返回

DO <程序名 1> [WITH <参数表 >] [IN <程序名 2 >]

相对应的在子程序中,用 PARAMETERS来接收和回送参数。 PARAMETERS <参数表 >

可以是表达方式,内存变量必须赋初值

当 < 程序名程序名 1>1>是是 <<程序名程序名2>2>中的一个过程时,必须中的一个过程时,必须

指明指明

11 、该语句应为子程序的第一条命令, 、该语句应为子程序的第一条命令, 22 、、 PAPARAMETERSRAMETERS 参数应与参数应与 WITHWITH 参数表一一对应参数表一一对应

三、子程序嵌套

  子程序还可以调用其它子程序(嵌套),因嵌套引出多两种返回方式

   RETURN [TO MASTER|TO < 程序名 >]        任何时候要推出VFP,只要执行QUIT命令

返回最外层主程序 强制返回指定程序

省略,返回外层调用程序

4.3.2 自定义函数

 一、自定义函数的建立 

[FUNCTION <函数名 >]   [PATAMETERS <参数表 >]   <语句序列 > [RETURN <表达式 >]

使用它表示该函数包含在调用程序中,缺省则函数为一个独立文件

函数体

用于返回表达式的函数值,省略则返回 .T.

自定义函数不能和系统函数、内存变量同名,使用方法与系统函数相同

[P139 例 4-14]

解法二 * 例 4-14解法二 clear

@5,10 say " 一次项系数: " get a default 1

@7,10 say " 常 数 项: " get b default 0

read

?"x:",root(a,b)

function root

parameters u,v

return iif(u=0,"无解 ",-v/u)

IIF 系统函数,若 u=0 ,值为“无解”;否

则为 -v/u

二、数组参数的传递

发送参数数组前加 @ ,接收参数数组不需定义。 * 例 4-14 数组传送 ,P140 clear dimension fs(2) fs(1)=1 fs(2)=0 @5,10 say "一次项系数: " get fs(1) @7,10 say "常 数 项: " get fs(2) read ?"x:",root(@fs) &&树组前加@可传递数组 function root parameters js && js(1)=fs(1),js(2)=fs(2) return iif(js(1)=0," 无解 ",-js(2)/js(1))

4.3.3  过程

VFP 准许一个 .PRG文件中设置多个程序模块,除主程

序以外每个模块为一个过程 过程的格式如下 : PROCEDURE <过程名 > [PARAMETERS < 参数表 >] <命令序列 > [RETURN] 过程部分往往位于程序文件的最后 .

[P141 例 4-15]

set decimals to 2 && 设置小数点后保留两位 ymj=0 @5,10 say "请输入半径: " get bj default 0 read do js with bj,ymj ?"ymj=",ymj return procedure js parameters r,s s=pi()*r*r return

过程文件

主程序文件 ymj=0 @5,10 say "请输入半径: " get bj default 0 read do js with bj,ymj in js1 &&调用过程文件 js1 中的过程 js ?"ymj=",ymj return 过程文件 procedure js parameters r,s s=pi()*r*r return

4.3.4 变量的作用域

以变量的作用域来分 , 内存变量分为 : 公共变量、私有变量和本地变量

一、公共变量 公共变量是在一个程序中的任何模块都可以使用的变量,

建立命令格式 PUBLIC < 公共变量表 > 需定义为公共变量的变量:下层模块建立的变量要供上层使用,某模块建立的变量要供并列模块使用

VFP 命令窗口定义的变量均为公共变量,公共变量必须用命令( RELEASE 或 CLEAR)来清除

建立的同时,赋初值为 .F.

二、私有变量

私有变量仅在定义它的模块及其下层模块中使用,定义它的模块运行结束自动清除 私有变量准许与上层模块的变量同名 ,同名时屏蔽上层模块的变量 . 本模块运行结束再恢复上层模块变量 私有变量类型声明格式如下: PRIVATE [<内存变量表 >] [ALL [LIKE|EXCEPT <通配符 >]]注意 : (1)PARAMETERS声明的参变量也是私有变量 (2)PUBLIC 命令除声明明变量类型外还赋初值,称为建立; PRIVATE 只是声明而已,不进行赋值。

[P142 例 4-17]

parameters sj private mj mj=3.14*sj*sj ?" 程序执行时的变量清单 " list memo like ?j return 在命令窗口输入 : mj=0 bj=3 do e4_17 with bj 观察输出情况,解释

三、本地变量

本地变量只能在建立它的模块使用,该模块运行结束自动清除

命令格式: LOCAL <内存变量表 >

注意: LOCAL不可缩写 例 E4_bl

<内存变量表 >指定的变量为本地变量 ,并赋初值 .F.

4.3.5  程序调试方法

一 .调试的概念 程序调试的目的:检查并纠正程序中的错误,以保证程序正确、可靠地运行。 程序调试的步骤:检查程序是否存在错误 确定出错位置 纠正错误 1 、程序中常见的错误 ( 1 )语法错误,例:数据类型不匹配等 ( 2 )超出系统准许范围错误,例:文件太大等 ( 3)逻辑错误,例:计算逻辑错误等

2 、查错技术

查错技术一:静态检查,通过阅读程序,找出错误查错技术二:动态检查,通过执行程序考察程序是否有错( 1 )设置断点 在断点处查看中间结果,考察程序是否有错( 2 )单步执行 一次执行一个命令,相当于断点设在每条指令之后( 3)跟踪 在程序执行过程中,跟踪某些信息的变化,以确定程序序是否有错( 4 )设置错误陷阱 通过错误陷阱捕捉可能发生的错误。可通过 ON ERROR语

句设置陷阱

4.3.6 结构化程序设计

[P147 例 4-19]结构化设计的三种方法( 1 )自顶向下,逐步求精 从整体出发,逐层分解,使复杂的问题简单化

( 2 )模块化 将系统分解为若干功能相关而又相对独立的模块

( 3 )层次化 系统按层次结构布局,即以树型结构来组织系统的全部

模块

4.4 窗口设计样例

4.4.1 浏览窗口的定制 VFP 准许用户按照自己的需要配置浏览窗口的功能。一、 BROWSE 命令 BROWSE [FIELDS <字段表 >] [FONT <字符表达式 1>[,<数值表达式 1>]] [STYLE <字符表达式 2>]

见下页解释

字体:宋,楷 字体大小: 16 ,20

字体形状: B , I,U

<字段表 >

<字段名 >[:R][:<数值表达式 >][:V=<表达式 1>[:F][:E=<字符表达式 1>]]

[:P=<字符表达式 2>][:B=<表达式 2>,<表达式 3>[:F]] [:H=<字符表达式 3>][:W=<逻辑表达式 1>]

只读 栏宽

设置字段级有效性检验表达式 1 为检验条件,光标离开字段时检

格式代码列表,见 P111-112

检验出错提示信息不管字段是否修改均检验,省略,则只修改时才检验

下界 范围检查 上界

不管字段是否修改均检验,省略,则只修改时才检验

栏目名,默认字段名为栏目名

为真,准许进入该字段,否则越过

BROWSE 命令

[FOR <逻辑表达式 > [REST] [FREEZE <字段 >] [LAST] [LOCK <数值表达式 2>] [LPARTITION] [NAME <对象名 >]

记录指针移到首记录

记录指针保持原位置

光标只能在指定字段移动 保存浏览

窗口外观

保持某些字段保持显示

光标在左分区第一字段 ,

准许使用表格控件的对象

LOCK使浏览窗口一分为二 , 右分区按常规显示左分区显示表的前N个字段

BROWSE 命令

[NOAPPEND] [NODELETE] [NOEDIT|NOMODIFY] [NOLGRID] [NORGRID]

[NOLINK] [NOMENU] [NOREFRESH] [NORMAL] [NOWAIT]

不准许追加记录

不准许做删除标记

不准许编辑 , 但准许删除和添加

删除左分区网格线

删除右分区网格线

取消左、右分区显示按记录联动

使系统菜单不出现表菜单

禁止刷新浏览窗口

用默认配置打开浏览窗口

打开窗口继续运行程序

BROWSE 命令

[SAVE] [TIMEOUT <数值表达式 3>] [TITLE <字符表达式 3>][VALID[:F] <逻辑表达式 2> [ERROR <字符表达式 4>]]

保持浏览窗口为活动 ,操作其它窗口后即返回

等待输入时间 ,超过浏览窗口自动关闭

设置浏览窗口标题

设置光标离开校验 : 记录修改后光标离开后计算 <逻辑表达式 2> , 其值为真准许光标离

开 <字符表达式 4>为出错提示信息

BROWSE 命令

[WHEN <逻辑表达式 3>] [WIDTH <数值表达式 4>][WINDOW <窗口名 1>] [IN [WINDOW] <窗口名 2>|IN SCREEN]

为真准许修改记录 ,否则为只读

浏览窗口每个字段宽度 , 但操作时可变

指定一个用户定义的窗口 ,浏览窗口采用其特性 窗口名 2 指定浏览窗口的

父窗口 ,SCREEN表示父窗口为 VFP主窗口

[P151 例 4-20]

clear allselect 0use bmdmindex on 代码 tag dmselect 0use sbbrowse title " 设 备 价 格 表 " nodelete lock 1 nomenu; fields 编号 :R, 名称 :R:H=" 设备名称 ", 价格 :B=2001,500000:F:W=bm

m()function bmmselect bmdmseek sb. 部门wait 名称 window nowait &&WAIT 提示窗口显示部门名select sb

二、定义功能键

功能键可以是单键、组合键或鼠标按键,当用户使用定义的功能键将执行预定的功能

ON KEY [LABEL <键标号 >] [<命令 >] 注释:( 1 )当程序执行( READ 、 BROWSE )等命令,进入某种暂

停状态,用户即可使用功能键执行规定的命令。( 2 ) PUSH KEY 保存 POP KEY 恢复 PUSK KEY CLEAR:清除

定义的功能键,见 P357附录二

一般为 DO命令

[P153 例 4-22]

CLEAR ALLPUSH KEY CLEAR && 清除以前设置的功能键ON KEY LABEL rightmouse DO tis && 设置鼠标右键为功能键

select 0use bmdmselect 0use sbbrowse title " 设备表 " && 编辑 sb.DBFpush key clear

[P153 例 4-22]续

procedure tis

if varread()=" 部门 " &&当前字段为部门时返回 .T.

select bmdm

browse title " 部门表 " nomodify && 显示部门代码和名称

=inkey(0,"MH") && 等待击键 select sb

endif

4.4.1 窗口命令与函数

一、窗口命令 P154 表 4-1 列出了 VFP 部分常用窗口命令的名称和简要功能。1 、窗口激活命令 ACTIVATE WINDOW [<窗口名 1>[,<窗口名 2>…]] <窗口名 1>[,<窗口名 2>…] 要激活的窗口的名称 下面两条指令先后激活计算器和文本编辑窗口 ACTIVATE WINDOW calculator &&激活计算器 MODI COMM wj.txt

2 、窗口关闭命令

将窗口从屏幕清除,并且删除它在内存中的定义( 1 ) RELEASE WINDOWS [<窗口名表 >] 关闭在 <窗口名表 >中指定的用户定义窗口和 VFP 系

统窗口,缺省关闭活动的用户定义窗口( 2 ) CLEAR WINDOWS 关闭所有用户定义的窗口( 3) CLEAR ALL 关闭所有用户定义的窗口 ,并返回到系统初始状态

[P155 例 4-23]

clear

keyboard '{Ctrl+F4}' * 向键盘缓冲区装入关闭命令@5,5 say 'x='GET x DEFAULT SPACE(2)

read

activate window command

* 程序执行结束激活命令窗口

二、消息对话框函数

MESSAGEBOX函数能产生带按钮的信息对话框

MSEEAGEBOX (< 字符表达式 1>[,< 数值表达式 >[,< 字符表达式 2>]])

指定在对话框中显示的信息文本

指定在对话框标题栏显示的信息文本,否则显示 Microsoft Visual FoxPro

根据 P156 表 4-2 内容设定对话框中的按钮、图标和默认按钮,缺省该参数取 0

函数返回值为用户按下的按钮对应的数值,见 P156表 4-3

具体应用见P156 例 4-2

4