690 likes | 924 Views
第 5 章 程序设计基础. Visual FoxPro 不仅是一个功能很强的 数据库管理系统,而且还内含一个使用方 便、功能强大的应用程序开发工具。本章 主要介绍程序设计的基础知识,包括结构 化程序设计的基本方法和面向对象程序设 计中的基本概念。. 5.1 程序设计概述. 程序设计 ( Programming )是利用系统所提供的设计 工具,按照程序设计语言的规范描述解决问题的算法并进行 程序编写的过程。 这个过程应包含分析、设计、编码、测试和排错等不同 阶段。 程序设计两种方法:
E N D
Visual FoxPro不仅是一个功能很强的 数据库管理系统,而且还内含一个使用方 便、功能强大的应用程序开发工具。本章 主要介绍程序设计的基础知识,包括结构 化程序设计的基本方法和面向对象程序设 计中的基本概念。
5.1 程序设计概述 程序设计(Programming)是利用系统所提供的设计 工具,按照程序设计语言的规范描述解决问题的算法并进行 程序编写的过程。 这个过程应包含分析、设计、编码、测试和排错等不同 阶段。 程序设计两种方法: 结构化程序设计(Structured Programming,SP) 面向对象的程序设计(Object-oriented Programming,OOP) 从程序设计的方法来看:Visual FoxPro既支持结构化程序 设计,也支持面向对象程序设计,并提供了许多相关的可视 化开发工具。
结构化程序设计(Structured Programming,SP) 提出时间:20世纪60年代 主要思想(程序遵循的设计原则): • 自顶向下 • 逐步求精 • 模块化 • 限制使用转移语句 程序流程三种基本结构:顺序、分支、循环。 本质:功能设计 方法:自顶向下,功能分解 开发过程:从“做什么”到“如何做”
面向对象的程序设计(Object-oriented Programming,OOP) 提出时间:20世纪60年代,但发展缓慢,20世纪90年代,面向 对象的程序设计方法风靡了整个软件行业,出现了大量支持面向 对象程序设计的语言和开发工具。 基本思想:世界由各种对象,任何事物都是对象,是某个对象类 的实例,复杂的对象可有较简单的对象组合而成。 基石:对象和类 • 对象:数据及其作用于这些数据之上的操作结合在一起所构成的独立实体的总称。 • 类:一组具有相同数据结构和相同操作的对象的描述。 基本机制:方法和消息 • 消息:要求某个对象执行类中某个操作的规格说明 • 方法:对象所能执行的操作,它是类中定义的函数,描述对象执行某个操作的算法,每个类都定义了一组方法。 三个重要特性:封装性、继承性和多态性。
面向对象的程序设计(Object-oriented Programming,OOP) 三个重要特性:封装性、继承性和多态性。 • 封装性:是指对象是数据和处理该数据的方法所构成的整体,外界只能看到其外部特性(消息模式、处理能力等),其内部特性(私有数据、处理方法等)对外部不可见。 • 继承性:反映的是类与类之间不同的抽象级别,根据继承与被继承的关系,类可分为基类(父类)和衍生类(子类)。子类可以从父类那里获得所有的属性和方法,并且可以对这些获得的属性和方法加以改造,使之具有自己的特点。 • 多态性:在形式上表现为一个方法根据传递给它的参数的不同,可以调用不同的方法体,实现不同的操作。 解决过程:采用自底向上方法,先将问题空间划分为一系列对象的集 合,再对对象集合进行分类抽象,一些具有相同属性行为的对象被抽 象为一个类,类还抽象分为子类。其间采用继承来建立这些类之间之 间的联系,形成结构层次。同时对于每个具体类的内部结构,又可采 用自顶向下逐步细化的方法由粗到细精化之。
5.2 结构化程序设计 结构化程序设计是指根据不同的情况和条件,控制 程序去执行相应操作的语句序列。Visual FoxPro中有 一类特殊的命令,在这些命令的控制下,可以使其他的 一组命令或函数重复执行多次,或者根据一定的条件控 制程序执行某一组命令而不执行另一组命令。 程序结构主要分为:顺序结构、分支结构、循环结 构,以及过程/函数调用,这些结构可以嵌套。
5.2.1 创建、修改和运行程序 1.创建和修改程序文件 Visual FoxPro程序是包含一系列命令的文本文件,其文件扩展名 为PRG。 三个步骤:
2.运行程序 在Visual FoxPro中,一旦运行程序文件,系统会自动地对程序文件(.prg)进行编译(包括对程序的词法检查、语法检查),生成“伪编译”程序(.fxp)。执行程序时,系统实质上是执行.fxp文件。
复习:名称表达式 定义:是由圆括号括起来的一个字符表达式,可 以用来替换命令和函数中的名称(字段名、变量 名、窗口名、菜单名、文件名、对象名) 格式:(内存变量名称) 功能:可以用来替换命令和函数中的名称,从而为VFP命令和函数提供了灵活性。
(1)用名称表达式替换命令中的字段名 USE XS FLD1='XH' FLD2='XM' BROWSE FIELDS (FLD1),(FLD2)
(2) 用名称表达式替换命令中的变量名。 Nvar=100 Var_name='nvar' Store 123.4 to (var_name) ?nvar 结果123.4
(3)用名称表达式替换命令中的表文件名 Dbf_name='js' Use (dbf_name)
(4)用名称表达式作为函数的参数 String1='visual foxpro 6.0' str_var='string1' ?substr((str_var),1,6) 结果:string
(5)用字符串表达式来构成一个名称表达式 Db_name='jxsj' Dbf_name='js' Use(db_name+'!'+dbf_name)
(6) 名称表达式不能出现在赋值号左边 例: Var=[abc] (var)=123
(7)宏替换 格式:&字符内存变量 功能:将存贮在字符型内存变量中的字符串替换出现,即把该变量所代表的字符串去掉定界符后重新放到该函数所在位置上。宏替换函数符号与内存变量名之间不能有空格,宏替换函数的范围是从符号“&”起,直到遇到一个点号(.)或空白为止。
(7)宏替换 nVar=100 var_name='nvar‘ store 123.4 to &var_name ?nvar 123.4
名称表达式和宏替换的相同点 1.替换命令中的变量名 Nvar=10 var_name='nvar' Store 100 to (var_name) Store 100 to &var_name ?nvar 2.替换命令中的文件名 X='js' Close tables all Use &x Use (x)
5.宏替换与名称表达式的不同点 1)宏替换可以连续替换,名称表达式则不行 例: string1='visual foxpro' Str_var='string1' ?substr(&str_var,1,6) &&visual ?substr((str_var),1,6) &&string
5.宏替换与名称表达式的不同点 2)宏替换可以出现在“=”左边,而名称表达式则不行 2.当‘=’为关系运算符时 Use xs Field_name='xs.xm' Locate for &field_name='李千里' Locate for (field_name)='李千里' 1.当’=’为赋值号时 Var_name='cvar3' &var_name='test2' (var_name)='test2' ?&var_name
5.宏替换与名称表达式的不同点 3)宏替换可以和其他符号直接相连,构成变量名,其结尾符 号为点号(.),而名称表达式不能和其他字符直接相连。 Nvar=10 Nvarb=50 Xnvar=20 var_name=‘nvar’ Store 230.5 to &var_name.b ?nvarb Store 100 to x&var_name ?xnvar
5.宏替换与名称表达式的不同点 4)宏替换可以用于类型转换,而表达式不可以。 这一点也可以理解为:宏替换可以构成表达式, 而名称表达式则不可以。 m=’25’ ?15+&m ?15+(m)
5.宏替换与名称表达式的不同点 5)宏替换可以替换整条命令,而名称表达式不可以 X=‘select xh,xm,xb from xs where xb=‘女’’ &x (x)
5.2.2 顺序结构 所谓顺序结构,是指程序运行时按照 语句排列的先后顺序,一条接一条地依次 执行,程序的执行流程如图5-1所示。 A B 图5-1 顺序结构
例5.1 下列程序的功能是计算圆的面积,其半径为4.12。 STORE 4.12 TO P S=P*P*3.14 ?'圆面积为:',S
例5.2 下列程序的功能是显示一个字符串在另一个字符串中的位置。 C=‘Visual FoxPro’ CC=‘Fox’ ?AT(CC,C)
例3 执行下列命令后,被打开的表文件是: X=‘xs.dbf/cj.dbf/js.dbf’ L=AT(‘/’,X)+1 F=SUBSTR(X,L,2) USE &F
5.2.3 分支结构 所谓分支结构,是指程序在运行过程 中,根据条件执行不同的操作。在VFP 中,有两种实现分支结构的语句: • 1.IF… else… endif语句 • 2.Do Case…endcase语句
(IF前的语句) F Lexp 语句组2 T 语句组1 (ENDIF后的语句) 1.IF… else… endif 语句 语法格式: IF lExpression Commands1 [ELSE Commands2] ENDIF
(IF前的语句) F Lexp 语句组2 T 语句组1 (ENDIF后的语句) 例5.3 下列程序的功能是根据变量x的值决定变量y的值(为1或-1) X=8 X>0 Y=1 ELSE Y=-1 ENDIF ?Y IF
(IF前的语句) F Lexp 语句组2 T 语句组1 (ENDIF后的语句) 例5.3 下列程序的功能是根据变量x的值决定变量y的值(为1或-1) X=-8 X>0 Y=1 ELSE Y=-1 ENDIF ?Y IF
例5.4 下面方程的功能是解一元二次方程。其中,PARAMETERS语句用于接收程序的参数(三个参数a、b、c分别对应一元二次方程的系数)。如程序名为cx.prg 述程序在运行时,必须使用具有WITH子句的DO命令,WITH子句中给出与a,b,c参数对应的值。格式:DO 程序名WITH 1,2,1
Parameter a,b,c T a=0? F delta=b*b-4*a*c F Delta>=0? i2 T Delta>0 F i12 T i11 结束 一元二次方程:ax2+bx+c=0 求解过程: (1)判断 a?=0 i)为0,提示“二项式系数不能为零”,结束 ii)不为0,进入步骤(2) (2)求Δ(程序中记做delta)的值, delta=b2-4*a*c。 i)判断delta?>=0,是进入i1),否进入i2) i1)是 判断 i11)delta>0,则 x1=(-b+sqrt(delta))/(2*a), x2=(-b-sqrt(delta))/(2*a), 结果输出,结束。 i12) delta=0 x1=x2=-b/(2*a), 结果输出,结束。 i2)否 实部:real_part=-b/(2*a), 虚部:img_part=sqrt(-delta)/(2*a), 结果输出,结束。 (3)结束 i1
PARAMETERS a,b,c • IF a=0 • =messagebox("二次项目系数不能为零!",48,"错误显示对话框") • return • endif • delta=b*b-4*a*c • if delta>0 • ?"方程有两个不等的实数根:" • ??(-b+sqrt(delta))/(2*a) • ??(-b-sqrt(delta))/(2*a) • else • if delta=0 • ?"方程有两个相等的实数根:" • ??(-b)/(2*a) • else • ?"方程有两个复根:" • real_part=-b/(2*a) • img_part=sqrt(-delta)/(2*a) • ?ALLTRIM(STR(real_part)+"+"+alltrim(str(img_part))+"i") • ?ALLTRIM(STR(real_part)+"-"+alltrim(str(img_part))+"i") • endif • endif
2.DO CASE… ENDCASE语句 IF语句只能判断最多两种情况,即“二分支”。若 要判断多于两种可能的情况,有两种方法可以实现。: • 一是在IF语句中嵌套IF语句,这种方法虽然可行,但当情况较多时结构不是很清晰。 • 第二种方法就是使用 DO CASE…ENDCASE语句(简称DO CASE语句)。
语法格式: DO CASE CASElExpression1 Commands1 [CASE lExpression2 Commands2 … CASE lExpressionN CommandsN] [OTHERWISE Commands] ENDCASE DO CASE Lexp1 语句组1 Lexp2 语句组2 … … Lexpn 语句组n 其他语句组 ENDIF后面的语句
Parameter a,b,c T a=0? F delta=b*b-4*a*c DO CASE Delta=0 步骤i delta>0 步骤ii delta<0 步骤iii 结束 一元二次方程:ax2+bx+c=0 求解过程: (1)判断,a?=0 i)为0,提示“二项式系数不能为零”,结束 ii)不为0,进入步骤(2) (2)求Δ(程序中记做delta)的值, delta=b2-4*a*c。 i)delta=0,则 x1=x2=-b/(2*a), 结果输出,结束。 ii)delta>0,则 x1=(-b+sqrt(delta))/(2*a), x2=(-b-sqrt(delta))/(2*a), 结果输出,结束。 iii) delta<0,则 实部:real_part=-b/(2*a), 虚部:img_part=sqrt(-delta)/(2*a), 结果输出,结束。 (3)结束
PARAMETERS a,b,c IF a=0 =messagebox("二次项目系数不能为零!",48,"错误显示对话框") return endif delta=b*b-4*a*c Do case Case delta>0 ?"方程有两个不等的实数根:" ??(-b+sqrt(delta))/(2*a) ??(-b-sqrt(delta))/(2*a) Case delta=0 ?"方程有两个相等的实数根:" ??(-b)/(2*a) Case delta<0 ?"方程有两个复根:" real_part=-b/(2*a) img_part=sqrt(-delta)/(2*a) ?ALLTRIM(STR(real_part)+"+"+alltrim(str(img_part))+"i") ?ALLTRIM(STR(real_part)+"-"+alltrim(str(img_part))+"i") endcase
循环入口 .F. Lexp 循环体后的语句 .T. 语句组 5.2.4 循环结构 在应用程序中经常会遇 到重复性操、作,重复的 次数有时可知、有时不可 知(只能根据操作的结果 确定操作是否应该结束)。 为适应这样的要求,程序 设计语句提供了循环语句。 这类语句的执行流程如图 所示。
5.2.4 循环结构 循环就是使得一组语句重复执行若干次,可以预 先制定要循环的次数,也可以根据某个条件控制循 环。在Visual FoxPro中,实现循环结构的语句有三种: • FOR…ENDFOR • DO WHILE…ENDDO • SCAN…ENDSCAN 其中,循环开始的语句称为循环的入口语句,如: FOR、DO WHILE、SCAN,循环结束的语句称为循环的 出口语句,如ENDFOR、ENDDO、ENDSCAN。在入口语 句和出口语句之间的一组语句常称为循环体。
1.FOR…ENDFOR循环结构 若预先知道循环的次数,可以使用FOR语 句实现循环。 FOR语句的语法格式为: FORnVar=nIitialValue TO nFinalValue[STEPnIncrement] Commands ENDFOR|NEXT 循环变量nVar是作为计数器使用的变量 计数器的初始值 计数器增加或减少的步长,缺省时为1 计数器的终值 在循环体Commands中,可以包含LOOP和EXIT语句。LOOP用于将控制直接返回给FOR语句,即忽略此后的循环体语句,以进入新的一次循环;EXIT语句将控制传递给ENDFOR后的第一条语句,即“跳出”循环
1.FOR…ENDFOR循环结构 FOR循环的执行过程如下: (a)将初值赋给循环变量 (b)判断循环变量的值是否超过终值,若超过终值,则结束循环,否则执行循环体。 (c)计算循环变量的值:循环变量=循环变量+步长; (d)转到(b)步骤执行。 FORnVar=nIitialValue TO nFinalValue[STEPnIncrement]