Delphi 是以 Object Pascal 语言为基础的可视化开发工具,虽然两者之间有着很大区别,但是要学好 Delphi,首先要掌握的就是 Object Pascal 语言。
Object Pascal语言编写环境
如何使用Delphi编写Object Pascal 程序。一般来说,使用 Delphi 开发出来的程序有以下 3 种。
1.图形界面程序
图形界面程序是目前Windows 平台最常见的应用程序,这些程序通过窗体和对话框与用户进行信息交互,实现一定的功能。例如Microsoft 公司的Office 系列软件和正在使用的Delphi 等,它们都是图形界面程序。
2.控制台程序
控制台程序是指一些没有图形用户界面的32 位Windows应用程序,类似在DOS 环境下运行的程序。这些程序很少要求用户输入大量的信息,一般只实现特定的功能。控制台程序的代码较小,占用的系统资源少,因此编译、链接的速度比较快。
3.服务器程序
服务器程序可以接受和处理客户应用程序的请求,并将结果信息返回给客户应用程序。服务器应用程序一般在后台运行,不需要大量的人机交互信息。
下面以开发一个简单的控制台程序为例,向读者介绍Delphi 中生成Object Pascal 程序的基本方法,并对Object Pascal 程序的一般结构进行简单说明。
在Delphi集成开发环境中,依次选择“File”? “New”?“Other”菜单项打开“New Items”对话框。选中“New”标签页中的“Console Application”选项,单击“OK”按钮,代码编辑器中将自动打开一个初始名为Project1.dpr的控制台程序。请将Project1.dpr 文件修改为如下内容:
program
Project1;
{$APPTYPE
CONSOLE}
//uses
SysUtils;
var
str:string;
begin
// Insert user code here
writeln(’您好,这是一个示范程序,请输入一行文字:’);
readln(str);
writeln(’您输入的是:’,str);
readln;
end.
依次选择“File”? “Save
All”菜单项可以将更改后的工程文件保存到指定的文件夹中。本章后面的例子都可以在该工程的基础上方便地实现。
按F9键进入编译、链接、运行程序。待程序提示“您好,这是一个示范程序,请输入一行文字:” 文字后,用户可以输入一些内容,例如输入“早上好!”,程序将输出结果:“您输入的是:早上好!”。
以下是对该程序的几点说明:
[if !supportLists]• [endif]程序第2 行中{$APPTYPE
CONSOLE}是一个编译器指令,它告诉编译器这个程序是一个控制台程序。
[if !supportLists]• [endif]uses SysUtils 语句前加了两个斜线,将这条语句以注释语句的形式屏蔽掉了,因为在这个例子中是不需要SysUtils 单元的。
[if !supportLists]• [endif]writeln 和readln两个函数分别表示输出和输入一行字符。程序最后的readln 语句是为了锁定窗口,否则输出结果将很快消失。
注释语句
作为起点,首先介绍如何在Object Pascal 代码中添加注释。如果不给程序加上适当的注释,一段时间后就很难理清程序的流程。同时编译器会将注解忽略,不会影响程序的编译与运行。
Object Pascal 中有3 种类型的注释。
花括号注释:组合符号“{”和“}”的成对使用。——{……}
圆括号/星号注释:组合符号“(*”和“*)”的成对使用。——(*……*)
Visual C++风格的双斜杠注释:符号“//”的单独使用。——//……
注意,相同类型的注释不要嵌套使用。虽然不同类型的注释进行嵌套在语法上是合法的,但不建议这样做。
标识符
Object Pascal 语言使用的标识符包括字母 A~Z、a~z、数字 0~9 及其他一些标准字符。
Object Pascal 语言的特殊符号
$ & * # � ( ) [ ] { } ^ ; : @ < = > , . ? + /
Object Pascal 语言的单个的特殊符号
(* *) (. .) .. // := <> >= <=
在 Object Pascal 语言中,标识符用来标识变量、常量、属性、类、对象、过程、函数、程序、组件库等。标识符可以由任意长度不带空格的字符串组成,但对于编译器来讲只有前面
255 个字符有效。其中,标识符的第 1 个字符必须是字母或下划线,其余字符可以是字母、数字或下划线。通常,标识符由一个或多个具有适当意义的英文单词组成。Object Pascal 语言对区分字母的大小写是不敏感的。
保留字和指令字
Object Pascal 还定义了 39 个指令字,它们具有特殊含义。但是,在用户重新定义了指令字后,在作用域内它们就失去了原来的意义。
其中Private、Protected、Public、Published、Automated、On 和At是指令字,但是,应当视其为保留字,不要定义和它们同名的标识符。
在 Delphi 集成开发环境的代码编辑器中,保留字和指令字以黑体显示,这样就大大方便了用户的使用,不必担心因为不小心而错误地将保留字或指令字定义为标识符。
数据类型与定义变量
传递给过程或函数的参数值必须与形参的类型一致。变量是程序代码中代表一个内存地址的标识符,那么该地址的内存内容就可以在程序代码执行时被改变。每个变量都有一个名字和数据类型,名字可以用来引用变量,数据类型决定变量的取值范围。
1.数据类型概论
Object Pascal 语言提供了非常丰富的数据类型,即简单类型(Simple)、字符串类型(String)、结构类型(Struct)、指针类型(Pointer)、函数和过程类型(Procedural)和变体类型(Variant)等。
(1)简单类型(Simple)
简单类型包括实数类型(Real)和有序类型(Ordinal)。有序类型又包括整数类型、字符类型、布尔类型、枚举类型和子界类型等。
① 整数类型;包括的类型:
Integer -2 147 483 648~2147 483 647
Cardinal 0~42 994 967 295
Shortint -128~127
Smallint -32 768~32 767
Longint -2 147 443 648~2 147 483 647
Int64 -2 ~2 -1
Byte 0~255
Word 0~65 535
Longword 0~4 294 967 295
②字符类型;字符类型有 3 种字符变量:
AnsiChar 8 位 根据扩展 ANSI 字符表排列
WideChar 16 位 根据 Unicode 码排列,前 256个 Unicode 字符同 ANSI 字符相同
Char Delpi 中通用的字符类型,相当于WideChar
注意:因为一个字符在长度上并不表示一个字节,如果程序中必须用到字符的字节数,最好用 SizeOf()函数获取。
③布尔类型
布尔类型包括4种,分别为Boolean、ByteBool、WordBool 和LongBool。Boolean和ByteBool 各占用一个字节,WordBool 占用两个字节,LongBool 占用4 个字节。
Boolean的值只能是0(False)或1(True),ByteBool、WordBool 和LongBool 可以是有符号的整数,为0 值代表False,非0值代表True。
最常用的是Boolean 类型,而ByteBool、WordBool 和LongBool 类型是为了与其他语言和Windows 环境兼容,因为Windows 的API 在返回一个布尔值时,其值可能是一个两字节的有符号整数。如果试图把返回值赋给Boolean 类型的数据,编译器认为类型不匹配,若是进行类型强制转换,可能使返回值的有效数据被截断。
④枚举类型
枚举类型是由一组有序的标识符组成的,它列出了所有这种类型可以包括的值。例如一个星期有7 天,程序中分别用 0、1、2、3、4、5、6 来表示一个星期的每一天,但在程序中很不直观。
type //变量名=(枚举列表)
DayOfWeek=(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
为了引用此枚举类型,必须声明一个DayOfWeek 类型的变量,例如:
var
Days:DayOfWeek;
这样就声明了一个DayOfWeek类型的枚举变量Days,Days 的值总是标识符列表中的一个。
为了简化程序,还可以将类型声明和变量声明合二为一,例如:
var
Days:(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
注意:枚举的元素只能是标识符,标识符的命名规则必须符合Object Pascal 关于标识符的规定。例如不能以数字打头,标识符不能是保留字,同一个枚举元素不能同时出现在多个枚举中。
⑤子界类型
子界类型是下列类型中某范围内的值,即整型、布尔型、字符型或枚举型。如果需要限制一个变量的取值范围时,子界类型是一个好的选择。
⑥实型
实型不是有序类型,因为它的值域是无限的,实型的数据也叫实数,实型用于表示通常所说的浮点数。Object Pascal 语言中的实数数据(Real)类型
Real48 Single Double Extended Comp Currency Real。
常用的实数类型是 Real、Single、Double。
(2)字符串类型(String)
Object Pascal 的字符串类型分为短字符串和长字符串两种。
短字符串,指字符串长度最大不超过 255 个字符的字符序列。当编译开关的状态为{$H-}时,用保留字 String 声明的是一个短字符串,不管编译开关$H 处于什么状态下,用 ShortString声明的变量总是短字符串类型。保留字String 后用方括号括起来的无符号整数,表示字符串的最大长度是200。当把一个字符串赋给一个短字符类型的变量时,超过其最大长度的将被截掉。短字符串中的每一个字符都可以通过字符串名加字符索引来访问。索引是从0 开始的,但索引 0 处存放的是字符串的实际长度,如下两行代码的功能是一样的,索引1 处才是真正的字符开始处。短字符串的长度是动态改变的,可以使用Low和High 函数取得字符串的最小序号和最大序号,Low 的返回值是0,High 的返回值是所声明的字符串的最大长度。
长字符串的长度几乎是无限制的,理论上可以达到2GB,实际上只会受计算机内存的限制。要声明一个长字符串,可以用预定义的标识符AnsiString 或把编译开关$H 改为{$H+}后用保留字String 声明。长字符串在声明以后自动被初始化为空字符串。长字符串中的每个字符,是从索引1 开始的,长字符串没有索引0,要取得长字符串的实际长度,只能调用Length()函数。长字符串在它最后一个字符后自动加一个NULL 字符表示字符串结束(NULL 字符并不是长字符串的一部分),这一点与字符指针类型(PChar)类似,因此将一个长字符串转换为PChar类型很方便,语法为:PChar(Str),其中Str 代表长字符串。长字符串被转换为一个指针,指向字符串的每一个字符,即使长字符串是空的,强制转换后总是能够获得一个指向以NULL 字符结束的字符中的指针。Object Pascal 允许字符串和长字符串同时出现在一个表达式中,编译器会自动根据需要进行转换。
注意:字符串变量必须用一对单引号括起来,如果字符串本身就有单引号,这个单引号要用两个连续的单引号表示,如:’His name is ’’Jim’’’。
(3)结构类型(Struct)
结构数据类型包括:集合类型、数组类型、记录类型、文件类型、类类型、类引用类型和接口类型等。
集合类型是一群具有相同类型的元素的组合,这些类型必须是有限类型,如整型、布尔型、字符型、枚举型和子界类型。
type
Set1=set of ’A’.. ’Z’; //基类型是子界型
Set2=set of Char; //基类型是字符型
Set3=set(Jan,Feb,Mar,Apr); //基类型是枚举型
Object
Pascal 语言提供了几个用于集合的运算符,用这些运行符可以判断集合与集合之间的关系,例如对集合增删元素,求交集运算等。赋值运算与简单类型一样,声明了一个集合类型的变量后,要为这个变量设定一个明确的值,例如:
var
TInt1,Tint2:set of 1..10;
以上代码虽然声明了两个集合变量,但变量 TInt1 和 TInt2并不是代表 1~10 组成的集合,必须对它们赋值:
TInt1:=[1,3,5,7,9];
TInt2:=[2..5,8..10];
这样TInt1 就是由1、3、5、7、9 组成的集合,TInt2 就是由2、3、4、5、8、9、10组成的集合。
关系运算,就是对集合类型的运算,遵循数学中关于集合运算的规则,运算的结果是布尔值。集合的关系运算就是判断两个集合相互之间的关系,关系运算符包括:=(等于)、<>(不等于)、>=(大于等于)、<=(小于等于)。
集合 A 等于集合 B,是指两个集合中的元素完全一样(不管元素的排列顺序如何),否则就是不相等.
数组类型
数组类型是某种数据类型的有序组合,其中每一个元素的值由其相对位置来指定,可以在数组的某个位置上放置数据,并在需要时使用这些数据。下面代码声明了一个 Integer 型的数组变量:
var
TInt:array [1..15] of Integer;
表示 TInt 指向一个含有 15 个 Integer型元素的数据串列,代表每一个元素的是 1~15 之间的数字,称为索引。数组的每一项由数据组名加“[ ]”中的索引来表示。TInt 包含 15 个变量,TInt[1]代表第 1 个变量,TInt[2]代表第 2 个变量,依次类推。
数组也可以用类型定义:type Int=array [1..15] of Integer; var TInt:Int;
可以用下面的方法对数组进行赋值: for I=0 to 15 do TInt[I]:=0; //为数组各元素赋初值为0
数组可以有多维的,定义及赋值方法如下:
type
TArr=array [1..15,1..15] of Integer; var
Arr:TArr;
C,R:Integer;
��
for
C:=1 to 15 do
for R:=1 to 15 do
Arr[C,R]:=0; //为多维数组各元素赋初值为0
��
记录类型:记录是程序可以成组访问的一群数据的集合。例如下列代码,说明了一个记录类型的定义方法:
type
TStudent=record
ID:Integer;
Name:String[10];
Age:Integer;
Memo:String[100];
end;
记录包含可以保存数据的域,每一个域都有一个数据类型。上面代码中声明的 TStuednt
类型有 4 个域。用下面的方法对记录类型的变量进行声明与使用:
var
Stu:TStudent;
with Stu do //以下代码为记录赋值,也可以只给记录的单个域赋值
begin
ID:=1;
Name:= ’Jim’;
Age:=18;
Memo:= ’He is a good student.’;
end;
(4)指针类型(Pointer)
指针是一个表示内存地址的变量。指针类型在任何语言中都比较难理解,也是一种比较灵活的数据类型。用以下形式定义指针变量:type 指针类型标识符=^基类型;
下面列举一个对指针操作的例子,代码如下:
program Point; //指针示例工程
{$Apptype
console}
type
PInt=^Integer; //定义指针类型 var
I,K:Integer;
PI:Pint; //整形指针
P:Pointer; //无类型指针
begin
I:=3;
K:=5;
PI:=@K; //整形指针指向整形数据
writeln(’K=’,PI^);
P:=@I;
K:=Integer(P^); //无类型指针指向整形数据
writeln(’K=’,K);
PI:=P; //指针之间赋值
writeln(’PI^:’,PI^);
readln;
end.
(5)函数和过程类型(Procedural)
Delphi 是面向对象和事件驱动的,因此以前那种自上而下的结构化设计方法已经不适合在Delphi 中编程了。函数和过程是Pascal 语言的两种子程序,它们可以随时被调用。函数执行时有返回值,而过程执行时,是没有返回值的。函数的调用是为了得到一个返回值,调用过程仅仅为了执行某种操作。函数只能出现在表达式中,不能单独使用;过程不能出现在表达式中,仅能以某个语句的形式出现。
函数的使用:函数在调用之前必须先声明。函数声明的语法格式如下:
function 函数名(<形式参数表>):<类型>;
begin
<语句>;
<语句>;
...
<语句>;
end;
函数调用的语法格式为:
<函数名>(<实参表>);
注意:实参表中的各个参数必须用逗号分割,其顺序必须和函数说明的顺序相对应,并且个数相同、类型相符。
过程的使用:过程与函数类似,在调用之前必须进行声明。过程声明的语法格式如下:
proceduce
<过程名>(<形式参数表>)
begin
<语句>
<语句>
...
<语句>
end;
过程调用的语法格式为:<过程名>(<实参表>)
(6)变体类型(Variant)
变体类型能够在运行期间动态地改变类型。变体类型能支持所有简单的数据类型,如整型、浮点型、字符串、布尔型、日期时间、货币及OLE 自动化对象等。
注意:变体类型不能表达Object Pascal 对象。
2.Type类型声明语句
在Object Pascal 中,所有的变量必须是某种特定的数据类型,数据类型决定了它所能包含的数值和可进行的操作。Object Pascal 提供了丰富的预定义数据类型,更重要的是它允许定义自己的类型,这就要用到类型声明语句了。类型也有作用域问题,在程序的Type 区声明的类型可以在整个程序中使用。在某个过程或函数中声明的类型则只能在这个过程或函数中使用。
类型声明语句的格式如下:
type 类型标识符=类型描述;
3.定义变量
变量和常量的区别在于变量在运行期间其值是可以改变的。变量必须明确地指定一个数据类型,而常量是通过等号右边的数值隐含确定的。
变量的类型可以是标准的类型,也可以是自己定义的类型,其语法如下:
var 变量标识符:类型;
4.定义常量
常量的特点是在它运行期间不能被修改,因此对常量的赋值是非法的。Object Pascal 提供了几个预定义的常量,如 True 和 False 等,当然也可以声明自己的常量,其语法如下:
Const 常量标识符=常数;
Object Pascal 的运算符
1.算术运算符:
操作符 操作 操作数据类型 结果类型
+ 加 整型、实型 整型、实型
- 减 整型、实型 整型、实型
* 乘 整型、实型 整型、实型
/ 除 整型、实型 整型、实型
mod 取余 整型 整型
div 整除 整型 整型
2.逻辑运算符;逻辑运算符操作对象和返回值都为布尔型,
not 非 布尔
and 与 布尔
or 或 布尔
xor 异或 布尔
3.比较运算符;比较运算符返回值为布尔型(True 或 False),
= 等于 简单数据类型、指针、集合、字符串或字符串包
<> 不等于 简单数据类型、指针、集合、字符串或字符串包
< 小于 简单数据类型、指针、集合、字符串或 PChar
> 大于 简单数据类型、指针、集合、字符串或 PChar
<= 小于等于 简单数据类型、指针、集合、字符串或 PChar
>= 大于等于 简单数据类型、指针、集合、字符串或 PChar
<= 子集 集合
>= 父集 集合
4.按位运算符
通过按位运算符可以修改一个变量的单独的位。可以进行按位与、或、非、异或,也可以对一个数进行向左(Shl)或向右(Shr)移位操作。
5.运算符优先级
一个表达式中可能有多个运算符,它们的运算是有先后顺序的,不同的运算符在表达式中的优先级如表4-12 所示。
() 括号
+,- 正号和负号
^ 乘方
*,/ 乘和除
+,- 加和减,字符串连接
=,>,<,<=,>=,<> 关系运算符
not 逻辑非
and 逻辑与
or 逻辑或
语句
1.常量声明语句;常量在声明时就被赋予了一个值,在程序执行过程中是不可改变的。像变量一样,常量也有类型。
2.赋值语句—— “=”
3.Goto 语句;Goto 语句可以从程序中的一个地方直接跳转到另一个地方。但是从结构化程序设计的角度来考虑,尽量不要使用 Goto语句。
goto label;//在使用Goto 语句之前,首先要声明标号。标号声明语句如下:
label label1,label2,⋯⋯,labeln;
4.复合语句;首尾使用 Begin 和 End 包括起来的一组语句称为复合语句。复合语句可以嵌套使用,也允许有空的复合语句。
5.If 语句
if <条件> then
<语句>
else
<语句>;
If...Then 语句被认为是单语句,在语句结束时只有一个分号
6.Case 语句;If...Then�Else 语句适合选项较少的情况,如果有很多选项的话利用 If 语句就比较麻烦,在这种情况下,Case 语句就容易多了。Case 语句的语法如下:
case <表达式> of
<数值>:<语句>;
<数值>:<语句>;
else
<语句>;
end;
注意:Case 构造中的任何一个语句都可以是单语句或复合语句。如果需要在某种情况下执行多行代码,必须将它们用Begin�End 括起来。
7.Repeat语句;Repeat 语句会重复执行一行或多行语句,直到某一状态为真。语句以 Repeat 开始,以 Until 结束,其后跟随被判断的布尔表达式。例如:
I:=0; repeat
I:=I+1;
Writeln(IntToStr(I));
until I>5;
执行以上的例子时,会显示1~6 的数字。布尔表达式I>5直到Repeat�Until 程序段结束才会被计算,也就是Repeat 语句至少要执行一次。
8.While语句;While 语句和 Repeat 语句的不同之处在于 While 语句的布尔表达式在循环的开始进行判断。如果表达式的结果为真则执行循环,否则退出循环。
9.For 语句;For 语句内的程序代码会执行一定的次数。它需要一个循环变量来控制循环次数。循环变量的类型可以是整型、布尔型、字符型、枚举型或子界型。
10.Break 语句;在各循环中调用 Break,可以使得程序的执行流程立即跳到循环的结尾。例如程序执行 5 次后跳出循环.
11.Continue 语句;如果想跳过循环中部分代码,并开始下一次循环,可以调用Continue语句。下面的例子在执行第3 次循环时,Continue 后的代码不执行而继续下一次的循环
12.With 语句;使用记录类型的变量时,可以通过 With 语句指定一些语句,这些都是针对某一个变量来说的,这样可以简化代码的输入量。
过程与函数
过程与函数是实现一定功能的语句块,是程序中的特定功能单元。可以在程序的其他地方被调用,也可以进行递归调用。过程与函数的区别在于过程没有返回值,而函数有返回值。
1.过程与函数的定义;过程与函数的定义包括过程原型或函数原型、过程体或函数体的定义。过程定义的形式如下:
procedure ProcedureName(ParameterList); directives;
var
LocalDeclarations;
begin
statements
end;
ProcedureName 是过程名,是有效的标识符。ParameterList为过程的参数列表,需要指明参数的个 数 和 数 据 类 型 。Directives 是一 些 关 于 函 数 的 指 令 字 , 如 果 设 置 多 个 , 应 该 用 分 号 隔 开 。LocalDeclarations 中定义了该函数中需要使用的一些临时变量,通常也称作本地变量。在Begin与End 之间是过程调用时实现特定功能的一系列语句。ParameterList、Directives、LocalDeclarations和Statements 都是可选部分。
函数的定义与过程非常类似,只是使用的保留字不同,而且多了一个返回值类型。具体形式如下:
function FunctionName(ParameterList): ReturnType; directives;
var
LocalDeclarations;
begin
statements
end;
可以将函数需要返回的数值赋值给变量 Result。如果函数体中存在着一些由于判断而产生的分支语句时,就要在每一个分支中设置返回值。通常要根据函数的返回值来确定下一步的操作。注意,这里与Visual C 和 Visual C++不一样,把一个值赋给 Result,函数并不会结束。
2.参数
函数定义时参数列表中的参数称为形参,函数调用时参数列表中的参数称为实参。在定义的函数原型中,多个参数之间用分号隔开,同一类型的参数可以放在一起,以逗号隔开。函数调用的时候,在函数原型中,多个参数之间用逗号隔开。
一般来说,形参列表和实参列表完全匹配是指参数的个数一样,而且顺序排列的数据类型也完全一致。对于普通的函数,如果编译器发现实参的数据类型与形参的数据类型不匹配,会将实参的数据类型进行一次或多次的“提升”,比如把Integer类型转换为Double 类型。可以为过程和函数的参数指定默认数值。
指定默认数值的参数要放在参数列表的后部,而没有指定默认数值的参数要放在参数列表的前部。在函数调用的时候,可以为设置了默认值的参数指定一个新值。在函数体中,各语句使用的是指定的新值,如果没有指定新值,则使用默认值。同样,如果存在多个设置了默认值的参数,只有在前面的参数指定了新值后,后面的参数才可以指定新值。
下面的例子定义了一个 OutputNum 函数,可以将一个浮点数按指定的精度输出。通过这个例子,可以体会函数中参数的使用:
program Project1;
{$APPTYPE
CONSOLE}
uses Sysutils; //为了使用函数Format
function
OutputNum(number:double;n:integer = 5):Boolean; var
Str : string; //浮点数显示输出的内容
begin
if n <= -1 then //小数点后的位数要大于或等于0
begin
Result:=False;
Exit;
//退出显示函数
end
else
begin
//设置显示的格式
Str := Format(’%*.*f’, [10, n, number]);
Result := True ;
Writeln(Str); //显示数据
end;
end;
begin
OutputNum(12.345); //n默认为5
OutputNum(123,3); //参数对数据类型进行升级
//下面一句代码不正确,故屏蔽掉
//OutputNum(123.456789,9.13); //参数对数据类型不能降级
//可以根据函数的返回值确定下一步的操作
if OutputNum(123.456789,-3) = False then
Writeln( ’输出失败。’ ) ;
Readln;
end.
3.过程与函数的调用约定
在调用过程或函数的时候,如果参数列表中具有多个参数,那么参数传递给过程或函数的顺序会对结果产生一定的影响。对于不同的语言,参数传递的顺序是不同的:Pascal 语言是按照从左向右的顺序进行传递的,而C语言是按照从右向左的顺序来传递的。为了确定传递的顺序,可以在过程或函数定义的时候,在Directives部分利用指令字指定传递的顺序。
4.过程和函数的重载
可以在同一个作用范围内给不同的过程或函数取同一个名称,这种现象就叫做重载。这样可以使编程更方便。在重载的情况下,决定使用哪个过程或函数的依据是形参和实参的一致性,即参数个数、参数类型以及它们之间的顺序,不存在一个函数调用满足两个重载函数的情况。另外重载函数必须用指令字Overload 来进行说明,函数的返回值类型不同就不可以作为重载函数的依据。下面的两个函数就是重载函数:
function Average(a:Integer; b:Integer):Double;overload; //求整形数据的平均值
function Average(a:Double; b:Double):Double;overload; //求实数数据的平均值
5.函数的递归调用
在 Object Pascal 中,过程或函数必须先说明再调用。以上规则在递归调用时属于例外情况。所谓递归调用,是指函数 A 调用函数 B,而函数 B 又调用函数 A 的情况,或是指一个函数调用自身的特殊情况。在递归调用中,函数要进行前置,即在函数或过程的标题部分最后加上保留字Forward。
program Project1;
{$APPTYPE CONSOLE}
var
Alpha:Integer;
procedure Test2(var A:Integer);forward;
//Test2被说明为前置过程
procedure
Test1(var A:Integer);
begin
A:=A-1;
if A>0 then
Test2(A); //经前置说明,调用未执行的过程Test2
procedure Test2(var A:Integer); //经前置说明的Test2 的执行部分
begin
A:=A div 2;
if A>0 then
Test1(A); //在Test2 中调用已执行的过程Test1 end;
begin
Alpha := 15; //给Alpha
赋初值
Test1(Alpha); //第1
次调用Test1,递归开始
end.