第 9章 结构化程序设计简介学习要点
1,程序的建立与执行
2,程序的分支结构与循环结构
3,子程序,自定义函数与过程
4,变量的作用域第 9章 结构化程序设计简介
9.1 程序文件
9.2 程序的控制结构
9.3 多模块程序习题与参考答案第 9章 结构化程序设计简介
Visual FoxPro程序设计包括结构化程序设计和面向对象程序设计 。 前者是传统的程序设计方法,若使用这种方法来设计 Visual
FoxPro程序的用户界面,不仅难度大,而且十分麻烦 。 后者面向对象,用户界面可利用系统提供的辅助工具来设计,应用程序也可自动生成,但仍需用户编写一些过程代码 。 就此而言,
结构化程序设计仍是面向对象程序设计的基础 。
9.1 程序文件
Visual FoxPro将命令文件 ( 有顺序要求的命令序列 ) 称为程序文件或程序,本节主要介绍程序的建立,执行以及专用于程序文件中的若干命令 。
9.1.1 程序文件的建立与执行
1.程序文件的建立与修改命令格式:
MODIFY COMMAND<文件名 >
功能:打开文本编辑窗口,用来建立或修改程序文件 。
说明,⑴ 程序文件由 Visual FoxPro命令组成 。 <文件名 >由用户指定,缺省的扩展名为,prg。
9.1.1 程序文件的建立与执行
⑵ 关闭编辑窗口的方法有:按 Ctrl+W键;按 Esc
键;在编辑窗口双击控制菜单按钮或单击关闭按钮 。
按 Ctrl+W键可将文件立即存盘并且退出编辑 。
此外还可用文件菜单的,保存,,,另存为,,
,还原,选项来关闭编辑窗口 。
⑶ 文本编辑窗口也可以编辑由 ASCII字符组成的非,prg文件 。,prg文件是程序,可以运行,一般的文本文件则可读而不可运行 。
9.1.1 程序文件的建立与执行
2.程序的运行命令格式:
DO <文件名 >
功能:执行由 <文件名 >表示的程序 。
说明:
⑴ 所谓执行程序,就是依次执行程序中的命令 。 例如 DO js,其效果和命令窗口中依次键入并执行命令一致 。
9.1.1 程序文件的建立与执行
⑵ DO命令默认运行,prg程序,如果要运行的是,prg程序,DO命令中的 <文件名 >只需取文件主名 。 要运行其它程序,<文件名 >中须包括扩展名,例如执行查询程序的命令为 DO
mczz.qpr。
⑶ Visual FoxPro程序可以通过编译获得目标程序,目标程序是紧凑的非文本文件,运行速度快,并可起到对源程序加密的作用 。
9.1.1 程序文件的建立与执行
3.程序书写规则
⑴ 命令分行程序中每条命令都以回车键结尾,一行只能写一条命令 。 若命令需分行书写,应在一行终了时键入续行符,;,,然后按回车键 。
⑵ 命令注释程序中可插入注释,以提高程序的可读性 。
注释行以符号,*” 开头,它是一条非执行命令,
仅在程序中显示 。 命令后也可添加注释,这种注释以符号,&&,开头 。
9.1.1 程序文件的建立与执行
4.求解的基本逻辑与程序通用性
⑴ 求解的基本逻辑
Visual FoxPro程序多数用于数据处理,解决问题的基本逻辑是:输入数据 → 处理数据 → 输出数据 。
⑵ 程序的通用性程序的通用性指程序对多种场合的适应性,通用性好的程序的应用范围较广 。 只能计算半径为 8的圆面积程序谈不上通用性,若将程序设计成能对任意半径算出圆面积,则通用性就大力增强 。 要做到这一点并不困难,只要将程序中原始数据定值改为由用户按需输入即可 。
9.1.2 程序文件中的专用命令在程序文件中,常常要用到一些在交互方式中不需要甚至不能执行的专用命令 。 本小节仅介绍其中若干较常使用的命令 。
1.程序结尾的专用命令程序的末尾可放一条 RETURN命令,它能使程序执行结束,并返回到调用它的上级程序继续执行,若无上级程序则返回到命令窗口 。 RETURN命令一般允许缺省 。
另一条命令为 CANCEL,它能使程序运行终止,
清除程序的私有变量,并返回到命令窗口 。
9.1.2 程序文件中的专用命令
2.输入输出专用命令传统的专用数据输入命令有 INPUT,ACCEPT等多种,数据输出命令有 TEXT… ENDTEXT命令,现均已很少使用 。 这里仅介绍定位输入输出命令 。
命令基本格式:
@< 行,列 >[SAY< 表达式 >][GET< 变量名
>][DEFAULT<表达式 2>]
功能:在屏幕的指定行列输出 SAY子句的表达式值,并可修改 GET子句的变量值 。
9.1.2 程序文件中的专用命令说明:
⑴ <行,列 >表示数据在窗口中显示的位置,行自顶向下编号,列自左向右编号,编号均从 0开始 。
行与列都是数值表达式,还可使用十进制小数精确定位 。
⑵ SAY子句用来输出数据,GET子句用来输入及编辑数据 。 若缺省 SAY子句,GET变量值从指定位置开始显示;含有 SAY子句时先显示其表达式值,然后空开一格显示 GET变量的值 。 SAY和 GET子句数据显示时的背景色不一样,前者以标准型显示,后者以增强型显示 。
9.1.2 程序文件中的专用命令
⑶ GET 子 句 中 的 变 量 必 须 具 有 初 值,或用
DEFAULT子句的 <表达式 >指定初值 。 初值一旦指定 。
该变量的类型在编辑期间就不能改变,字符型变量的宽度与数值型变量的小数位数也无法再变 。
⑷ GET子句的变量必须用 READ命令来激活,也就是说,在若干带有 GET子句的定位输入输出命令后,
必须遇到 READ命令才能编辑 GET变量 。 当光标移出这些 GET变量组成的区域时 READ命令执行结束 。
9.1.2 程序文件中的专用命令
3.WAIT命令命令格式:
WAIT[< 信 息 文 本 >][TO< 内 存 变 量
>][WINDOW[AT<行 >,<列 >]]
功能:暂停程序的运行,直到用户输入一个字符 。
也可只用于输出一条提示信息 。
说明:
⑴ WAIT命令使 Visual FoxPro程序暂停运行,等用户按任一键 ( 或回车 ) 后,程序继续运行 。
9.1.2 程序文件中的专用命令
⑵ <内存变量 >用来保存键入的字符,如果不选 TO子句,则输入的数据不予保存 。
⑶ 如果缺省 <信息文本 >,则执行命令后屏幕显示,按任意键继续 …,,提示按任一键将继续运行 。
⑷ WINDOW子句可使主屏幕上出现一个
WAIT提示窗口,位置由 AT选项的 <行 >,<列
>来指定 。 若缺省 AT选项,<信息文本 >将显示在主屏幕右上角 。
9.2 程序的控制结构与其它高级语言程序相似,Visual FoxPro程序也有 3种基本控制结构,即:顺序结构,分支结构和循环结构 。 顺序结构按命令的书写顺序依次执行;分支结构能根据指定条件的当前值在两条或多条程序路径中选择一条执行;而循环结构则由指定条件的当前值来控制循环体中的语句 ( 或命令 ) 序列是否要重复执行 。 下面分别介绍它们在 Visual FoxPro中的描述方式 。
9.2.1 顺序结构顺序结构的程序运行时按照语句排列的先后顺序,一条接一条地依次执行,它是程序中最基本的结构 。 例 9-1就是一个顺序结构的例子 。
9.2.2 分支结构计算机具有判别功能 。 判别是靠程序实现的,
Visual FoxPro能用条件语句或多分支语句构成分支结构,并根据条件成立与否来决定程序执行的流向 。
条件语句是一个具有两个分支的程序结构,又可分成带 ELSE与不带 ELSE两种格式 。
1.简单的条件语句语句格式:
IF <逻辑表达式 >
<语句序列 >
ENDIF
9.2.2 分支结构
2.带 ELSE的条件语句
IF <逻辑表达式 >
<语句序列 1>
ELSE
<语句序列 2>
ENDIF
功能:根据 <逻辑表达式 >的逻辑值,选择执行两个语句序列中的一个 。 若 <逻辑表达式 >值为真,先执行 <语句序列
1>,然后再执行 ENDIF后面的语句;若其值为假,先执行 <
语句序列 2>,然后再执行 ENDIF后面的语句 。
9.2.2 分支结构
3.多分支语句语句格式:
DO CASE
CASE <逻辑表达式 1>
<语句序列 1>
CASE <逻辑表达式 2>
<语句序列 2>

