1、第2章 OOP Pascal基础知识,内容提要,OOP Pascal基本知识常用数据类型运算和运算符常量和变量常用语句过程和函数,2.1 OOP Pascal基本要素,Delphi是Borland公司推出的面向对象的可视化编程环境,特别适合于快速规范地开发Windows应用程序。从Borland公司推出Delphi 1.0至今,Delphi已经发展了7代产品,每一代都是伴随Windows操作平台的升级而升级。使用Delphi,用户可以轻松地进行各种复杂应用程序的开发。,2.1.1 标识符,标识符是用来标识一个特定元素的,如类名、变量名、单元名、方法名等。利用标识符可以完成对变量、常量、数据类型
2、、过程、函数、类等的引用。,Object Pascal标识符由字母、数字、下划线组成,其规定为: (1)必须以字母或下划线开始; (2)不能与保留字相同; (3)避免与Object Pascal已经使用的标准标识符相同。,2.1.2 关键字,关键字又称保留字(Reserved Words)是由系统规定的、具有特定意义的单词。在编程时不能被重新定义或另作他用。Object Pascal 语言规定的保留字详见本教程P28页表2-1。,除了上述的保留字外,Private、Protected、Public、Published 和Automated在定义对象类型时也作为保留字,而在其他场合则作为指令符。
3、单词at和on也具有特殊的含义。注意:Object Pascal 编程语言和许多编程语言不同,它对单词的大小写是不敏感的。Object Pascal不区分大小写。IN、in和In都被看做是同样的意义。,2.2 数据类型,OOP PASCAL 语言是一种强类型语言,这表明每一个变量在赋值之前必须明确给出它的类型。即变量在访问之前必须声明。OOP PASCAL 数据类型丰富,它允许使用17种类型的数据。其结构如P31图2-1所示。,2.2.1 简单类型,OOP PASCAL 中的简单类型包括整形、字符型、布尔型、枚举型、子界类型以及实数类型。其中,整形、字符型、布尔型、枚举型、子界类型统称为顺序类
4、型(ordinal types)。在顺序类型中,除了第一个元素,每一个元素都有唯一的前趋;除了最后一个元素外,每一个元素都有唯一的后继。,1. 整型,OOP PASCAL 中将整数类型分为基本的 (fundanmental) 和一般的 (generic) 整数类型。 基本的整数类型包括 Shortint (短整型)、Smallint (小整型)、Longint (长整型)、Int64 (64位整型)、Byte (字节型)、Word (字型)和 Longword (长字型)。它们的取值范围和格式如表2-4所示:,表2-4 基本整数类型,2. 字符型,字符类型也有基本类型和一般类型之分。基本类型包
5、括 AnsiChar 和 WideChar 两种类型。其中,AnsiChar 的格式为8位字节,取值的序数按扩展 ANSI 字符集排列;而 WideChar 的格式为16位字节,是为兼容 UniCode 字符集而设置的,它的前256个 UniCode 字符同 ANSI 字符相同。一般的通用字符类型为 Char ,它等价于 AnsiChar。由于字符型也属于顺序类型,可用函数 Ord 来取出字符的序数,即 Ord(A)=65 成立。也可用预定义的函数 Chr 来返回对应的字符值,即 Chr(65)=A 成立。,3. 布尔型,布尔型数据用于进行逻辑运算,布尔型数据的值只有两个:True(真)和Fa
6、lse(假)。 Object Pascal包括4种形式的布尔型数据,详见表2-7。,表2-7 Object Pascal 语言的布尔型,4. 枚举型,枚举类型定义了一组值的顺序集合。它们的次序根据标识符的枚举顺序而定。在 Delphi 中广泛使用了枚举类型来定义组件对象的属性。 枚举类型是一种用户子定义类型,定义枚举类型的语法如下: Type 类型名称(TypeName) = (值1,值2,值3,值n);如下是定义枚举类型的例子:Type Fruits=(Apples , Oranges , Bananas , Grapes);在程序中定义好了枚举类型后,可以象如下声明变量:Var MyFru
7、it : Fruits;,5. 子界类型,子界类型也是一种用户字定义类型,它规定了值域的上界和下界及取值的类型。字节类型必须是顺序类型中某范围的值,在想限制一个变量的取值范围时,子界类型是非常有用的。子界类型的定义如下: Type 类型名称 = 值域下界 值域上界;定义子界类型必须注意以下几点:上界和下界必须属于顺序类型,且为同一顺序类型。上界和下界的类型定义了子界的基类型。上界的序号必须大于下界的序号。 正确的定义举例如下:Type SomeNumbers = 0 15;SomeCaps = A H; 变量声明可以采用以下方式: Vars: someNumbers ;,6. 实型,实数类型用
8、于定义一个通常所说的浮点数所表示的数字的集合。它是属于数据类型中的简单类型,但已不属于顺序类型。 实数类型也有基本类型和一般类型。基本类型包括:Real48 、Single 、Double 、Extended 、Comp 和Currency ;一般类型为:Real 。详细的格式及表示范围如表2-6 所示:,占用内存(字节),2.2.2 字符串类型,字符串型是存储字符串数据的类型。OOP PASCAL 中提供的预定义类型如表2-7:,表2-7 字符串类型,注:在 Delphi5.0 以后的程序中可直接定义String 类型,其默认为 AnsiString 类型(或者说是LongString 类型
9、),如果使用$H-,则被解释为 ShortString 类型。,2.2.3 结构类型,结构类型包括:集合(Set)、数组(Array)、记录(Record)、文件(File)以及类(Class)、类引用(Class Reference)、接口(Interface)等类型。它的实例中含有一个或多个值。,2.2.4 指针类型,指针是内存中数据结构的详细地址,相当于一个表示内存地址的变量。指针类型声明的一般形式为:Type 指针类型名 = 类型特殊符号 “” 表明了是一个指针类型,其后面紧跟的类型确定了指针所指向的类型,可以是简单类型,如整型、实型、枚举等;也可以是结构类型,如数组、集合、记录等类型
10、。 “”还有另外一种含义,跟在指针类型的变量后面,表示具体的值。配合指针操作的还有符号“”,它是取址运算符,表示取地址操作。,2.2.5 过程类型,过程类型变量相当于指针的角色,它可指向一个过程或函数,并且可以作为另一个过程或函数的参数使用。其定义的方式如下例: Type TProcedure = Procedure ;/声明一个无参数过程类型 TIntegerFunction = Function:Integer; / 声明一个无参数函数类型,返回值为整型 TStringProcedure = Procedure(const S:String);/声明一个带有 String 类型参数的过程类
11、型 VarProc :Tprocedure;IntF :TintegerFunction;StrP :TstringProcedure;,2.2.6 可变类型,用于标识可变类型的保留字是Variant ,Variant 类对象本质上是无类型变量,也就是它们可以自动显现不同的类型。 可变类型就是为了解决在编译时数据类型无法确定的情况下,Object Pascal 才引入的数据类型。 可变类型变量举例如下: Var X :Variant; S :String; Begin X := 10 ; S := IntToStr(X+20); X := Object Pascal; MessageDlg(X
12、,mtConfirmation,mbYesNoCancel,0); End;,2.3 运算和运算符,运算是对数据进行加工处理的过程,描述各种不同运算的符号称为运算符,而参与运算的数据称为操作数。表达式是表示某个求值规则的运算公式,它由运算符和圆括号将常量、变量等操作数以合理的形式组合而成。表达式可以用来执行运算、操作或测试数据,每个表达式都会产生惟一的值。表达式的类型由运算符的类型决定。在Object Pascal 中有以下几种运算符:算术运算符、位运算符、字符串运算符、关系运算符、布尔运算符、集合运算符、指针运算符、类运算符和运算符。本节介绍几种常用的运算和运算符。,2.3.1 算术运算,算
13、术运算的操作对象为整形或实型,算术运算符包括 +,*,/,div 和 mod,详细说明如下表2-8:表2-8 OOP PASCAL语言的算术运算符,2.3.2 布尔运算,布尔运算的操作对象的类型为布尔型,返回的结果值也是布尔类型。布尔运算符基本有四个,分别是 Not , And , Or , Xor , 其详细说明如表2-9:表2-9 OOP PASCAL语言的布尔运算符,2.3.3 逻辑运算,逻辑运算实现的是按位的运算,它的操作及其操作的结果均为整数,逻辑运算的操作说明如下表2-10 所示:表2-10 OOP PASCAL语言的逻辑运算符,2.3.4 指针运算,指针运算符及其说明如下表2-1
14、1: 表2-11 OOP PASCA 语言的指针运算符,2.3.5 集合运算,集合运算是以集合类型作为操作数的,它的运算符及其说明如下表2-12:表2-12 OOP PASCAL语言的集合运算符例如(4 in 1,20)=false (2 in 1,2)=true,2.3.6 关系运算,关系运算用于比较两个操作数,其返回值的类型是布尔型。关系运算符的操作说明如下表2-13:表2-13 OOP PASCAL语言的关系运算符,2.3.7 字符串运算,操作符 + 可以用作算术运算符、指针运算符和集合运算符,还可以用作表示把两个字符串类型的操作数相连接,即连接两个字符串。例如:My+ String=
15、MyString;,2.3.8 取址运算,取址运算符 ,它返回变量、函数、过程或方法的地址。关于取址运算符 ,其原则说明如下:如果 X 是变量,则 X 返回 X 的地址;在默认的编译指示$T-下,X 的类型为 Pointer ;而在$T+状态, X 的类型为 T,其中的 T 为 X 的类型。如果 F 是一个过程或函数, F 返回 F 的入口点,它的类型一定是 Pointer 。,2.3.9 运算符的优先顺序,在表达式中有多种运算符时,要注意各个操作符之间的优先级。通常情况下,先作括号里的运算,再从优先级由高到低的次序来做,同等优先级的,按从左到右出现的顺序处理。所以,在不清楚具体优先级的情形下
16、,可以使用括号,来确保程序的正确性。,表2-14 OOP PASCAL中运算符的优先级,2.4 常量与变量,定义常量的目的基本上有两种:其一,在程序中经常用到某些常数值,为了书写方便及减少频繁输入造成错误,可把它定义为一个常量;其二,就是为了便于程序的阅读或修改,定义常量可使程序易于维护。 1常量的声明 常量可以在程序、单元、过程或函数的声明部分进行声明,常量在说明时就被赋予了一个值,在程序执行过程中是不可改变的。 声明常量的一般形式如下: Const常量名1=常量值1;常量名2=常量值2;,在程序设计中常用到两种形式的数据,一种是在程序执行过程中其值保持不变的数据,称为常量;另一种是在程序执
17、行过程中其值可以改变的数据,称为变量。,2.4.1 常量,2. 类型常量类型常量主要是不能修改的只读变量。在声明常量时,直接声明其常量类型。类型常量的声明方法如下:Const常量名1:类型名=常量值1;常量名2:类型名=常量值2; 举例如下: ConstWeekDays:Integer=7;DayInYear:Integer=365;,2.4.1 常量(2),2.4.2 变量,变量实际就是程序员在内存中指定的一个带有标识符的地址空间,变量名则是这个指定内存地址的标识符,而变量的类型则确定了这个内存地址中存的值什么样是合法的或可能的,并且该内存地址里的值是可以改变的。 1. 变量的声明 变量在使
18、用之前,也必须先进行声明。声明变量的保留字为 Var ,其声明的一般形式如下:Var变量名1:类型名1;变量名2:类型名2; 声明变量举例如下:VarGz_Sum : Real;Value_1,Value_2 : Integer;StrTitle : String;X : Variant;,2.4.2 变量,2. 变量的作用域变量的作用域是指它的可见性和生命期。可见性是指可以访问该变量的区域,生命期是指一个变量可以保持它的值和可见性的时间。在 Delphi 7 中,变量可以在程序、单元、函数或过程的声明部分进行声明,声明的位置则决定了变量的作用域。 声明在过程或函数内部的变量有时叫做局部变量,
19、而在应用程序开始声明的变量叫做全局变量。全局变量可以在声明时对它进行初始化,格式为:var :=其中常量表达式的值必须与变量定义的类型相兼容。,2.4.2 变量,3. 变量的强制类型转换 由于 Delphi 的编译器对各种类型的参数检查是非常严格的,类型不匹配则通不过编译器的编译检查,为通过编译器的编译检查,经常需要把一个变量的类型转换为另一个变量类型。强制类型转换就是一种技术,通过它能使编译器把一种类型的变量当作另一种类型变量,由此来通过编译器的编译检查。注:强制类型转换要求两种类型在内存中存储空间的大小必须相同,整数类型变量与实数类型之间不能进行这样的转换,应该通过预定义的标准函数,如:T
20、runc()或Round()函数。,2.5 OOP PASCAL 中的语句,Object Pascal 中的语句可分为简单语句和结构语句两种。简单语句有赋值语句、空语句、跳转语句(Goto语句)和过程语句;结构语句有复合语句、条件语句、循环语句和 开域语句(With 语句)。,语句的书写规则 可以把多个语句放在一个程序行中,也可把一个语句分多行书写 每个语句都必须以分号“;”结束。 对于较为复杂的程序常用到复合语句,复合语句是指将多个语句用begin和end两个保留字包围起来,格式如下: begin ; ; ; end;复合语句在Object Pascal中被视为一个语句,因此在end后必须,
21、2.5.1 简单语句,1赋值语句赋值语句用来显式地给变量赋值,即用表达式的值取代变量的当前值。赋值语句的一般形式如下:变量名 := 表达式 ; 如:MyNumber_1 := 100 ;,2. 空语句在 Object Pascal 中允许使用空语句,所谓空语句就是语句中没有任何表达式的值和赋值符号,只有一个分号。 可参见P57例题。,2.5.1 简单语句(2),3. Goto 语句和语句标号Goto 语句可以将程序的执行流程转移到程序指定的某个位置,即转移到其它语句处再继续执行。Goto 语句必须借助语句标号才可能使程序知道转移的位置,Object Pascal 可以使用标号(Labels)来
22、标识语句以提供 Goto 语句将跳转的确切位置。 Goto 语句的一般形式如下:Goto 语句标号;,注:Goto语句所转向的语句标号必须和该语句同处于相同的程序段内,不能转入或转出一个过程或函数,也不能转入该程序段内其它的循环结构。,2.5.2 复合语句,复合语句由若干个简单语句或结构语句构成,在这些语句前后加入保留字 Begin和 End 即可。其一般形式如下:Begin语句1;语句2;语句n;End;,例如:把两个变量的值进行交换的复合语句如下: BeginX := Number_1 ;Number_1 := Number_2 ;Number_2 := X ; End;,2.5.3 条件
23、语句(1),Object Pascal 语言提供的条件语句有两种,即 If 语句和 Case 语句。,1If 语句If 语句需要计算一个表达式,并根据计算结果决定程序流程。If 保留字后的表达式的值必须是一个布尔类型(Boolean)。其语句的一般形式如下: If Then ; 或语法中带有 Else 子句,如: If Then Else ;其中, 是一个逻辑型的表达式,其值为 Boolean 类型。当值为真(True)时,程序执行保留字 Then 后的 ;当值为假(False)时,程序则执行保留字 Else 后的 。两种形式中的 即可以是单语句也可以是复合语句。最后的“;”号代表着 If 语
24、句的结束,所以在保留字 Else 之前不应加有“;”号。,2.5.3 条件语句(2),2. Case 语句Case 语句的一般语法形式为:Case 选择器表达式 Of情况常量表1:语句1;情况常量表2:语句2;情况常量表n:语句n;Else语句End; 其中:选择器表达式的值必须为顺序类型(如整型、字符型、布尔型和子界型等)。情况常量列表中的值应是选择器表达式可能具有的值。由每一个情况常量列表列出的值在 Case 语句中必须是唯一的,相互间值的范围也不允许有重叠部分。Else 提供了如果所列出的情况都不出现,应执行的语句,也就是说程序只能选择一个执行结果。根据需要也可以省略掉 Else 部分和
25、它后面的语句。,2.5.3 条件语句(3),条件语句举例:以例题2.2为例,用 Case 语句来代替 If 语句的实现。程序代码如下:Case Mark Of90100 : ShowMessage(优);8089 : ShowMessage(良);7079 : ShowMessage(中);6069 : ShowMessage(及格);059 : ShowMessage(不及格);ElseShowMessage(输入超出范围);End;,2.5.4 循环语句(1),在编程过程中遇到的好多问题是重复单调的。比如从1加到100 ,问题虽然简单却要重复操作。我们可以把这些重复的动作交给计算机去完成。
26、引例:求1+2+3+100 的值。,OOP Pascal 语言提供了三种循环语句,每一种可分别适合某一特定情况。这三种循环分别是:Repeat 、While 和 For 循环语句。 循环结构只关心下面的三个要素:进入循环结构的条件是什么?在什么情况下结束循环过程?循环体内部要完成的操作及在循环体内如何改变循环条件?,2.5.4 循环语句(2),1. Repeat 循环语句Repeat 循环语句是以 Repeat 开始,以 Until 结束。它可以重复执行 Repeat 和 Until 之间的语句,直至 Until 后的表达式为真,则退出循环执行其后的语句。 Repeat 循环语句的一般形式为:
27、Repeat语句1;语句2;语句n;Until ;,循环体,2.5.4 循环语句(3),2. While 循环语句 While 循环语句在多数场合下都可以代替 Repeat 循环语句,但与 Repeat 循环语句不同的是,它的布尔类型的表达式在 While 之后,即在循环刚开始处,所以 While 循环是先进行判断,再执行循环语句。While 循环语句的一般形式为:While Do 其中,表达式必须是一个具有Boolean类型值的表达式。如果表达式的值为真(True)则执行 Do 后的循环体语句;如果表达式的值为假(False),则不执行 While 循环体而直接跳到 While 循环体后再执
28、行其它语句。Do 后的循环体语句,可以是简单语句、复合语句或其它结构语句。,2.5.4 循环语句(4),3. For 循环语句For 循环语句可以执行一定的次数,它需要一个循环变量来控制循环的次数。For 循环语句有两种形式:增量循环和减量循环。增量循环 For 语句的一般形式为:For 循环变量名:=初值 To 终值 Do 语句减量循环 For 语句的一般形式为:For 循环变量名:=初值 DownTo 终值 Do 语句其中,循环变量必须是一个顺序类型的局部变量,也不允许带有限定符。初值和终值的类型应和循环变量的类型兼容。循环体中的语句可以是简单语句、复合语句或结构语句。,2.5.4 循环语
29、句(5),三种循环的比较以上三种循环都可用来实现循环,它们的使用特点归结为:如果知道循环执行多少次的话,可以使用 For 循环语句结构。 For 循环执行速度快,效率高。如果不知道循环要执行多少次,但至少会执行一次的话,选用 Repeat Until 循环语句结构比较合适;当认为程序可能一次都不执行的话,最好选用 While Do 循环语句结构。,Break() 过程和 Continue() 过程 在 While 、Repeat 或 For 三种的循环体中,可调用 Break() 过程,使得程序的执行流程发生改变,即在循环体中当某个条件成立时跳出循环体。如果想跳过循环体中部分代码重新开始下一次
30、循环,调用 Continue() 过程。,2.6 过程和函数,一般来说每个程序都由若干个主要的任务构成,每个主要任务又可分成若干个子任务,这样逐层细化,一直细化到每个子任务都只完成一个简单的基本功能为止。 为此,可以把某些功能完全相同或非常相近的子任务单独提取出来,划分成程序的基本单元,其它程序可以重复调用。这样做提高了编程效率,是程序更加规范化,也减少了代码的出错率。,函数和过程就是 OOP Pascal 语言中的两种子程序,它们可以随时被调用。函数在执行时将返回一个值,而过程执行时不返回任何值。,2.6.1 过程的声明,过程声明的一般语法形式为:procedure 过程名(形式参数表);指
31、令符; 局部声明: begin 执行语句 end;,在Delphi 7 的单元中声明过程或函数时,只需要在单元内声明过程或函数头部(可在单元的接口部分,也可在单元的实现部分),然后把光标定位在头部内,点击鼠标右键弹出快捷菜单,在该菜单中单击 【Complete Class at Cursor】菜单项即可。Delphi 7 会帮助完成自定义过程、函数或类的输入。,2.6.2 函数的声明,函数声明的一般语法形式为:Function 函数名(形式参数表):返回类型;指令符; 局部声明部分 begin 执行语句 end;,需要特别注意的是:函数必须有返回值,所以在函数声明时要给出返回值的类型;而过程没
32、有返回值,声明时也就没有返回类型。,2.6.3 过程和函数的调用,1过程调用 调用过程的一般形式如下: 过程名(实参数表); 如果声明的过程没有形参,调用时便可以省略后面的实参表,其形式如下: 过程名;,2函数的调用 调用函数的一般形式如下:函数名(实参数表);在调用过程和函数时要注意:在过程与函数声明的作用域内才可调用该过程或函数;调用过程或函数时还要注意有参数时,参数的类型一定要保持相同。,2.6.4 参数传递方式,在上面的调用过程或函数时,程序将把实参传递给形参,按传递方式的不同,OOP Pascal 中过程和函数的参数可分为:值参数、常量参数、变量参数和外部参数。,1值参数 如果形式参
33、数表中的参数前面没有 Const 、Var 或 Out 声明的参数,该参数则为值参数类型。 在 OOP Pascal 中值参数是按“值传递”方式将实参的值传送给形参的。值传递指的是在调用子过程语句被执行时,带实参值的调用语句将实参复制给子过程中的形参。所以要求实参的个数、数据类型与形参个数、数据类型完全匹配。,2.6.4 参数传递方式,2常量参数 如果形式参数表中的参数前面有 Const 声明的参数,该形式参数则为常量参数。常量参数在过程或函数中是绝对不允许改变的参数值,也不能再作为实参传送给该过程或函数体中另一个过程或函数的变量形参。 如果在一个过程或函数中其形参在执行过程中不应该改变其数值
34、的话,那么就应该使用一个常量参数。这样可以保护形参而杜绝发生意外的情况。 Delphi 7 系统 在 Sysutils 中声明的字符串比较函数,如 CompareStr() 函数中的形参就是常量参数,它的首部如下:Function CompareStr(Const S1,S2:String):Integer;,2.6.4 参数传递方式,3变量参数 如果形式参数表中的参数前面有 Var 声明的参数,该形式参数则为变量参数类型。变量参数的参数传递方式为“地址传递”方式。 地址传递指的是调用过程语句被执行时,过程中的形参直接引用了调用语句中的实参。所以形参与实参实质上是用同一个存储单元。如果在子过程中修改了形参值,就会直接体现在实参上,在某些情况下,会造成负面影响。,2.6.4 参数传递方式,4外部参数如果形式参数表中的参数前面有 Out 声明的参数,该形式参数则为外部参数类型。外部参数与变量参数一样在实参与形参之间的值传递是按地址传递方式进行的。但是使用时与变量参数有很大的区别。当调用含有外部参数的过程或函数时,所引用的实参(变量)的初始值将被抛弃,该变量仅被用来作为一个容器来存储过程或函数执行的中间结果。在编写应用象 COM 、CORBA 这样的分布式对象模型的程序中,会经常使用外部参数。,