590 likes | 802 Views
7.1. 7.2. 7.3. 7.4. 7.5. 7.6. 程序文件的建立与运行. 顺序结构程序设计. 分支结构程序设计. 循环结构程序设计. 模块结构程序设计. 数组及其应用. 第 7 章 结构化程序设计. 7.1 程序文件的建立与运行. 7.1.1 程序文件的建立 1 .用菜单方式建立程序文件 执行“文件 / 新建 / 程序 / 新建文件”菜单命令。. 2 .用命令方式建立程序文件. 格式: MODIFY COMMAND < 程序文件名 > 功能:新建或修改指定的程序文件。. 7.1.2 程序文件的运行. 1 .用菜单方式运行程序文件
E N D
7.1 7.2 7.3 7.4 7.5 7.6 程序文件的建立与运行 顺序结构程序设计 分支结构程序设计 循环结构程序设计 模块结构程序设计 数组及其应用 第7章 结构化程序设计
7.1 程序文件的建立与运行 • 7.1.1 程序文件的建立 • 1.用菜单方式建立程序文件 • 执行“文件/新建/程序/新建文件”菜单命令。
2.用命令方式建立程序文件 • 格式:MODIFY COMMAND <程序文件名> • 功能:新建或修改指定的程序文件。
7.1.2 程序文件的运行 • 1.用菜单方式运行程序文件 • 执行“程序/运行”菜单命令。 • 2.用命令方式运行程序文件 • 格式:DO <程序文件名> • 功能:将指定的程序文件调入内存并运行。
7.1.3 程序中的辅助命令 • 1.程序注释命令 • 格式1:NOTE <注释内容> • 格式2:* <注释内容> • 格式3:[<命令>] && <注释内容>
2.结束程序运行命令 • 格式1:RETURN • 功能:返回到上级程序模块。 • 格式2:RETURN MASTER • 功能:返回到最上级主程序。
格式3:CANCEL • 功能:停止程序执行,关闭所有文件,返回系统交互状态。 • 格式4:QUIT • 功能:停止所有程序执行,关闭所有文件,退回到宿主操作系统。
3.运行环境设置命令 • CLEAR 清屏幕 • CLEAR ALL 关闭所有文件、释放所有内存变量 • SET DEFAULT TO 设置文件访问时默认的驱动器 • SET PATH TO 设置文件访问时默认的路径 • SET TALK ON/off 设置所有命令执行的结果显示与否
7.1.4 程序中的交互输入命令 • 1.字符串输入命令 • 格式:ACCEPT [<提示信息>] TO <内存变量> • 功能:暂停程序的运行,等待用户键入一串字符赋给指定的内存变量。
2.表达式输入命令 • 格式:INPUT [<提示信息>] TO <内存变量> • 功能:暂停程序运行,接受用户键入的表达式并将其值赋给指定的内存变量。
3.等待或单字符输入命令 • 格式:WAIT [<提示信息>] [TO <内存变量>] • 功能:暂停程序运行,若包含 [TO <内存变量>]短语时,将用户所键入的一个字符赋给指定的内存变量;否则待用户按任一键后继续程序的执行。
4.定位输出命令 • 格式:@ <行,列> SAY <表达式> • 功能:在屏幕上指定的行、列位置输出指定表达式的值。
7.2 顺序结构程序设计 • 7.2.1 基本程序结构 • 1.顺序程序结构 • 2.分支程序结构 • 3.循环程序结构
7.2.2 顺序结构程序设计 • 严格按照程序中各命令的先后排列顺序自上而下逐条执行。 • 【例7-6】在职工档案表中查看指定职工的有关情况。 • USE zgda • ACCEPT "请输入被查询者姓名:" TO xm • LOCATE FOR 姓名=xm • CLEAR • ? "姓名:"+姓名 • ? "性别:"+性别 • ? "职称:"+职称 • ? "出生日期:"+DTOC(出生日期) • USE • RETURN
7.3 分支结构程序设计 • 7.3.1 简单分支结构 • 格式: • IF <条件> • <语句序列> • ENDIF • 执行过程:当<条件>成立时,逐条执行IF与ENDIF之间的<语句序列>,然后执行ENDIF后的语句;当<条件>不成立时,不执行<语句序列>而直接执行ENDIF后的语句。
【例7-8】某种商品一次购买 100件以上时,可享受8%的优惠。试编程根据输入的单价和数量计算应付金额。 • CLEAR • INPUT "数量:" TO sl • INPUT "单价:" TO dj • je=dj*sl • IF sl>=100 • je=je*0.92 • ENDIF • ? "应付金额:"+STR(je,8,2) • RETURN
7.3.2 选择分支结构 • 格式: • IF <条件> • <语句序列1> • ELSE • <语句序列2> • ENDIF • 执行过程:若<条件>成立仅执行<语句序列1>,而后执行ENDIF后的语句;否则仅执行<语句序列2>,而后转去执行ENDIF后的语句。
【例7-10】出租车不超过5公里时一律收费10元,超过时则超过部分每公里加收1.6元。试编程根据里程数计算并显示出应付车费。【例7-10】出租车不超过5公里时一律收费10元,超过时则超过部分每公里加收1.6元。试编程根据里程数计算并显示出应付车费。 • CLEAR • INPUT "里程:" TO lc • IF lc<=5 • ? "车费为:十元" • ELSE • cf=10+(lc-5)*1.6 • ? "车费为:"+STR(cf, 6, 2) • ENDIF • RETURN
7.3.3 分支嵌套结构 • 在分支结构的<语句序列>中,允许包括另一个合法的分支结构语句。 • 【例7-12】设硅谷公司员工的工资计算方法如下: • 每工时按68元发放; • 工作时数超过120小时者,超过部分加发百分之十五; • 工作时数不到80小时者,扣发500元。
试编程按输入的员工号和该号员工的工时数,计算并输出其应发工资。试编程按输入的员工号和该号员工的工时数,计算并输出其应发工资。 • CLEAR • ACCEPT "员工号:" TO ygh • INPUT "工时:" TO gs • IF gs>120 • gz=gs*68+(gs-120)*68*0.15 • ELSE • IF gs<80 • gz=gs*68-500 • ELSE • gz=gs*68 • ENDIF • ENDIF • ? &&输出一个空行 • ? ygh+"号员工应发工资:"+STR(gz, 8, 2) • RETURN
7.3.4 多路分支结构 • 用来解决在多种不同情况下的程序选择执行问题。 • 格式: • DO CASE • CASE <条件1> • <语句序列1> • CASE <条件2> • <语句序列2> • …… • CASE <条件n> • <语句序列n> • [OTHERWISE • <语句序列n+1>] • ENDCASE
【例7-13】编程计算银行存款整存整取应得的利息。【例7-13】编程计算银行存款整存整取应得的利息。 • CLEAR • INPUT "本金(元):" TO bj • INPUT "存期(年):" TO cq • DO CASE • CASE cq>=5 • rate =4.5 &&年利率为4.5% • CASE cq>=3 • rate =3.6 &&年利率为3.6% • CASE cq>=2 • rate =3.1 &&年利率为3.1% • CASE cq>=1 • rate =2.7 &&年利率为2.7% • CASE cq>=0.5 • rate =2.21 &&年利率为2.21% • OTHERWISE • rate =1.23 &&年利率为1.23% • ENDCASE • lixi=bj*cq*rate /100 • ? &&输出一个空行 • ? " 应得利息:"+STR(lixi, 8, 2) • RETURN
7.4 循环结构程序设计 • 7.4.1 当型循环结构 • 格式: • DO WHILE <条件> • <语句序列> • ENDDO • 执行过程:若<条件>成立,执行DO WHILE和ENDDO之间的<语句序列>;若<条件>不成立则不执行<语句序列>,直接转去执行ENDDO后的语句。每执行一遍后再对<条件>判断一次,一旦<条件>不成立就结束循环转去执行ENDDO后面的语句。
【例7-14】求1+2+3+...+100的累计值。 • CLEAR • STORE 0 TO n, s • DO WHILE n<100 • n=n+1 • s=s+n • ENDDO • ? "累计值为:"+STR(s, 6) • RETURN
7.4.2 步长型循环结构 • 格式: • FOR <循环变量>=<初值> TO <终值> [STEP <步长值>] • <语句序列> • ENDFOR|NEXT • 执行过程:首先将初值赋给指定的循环变量,然后判断其值是否超过终值,不超过即执行循环体,超过则不执行循环体。遇到ENDFOR(或NEXT)语句时自动给循环变量增加一个步长值,再判断循环变量的当前值是否超过终值,不超过再次执行循环体,超过则结束循环转去执行ENDFOR(或NEXT)后的语句。
【例7-18】用步长型循环结构编程求1+2+3+...+100的累计值。【例7-18】用步长型循环结构编程求1+2+3+...+100的累计值。 • CLEAR • s=0 • FOR n=1 TO 100 • s=s+n • ENDFOR • ? "S="+STR(S,6) • RETURN
7.4.3 扫描型循环结构 • 格式: • SCAN [<范围>] [FOR <条件1>] [WHILE <条件2>] • <语句序列> • ENDSCAN • 执行过程:对当前数据表中指定范围内符合条件的记录,逐个进行<语句序列>所规定的操作;缺省范围和条件短语时,则对所有记录逐个进行<语句序列>所规定的操作。
【例7-20】 用扫描型循环结构编程,输出职工档案数据表中基本工资在800元以下的职工姓名及其基本工资数,并输出这些职工的人数。 • CLEAR ALL • USE zgda • CLEAR • STORE 0 TO n • SCAN FOR基本工资<800 • ? 姓名, 基本工资 • n=n+1 • ENDSCAN • ? "基本工资在800元以下的职工共有:"+STR(n, 3)+ "人" • CLOSE DATABASE • RETURN
7.4.4 循环嵌套结构 • 在一个循环结构的循环体内包含有其它循环结构,便形成了循环的嵌套。 • 【例7-21】输出下图所示的乘法九九表。
CLEAR ALL • CLEAR • a=1 • DO WHILE a<=9 • b=1 • ? &&用于换行输出 • DO WHILE b<=a • ?? SPACE(2)+STR(a, 1)+"×"+ STR(b, 1)+"="+ STR(a*b, 2) • b=b+1 • ENDDO • a=a+1 • ENDDO • RETURN
7.5 模块结构程序设计 • 一个应用程序通常可由多个相关的功能模块(Module)组成,这里所说的模块是指具有某种功能的一段相对独立的程序。 • 采用模块结构程序设计的好处在于:整个程序结构清晰,易于分别编写与调试,便于维护与调用,并利于程序功能的进一步扩充与完善。
7.5.1 程序模块的建立与运行 • 【例7-26】采用主程序调用子程序的方法,对于任意输入的整数x、y、z的值,计算 w=x!+y!+z! 的值。 • **主程序main1.prg • CLEAR ALL • INPUT "x= " TO x • INPUT "y= " TO y • INPUT "z= " TO z • n=x &&将x的值赋给n,为计算x的阶乘做准备 • DO subp1 &&调用subp1子程序计算x的阶乘 • a=t &&把子程序计算的结果存入变量a • n=y • DO subp1 • b=t • n=z
DO subp1 • w=a+b+t • ? "w=x!+y!+z!= ", w • RETURN • **子程序subp1.prg • PUBLIC t &&宣告t为全局变量,详见7.5.4节 • t=1 • FOR i=1 TO n • t=t*i • NEXT • RETURN
7.5.2 应用程序的模块化设计 • 目前,各种基于数据库的事务管理应用程序的开发大都采用“自顶向下”的模块化程序设计方法,大大方便了整个程序的开发与调试,并极大地增加了程序的灵活性和可维护性。
例如,下图是一个简化的职工档案管理系统的程序模块结构,每个程序模块都对应一个磁盘上的.PRG文件。例如,下图是一个简化的职工档案管理系统的程序模块结构,每个程序模块都对应一个磁盘上的.PRG文件。
7.5.3 带参模块的建立与调用 • 1.主模块的带参调用命令 • 格式:DO <程序模块名> WITH <参数表> • 功能:调用指定名称的程序模块,并将<参数表>中各个参数的值分别传递给所调用模块中的对应参数。
2.子模块的接受参数命令 • 格式:PARAMETERS <参数表> • 功能:接受主模块带参调用命令传递过来的各个参数。 • 【例7-28】利用主模块带参调用子模块的方法计算圆柱的体积。 • ***计算圆柱体积的主模块abc.prg • CLEAR • INPUT " 圆柱半径:" TO a • INPUT " 圆柱高:" TO b • STORE 0 TO c • DO rhv WITH a, b, c • ? " 圆柱体积为:", c • RETURN • ***计算圆柱体积的子模块rhv.prg • PARAMETERS r, h, v • s=3.14159*r*r • v=s*h • RETURN
7.5.4 内存变量作用域 • 内存变量的作用域是指该变量在各程序模块内发挥作用的有效范围。按作用域的不同,可将内存变量划分为全局变量、私有变量和局部变量。
1.全局变量 • 全局变量又称公共变量,是指在任何命令语句以及任何嵌套层次的程序模块中均起作用的内存变量。定义全局变量的命令格式如下。 • 格式:PUBLIC <内存变量表> • 功能:将<内存变量表>中指定的内存变量定义为全局变量。
2.私有变量 • 在某个模块中创建的内存变量,只能在该模块及其下属模块中使用,而不与其它模块中的同名变量相关。定义私有变量的命令格式如下。 • 格式1:PRIVATE <内存变量表> • 格式2:PRIVATE ALL [LIKE/EXCEPT <统配符>] • 功能:指定某些变量只限于本模块及其下属模块使用,并使其上级模块或其他模块中的同名变量隐蔽起来直至本级模块运行结束为止。
3.局部变量 • 在当前模块中定义并只有在当前模块中有效的内存变量,一旦当前模块执行完毕,此种变量便自动释放。定义局部变量的命令格式如下。 • 格式:LOCAL <内存变量表> • 功能:将<内存变量表>所列的各个内存变量定义为局部变量。
7.5.5 过程与过程文件 • 1.过程的概念 • 过程可以看作是以下形式的一个程序段: • PROCEDURE <过程名> • [PARAMETERS <参数表>] • <语句序列> • ENDPROC • 此种过程通常被包含在调用它的应用程序文件中,作为该程序的一个组成部分。一个应用程序文件可以包含多个这样的过程,习惯上把它们放在应用程序的最后面。
2.过程文件 • 将某个应用程序系统所包含的多个子模块分别作为不同的过程保存在同一个程序文件中,这样的程序文件被称为过程文件。过程文件的结构形式如下。 • PROCEDURE <过程名1> • <语句序列1> • ENDPROC • PROCEDURE <过程名2> • <语句序列2> • ENDPROC • …… • …… • PROCEDURE <过程名n> • <语句序列n> • ENDPROC
7.5.6 用户自定义函数 • 1.自定义函数的概念 • 自定义函数实际上是由用户自行编写的一个具有特定功能的程序段,其程序组成结构如下。 • [FUNCTION <函数名>] • [PARAMETERS <参数表>] • <语句序列> • RETURN <表达式> • ENDFUNC
2.自定义函数举例 • 【例7-33】 编写一个计算阶乘的自定义函数包含在调用它的程序中,并调用此函数来计算组合数 的值。 • **包含自定义函数的计算组合数程序zhs.prg • CLEAR • INPUT "请输入m的值:" TO m • INPUT "请输入n的值:" TO n • **调用自定义函数jiech计算组合数: • y=jiech(m)/(jiech(n)*jiech(m-n)) • ? "组合数的计算结果是:" +str(y, 8) • RETURN
**计算阶乘的自定义函数jiech: • FUNCTION jiech • PARAMETERS k • t=1 • FOR i=1 TO k • t=t*i • ENDFOR • RETURN t • ENDFUNC
7.6 数组及其应用 • 数组是一批相同名称不同下标的内存变量,数组中的每个元素用数组名及下标(表明在该数组中的排列顺序)表示,下标的个数决定了数组的维数。Visual FoxPro支持一维数组和二维数组。
7.6.1 数组的定义与使用 • 1.数组的定义 • 格式1:DIMENSION <数组名>(<expN1>[,<expN2>])[,<数组名>(<expN1>[,<expN2>]),... • 格式1:DECLARE <数组名>(<expN1>[,<expN2>])[,<数组名>(<expN1>[,<expN2>]),... • 功能:建立指定的若干个一维或二维数组。