CASE <逻辑表达式 n>
<语句序列 n>
[OTHERWISE
<语句序列 n+1>]
ENDCASE
9.2.3 循环语句在处理实际问题的过程中,有时需要重复执行相同的操作,即对一段程序进行循环操作,这种被重复的语句序列称为循环体 。
Visual FoxPro具有一般程序设计语言都有的
WHILE条件循环语句和 FOR步长循环语句,此外还有专用于对表进行处理的 SCAN扫描循环语句 。 循环执行的次数一般由循环条件决定,但在循环体中可插入跳出语句 EXIT来结束循环,也可以用 LOOP语句来继续循环 。
9.2.3 循环语句
1.条件循环语句格式:
DO WHILE <逻辑表达式 >
<语句序列 >
ENDDO
说明,语句格式中的 <逻辑表达式 >称为循环条件,<语句序列 >称为循环体 。 语句执行时,若循环条件为假就结束循环,
然后执行 ENDDO后面的语句;为真则执行循环体,一旦遇到
ENDDO就自动返回到 DO WHILE重新判断循环条件是否成立,
以决定是否继续循环 。
9.2.3 循环语句
[例 9-4] 编程显示 teacher.dbf中所有男教师的姓名 。
* e9-4.prg
USE teacher
DO WHILE NOT EOF()
IF 性别 =“男,
? 姓名
ENDIF
SKIP
ENDDO
USE
9.2.3 循环语句
2.步长循环语句格式:
FOR <内存变量 >=<数值表达式 1> TO <数值表达式 2> [STEP<数值表达式 3>]
<语句序列 >
ENDFOR│ NEXT
说明,语句格式中的 <内存变量 >称为循环变量,<数值表达式 1>,<
数值表达式 2>,<数值表达式 3>分别称为初值,终值,步长 。 语句执行时,
通过比较循环变量值与终值来决定是否执行 <语句序列 >。 步长为正数时,
若循环变量值不大于终值就执行循环体;步长为负数时,若循环变量值不小于终值就执行循环体 。 执行一旦遇到 ENDFOR或 NEXT,循环变量值加上步长,然后返回到 FOR重新与终值比较 。
9.2.3 循环语句
[例 9-5] 编写计算 S=1+2+3+… +100的程序 。
* e9-5.prg
s=0 && s为累加器,初值为 0
FOR i=1 TO 100 && i为计数器,初值为 1
s=s+i &&累加
NEXT
“s=”,s
9.2.3 循环语句
3.扫描循环语句格式:
SCAN [< 范围 >] [FOR< 逻 辑 表 达 式 1>]
[WHILE<逻辑表达式 2>]
<语句序列 >
ENDSCAN
说明,该语句针对当前表进行循环,<范围 >子句表示记录范围,缺省值为 ALL。 语句执行时在 <范围 >
中依次寻找满足 FOR条件或 WHILE条件的记录,并对找到的记录执行 <语句序列 >。
9.2.3 循环语句
[例 9-6] 根据例 9-4的要求,用扫描循环语句编程 。
* e9-6.prg
USE teacher
SCAN FOR 性别 =“男,
? 姓名
ENDSCAN
USE
9.2.3 循环语句
4.循环辅助语句在各种循环语句的循环体中可以插入
LOOP和 EXIT语句,前者能使执行转向循环语句头部继续循环;后者则用来立即退出循环,
转去执行 ENDDO,ENDFOR或 ENDSCAN后面的语句 。
[例 9-7] 编程计算 S=1+2+3+… +100,并求 1~ 100之间奇数之和 。
9.2.3 循环语句
* e9-7.prg
STORE 0 TO i,s,t
DO WHILE i<100
i=i+1
s=s+i &&累加 i值
IF INT(i/2)=i/2 && i为偶数时条件值为,T.
LOOP
ENDIF
t=t+i &&累加奇数
ENDDO
“1+2+3+… +100=”,s
“1~ 100奇数和为:,,t
9.2.3 循环语句
5.多重循环若一个循环语句的循环体内又包含其它循环,就构成了多重循环,也称为循环嵌套 。 较为复杂的问题往往要用多重循环来处理 。
[例 9-8] 在 teacher.dbf中找出所有未婚教师的姓名,性别与部门,并要求在各输出行下显示一行虚线 。
9.2.3 循环语句
* e9-8.prg
CLEAR
USE teacher
SCAN FOR NOT 婚否 &&外循环姓名 +SPACE(3)+性别 +SPACE(3)+部门
? &&起换行作用
FOR i=1 TO 30 &&内循环
“-” &&内循环的循环体
ENDFOR &&内循环结束语句
ENDSCAN &&外循环结束语句
USE
程序执行结果如下:
赵海东 男 23
王 强 男 22
李 东 男 23
9.3 多模块程序应用程序一般都是多模块程序,可包含多个程序模块 。 模块是可以命名的一个程序段,
可指主程序,子程序和自定义函数 。 本节介绍模块的构成及调用方法,多模块程序中变量的作用域,以及结构化程序设计的概念 。
9.3.1 子程序
1.调用与返回对于两个具有调用关系的程序文件,常称调用程序为主程序,被调用程序为子程序 。
已知执行 DO命令能运行 VISUAL FOXPRO程序,
其实 DO命令也可用来执行子程序模块 。 主程序执行时遇到 DO命令,执行就转向子程序,称为调用子程序 。
子程序执行到 RETURN语句 ( 或缺省该语句 ),就会返回到主程序中转出处的下一语句继续执行程序,称为从子程序返回,或简称返主 。
9.3.1 子程序
2.带参数子程序的调用与返回
DO命令允许带一个 WITH子句,用来进行参数传递 。
命令格式:
DO 〈 程序名 1〉 [WITH〈 参数表 〉 ] IN 〈 程序名 2〉
说明:
① 〈 参数表 〉 中的参数可以是表达式,但若为内存变量必须具有初值 。
② 当 〈 程序名 1〉 是 IN子句 〈 程序名 2〉 中的一个过程时,
DO命令调用该过程 。
9.3.1 子程序调用子程序时参数表中的参数要传递给子程序,
子程序中也必须设置相应的参数接收语句 。 VISUAL
FOXPRO的 PARAMETERS命令就具有接收参数和回送参数值的作用 。
命令格式:
PARAMETERS 〈 参数表 〉
功能:指定内存变量以接收 DO命令发送的参数值,
返主时把内存变量值回送给调用程序中相应的内存变量 。
9.3.1 子程序
[例 9-9] 设计一个计算圆面积的子程序,并要求在主程序中带参数调用它 。
主程序:
* e9-9.prg
ymj=0
@5,10 SAY,请输入半径:,GET bj DEFAULT 0
READ
DO js WITH bj,ymj &&调用子程序
“ymj=”,ymj &&显示圆面积
RETURN
子程序:
* js.PRG
PARAMETERS r,s
s=PI()*r*r && Visual FoxPro的 PI()函数返回 π值
RETURN &&返主
9.3.1 子程序
3.子程序嵌套主程序与子程序的概念是相对的,子程序还可调用它自己的子程序,即子程序可以嵌套调用 。 Visual FoxPro的返回命令包含了因嵌套而引出的多种返回方式 。
命令格式:
RETURN [TO MASTER|TO 〈 程序文件名 〉 ]
说明,命令格式中的 [TO MASTER]选项,使返主时直接返回到最外层主程序;可选项 TO 〈 程序文件名 〉 强制返回到指定的程序文件 。
顺便指出,任何时候要退出 Visual FoxPro,只要执行命令 QUIT。
9.3.2 自定义函数
1.自定义函数的建立自定义函数的定义格式如下:
[FUNCTION〈 函数名 〉 ]
[PARAMETERS〈 参数表 〉 ]
〈 语句序列 〉
[RETURN〈 表达式 〉 ]
9.3.2 自定义函数说明:
① 若使用 FUNCTION语句来指出函数名,表示该函数包含在调用程序中 。 若缺省该语句,表示此函数是一个独立文件,
函数名将在建立文件时确定,其扩展名默认为,prg,并可使用命令 MODIFY COMMAND〈 函数名 〉 来建立或编辑该自定义函数 。 还需注意,自定义函数的函数名不能和 Visual FoxPro
系统函数同名,也不能和内存变量同名 。
② 〈 语句序列 〉 组成为函数体,用于进行各种处理;简单的函数其函数体也可为空 。
③ RETURN语句用于返回函数值,其中的 〈 表达式 〉 值就是函数值 。 若缺省该语句,则返回的函数值为,T.。
④ 自定义函数与系统函数调用方法相同,其形式为:
函数名 [〈 参数表 〉 ]
9.3.2 自定义函数
[例 9-10] 设计一个自定义函数,用来求一元一次方程
AX+B=0的根 。
自定义的求根函数 root.prg如下:
* root.prg
PARAMETERS a,b
RETURN IIF(a=0,“无解,,-b/a)
上述 ROOT函数中的 IIF函数是标准函数,其功能类似于 IF
语句 。 若 A=0,它的值是字符串,无解,;否则返回一 B/A的值 。
现在使用下述命令调用 ROOT函数来解决方程 2X+4=0:
“X:”,ROOT(2,4) &&显示结果 X=-2
9.3.2 自定义函数
2.数组参数的传递在调用自定义函数或过程时,也可将数组作为参数来传递数据 。 此时发送参数与接收参数都使用数组名,发送参数数组名前要加@来标记,而作为接收参数的数组不需事先定义 。
9.3.3 过程过程的格式如下:
PROCEDURE〈 过程名 〉
[PARAMETERS〈 参数表 〉 ]
〈 命令序列 〉
[RETURN]
说明,从格式可知,过程是以 PROCEDURE开头,
并标出 〈 过程名 〉 的程序或程序段序列是过程体 。 与程序调用一样,过程也用 DO命令调用 。
9.3.3 过程
[例 9-11] 调用过程文件中的过程示例 。
主程序:
* e9-11.prg
ymj=0
@5,10 SAY“请输入半径:,GET bj DEFAULT 0
READ
DO js WITH bj,ymj IN js1
“ymj=”,ymj
过程文件:
* js1.prg
PROCEDURE js
PARAMETERS r,s
s=PI()*r*r
在过程中也可调用其它程序模块 。
9.3.4 变量的作用域
1.公共变量在任何模块中都可使用的变量称为公共变量,公共变量可用下述命令来建立 。
命令格式:
PUBLIC〈 内存变量表 〉
2.私有变量
Visual FoxPro默认程序中定义的变量是私有变量,私有变量仅在定义它的模块及其下层模块中有效,
而在定义它的模块运行结束时自动清除 。
9.3.4 变量的作用域命令格式:
PRIVATE [〈 内存变量表 〉 ][ALL[LIKE|EXCEPT
〈 通配符 〉 ]]
3.本地变量本地变量只能在建立它的模块中使用,而且不能在高层或底层模块使用,该模块运行结束时本地变量就自动释放 。
命令格式:
LOCAL〈 内存变量表 〉
9.3.5 结构化程序设计的概念典型的数据库应用系统通常含有输入,修改,查询,统计,打印报表等功能模块,它是一个多模块系统,通常用菜单来管理这些模块 。 数据库应用系统通常包含众多模块 。 在 VISUAL FOXPRO流行前,开发应用系统通常遵循结构化程序设计的原则与方法 。
1.自顶向下,逐步求精
2.模块化
3.层次化习题
1.填空
⑴ 程序运行的命令是 __________。
⑵ 程 序可以通过编 译获得目标程 序,目标程序 是
__________。
⑶ 计算机解题须遵循求解的 __________,还须适当注意 __________。
⑷ GET子句的变量必须用 __________命令来激活 。
⑸ Visual FoxPro 程 序 有 三 种 基 本 控 制 结 构,即
__________,__________和 __________。
习题
⑹ Visual FoxPro能用 __________或 __________构成分支结构,实现判别功能 。
⑺ Visual FoxPro具有三种循环语句,即 __________、
__________和 __________。
⑻ 对于两个具有调用关系的程序文件,常称调用程序为
__________,被调用程序为 __________。
⑼ DO 命 令 允 许 带 一 个 WITH 子句,用 来 进 行
__________。
⑽ 若 以 变 量 的 作 用 域 来 分 类,内 存 变 量 可 分 为
__________,__________和 __________三类 。
参考答案
1,( 1) DO〈 文件名 〉
( 2) 紧凑的非文本文件
( 3) 基本逻辑,程序的通用性
( 4) READ
( 5) 顺序结构,分支结构,循环结构
( 6) 条件语句,多分支语句
( 7) 条件循环语句,步长循环语句,扫描循环语句
( 8) 主程序,子程序 ( 9) 参数传递
( 10) 公共变量,私有变量,本地变量