delphi课程设计_第1页
delphi课程设计_第2页
delphi课程设计_第3页
delphi课程设计_第4页
delphi课程设计_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第4章 过程与函数,本章着重讲解Delphi过程和函数的声明与实现,介绍参数类型与传递方式。最后讨论过程和函数的使用。 4.1 过程与函数的编写 4.2 参数 4.3 过程与函数的使用 4.4 本章小结,第4章 过程与函数,过程和函数统称为例程(routines),它们包括程序头、声明和一段可以被程序中不同位置调用的语句块。它们明显的区别在于:函数(function)是执行时返回值的例程,过程(procedure)是不返回值的例程。 使用过程和函数可以降低程序的复杂性。通过使用恰当命名的过程和函数,使编写代码的工作可以划分成有限的部分,并避免重复编写雷同的代码。 过程和函数的设计以功能单一,代

2、码短小为佳。对于它们的“理想”长度并没有一个公认的标准,但是,从软件开发的经验出发,都倾向于“短短益善”。,4.1 过程与函数的编写,4.1.1 过程 4.1.2 函数 4.1.3 指示字* 4.1.4 程序型类型*,4.1 过程与函数的编写,编写过程或函数时,首先需要为其指定名称、接受参数的个数及类型。对于函数,还要指定返回值的类型,这部分声明有时叫做原型(prototype)、标题(heading)或头(header)。然后才可以编写局域声明块,用于声明过程或函数中需要使用的局域变量,最后开始编写代码块,用于过程或函数随时被调用时的执行,这部分称为例程的主体(body),即程序体。,4.1

3、.1 过程,编写过程是为了将一个程序分成更小的、更易于控制的语句块。过程的声明是由过程头和附属部分组成的,其中过程头的语法是: Procedure 标识符(参数列表) 附属部分的语法如下: 调用约定;指示字 procedure是保留字,过程标识符可以是任何合法的标识符,以后就是通过这个标识符调用该过程。一个过程可以有参数,如果有多个参数,参数之间用分号隔开;也可以没有参数,对于后者,过程标识符后直接跟分号。声明过程的示例如下: Procedure ThreeParamsProc (Param1,Param2:Integer;param3:Real);,4.1.1 过程,声明了一个过程后,就应当

4、在程序单元的Implementation部分实现这个过程,实现过程的语法是这样的: Procedure 过程标识符(形参); Begin 过程的执行体 End;,4.1.1 过程,正如前所述,过程还可以有自己的局域变量,它紧接在过程名后面声明,这样的程序示例如下: Procedure ThreeParamsProc(param1,param2:integer;param3:real); Var i,j,K:integer; /声明三个局域变量 Begin i := Param1; j := Param2; k := Trunc(Param3); End;,4.1.2 函数,声明函数的语法跟过程

5、的声明有相似之处,不同的是函数头,声明函数的语法为: Function 函数标识符(参数列表):返回值; 示例如下: Function MyFunc(Param1,param2:Integer;param3:Real) :Integer; 上述例子中声明了一个函数,函数名是MyFunc,有三个参数,前两个是整数类型,第三个是实数类型,返回类型是整数类型。,4.1.2 函数,实现函数的语法是这样的: function ThreeParamsProc (param1, param2 : Integer; param3 : Real) : integer; Begin 函数执行体 End;,4.1.

6、2 函数,和过程一样,函数可以有参数,可以没有参数。要注意的是:函数必须指定返回类型。Delphi的函数可以返回任何数据类型(除了文件类型)。另外,还要注意,在过程的定义中,过程的执行体可以是空的,但函数的执行体至少要有一个语句,那就是必须返回一个数值。如果程序代码中没有给出函数的返回值,那么,在程序编译时,Delphi将给出一个警告信息。,4.1.2 函数,函数的返回值 函数可以包含任何可执行代码,可以完全像过程一样。但是在Delphi中函数的返回值必须在函数返回前被计算并赋给函数。Delphi语言的函数返回方法跟其他语言中函数通过Return语句实现返回值不同,在Delphi中返回值是通过

7、对函数标识符赋值的方式实现的。利用赋值语句将返回值赋给左边的函数名,编译程序就默认这是结果值。程序示例如下: Function PlusTwo(Number:Integer) : Integer; Begin ./ 其它可执行代码 PlusTwo := Number * 2; End; 上面的程序将传入的参数Number乘以2,并将相乘后的结果作为返回结果。,4.1.2 函数,Result变量 Delphi自动在函数内部隐含了一个局域变量,这就是Result变量。我们不必显式地声明Result,它被默认为与函数结果有相同的类型,对Result的赋值相当于对函数名赋值,也就是说相当于返回一个数值

8、。还是上面的范例,程序代码可以调整为如下样子: Function PlusTwo(Number:Integer) : Integer; Begin ./ 其它可执行代码 Result := Number * 2; End;,4.1.2 函数,Result是个真正的变量,可以在函数中被引用在赋值语句的任一边。如果Result仅仅是为了返回一个数值,那它也没有什么意义,Result变量的关键在于它能出现在赋值语句的右边,而如果函数名出现在赋值语句的右边,则意味着递归调用,另外对Result变量赋值不一定就是从函数返回,这跟对函数名赋值也不同,程序示例如下: Function Square(x:in

9、teger) : integer; Begin Result := x; Result := Result *x; end; Exit可以出现在任何过程和函数的块中。Exit过程在其出现的位置停止例程的执行,并立即将程序控制交回例程被调用的执行点处。,4.1.3 指示字*,Delphi对于函数的声明和调用提供了更多的支持。在使用时,Delphi提供了几个特殊的指示字,以区分默认的声明和调用方式。 1. 调用约定指示字 声明过程或函数时,可以指定调用约定(calling convention)。指定调用约定可以使用的指示字包括register、pascal、cdecl、stdcall以及safe

10、call。 2. External指示字 External 这个指示字允许从程序中调用分别编译的例程,表明过程或函数是外部的。外部例程可以来自对象文件(object files,即.obj文件)或动态可加载库(dynamically loadable libraries,即.dll文件)。,4.1.3 指示字*,3.Forward指示字 当使用一个标识符(任何类型)时,编译器必须已经知道该标识符指的是什么。为此,通常需要在例程使用之前提供一个完整的声明。 一般情况下,当调用一个过程或函数时,被调用的过程或函数必须是在Type区已声明的。然而在某些情况下可能做不到这一点,此时使用Forward指

11、示字可以让编译器查找过程或函数的定义。要预先声明一个过程或函数,而且只给出它的名字和参数,不列出其实现代码,需要在句尾加forward关键字。,4.1.4 程序型类型*,Delphi的另一个独特功能是可定义程序型类型(procedual type)。程序型类型属于语言的高级功能,它允许将过程和函数的引用赋值给变量或传递给其他过程和函数。程序型类型不是很常用。,4.2 参数,参数是过程、函数间传递和交换数据的基础。大多数过程和函数头都包括一个参数列表(parameter list)。参数列表是一个参数声明序列,声明之间以分号隔开,参数列表由圆括号封装。每个声明是一个参数名序列,参数名之间以逗号隔

12、开,大多数情况下跟随一个冒号(:)和一个类型标识符,某些情况下还跟随一个等号(=)和一个缺省值。参数名必需是有效标识符。例如: Funcion Add(x,y:Real):real; Procedure Translate(var S:string;X:Integer);,4.2.1 参数类型,1. 值参数 大多数参数是值参数(缺省参数)或变量参数(var参数),其中值参数最常用。值参数是一种传递数值副本的参数,当调用过程或函数时,程序为实参的值复制一个副本,由值参数来传递。,4.2.1 参数类型,1. 值参数的示例 Procedure SubProc(Value:integer); Begi

13、n Value:=100; End; Porcedure MainProc; Var X:integer; Begin X:=1; SubProc(X); /值参数对过程、函数而言是局部变量,修改值参数不会 /直接改变参数的值。 ShowMessage(IntToStr(X); End; 具体参见程序ValueParameterExample.dpr,4.2.1 参数类型,2. 变量参数 变量参数相当于一个指针,该参数在传递时传递的不是实参的值的副本,而是指向实参值的一个引用。这样当参数在过程或函数中被改变时,实参的值也相应改变,在过程或函数中对形参的引用实际上就是对实参自身的引用。,4.2.

14、1 参数类型,变量参数的示例: Procedure SubProc(var Value:integer); Begin Value:=100; End; Porcedure MainProc; Var X:integer; Begin X:=1; SubProc(X); /X作为变量参数传递给SubProc过程。ShowMessage(IntToStr(X); End; 注:本例中SubProc(200)非法 具体参见VARParameterExample.dpr,4.2.1 参数类型,3. 常量参数 常量参数与其他参数的区别在于,常量参数是只读的,也就是说不允许在过程或函数中改变常量参数的值

15、,对常量参数赋值是非法的,并且不允许把常量参数再作为实参传递给另一个过程或函数。例如: Procedure MyProc(const Value:integer); Begin Value:=3; AnotherProc(Value); End; 以上程序包含了不合法代码。,3. 常量参数 常量参数与值参数一样都是传值的参数,即常量参数的值只是复制输入的参数值。具体参见ValueParameterExample.dpr function repeatStr(const str:string;n1:integer):string; var ReStr:string; nLoop:integer;

16、 begin /str:=I love this game; ReStr := ; for nLoop:=1 to n1 do ReStr:=ReStr + str; Result:=ReStr; end; procedure TForm1.Button1Click(Sender: TObject); var paraStr:string;/具体参见ValueParameterExample.dpr begin paraStr:=SKY; showMessage(调用前paraStr= +paraStr); showMessage(repeatStr(paraStr,3); / showMes

17、sage(repeatStr(OTO,3); /也可直接带入值 showMessage(调用后paraStr= +paraStr); end;,4.2.1 参数类型,4. out参数 一个out参数就象一个变量参数,它传递的也是引用。然而,对于out参数,引用变量的初始值被其传递到的例程丢弃。out参数仅用于输出,也就是说,它告诉函数或过程在哪里存储输出,而不提供任何输入。例如: Procedure GetInfo(out Info:string); 调用时: Var MyRecord:string GetInfo(MyRecord);,program Project2; /具体参见OutPa

18、raExample.dpr $APPTYPE CONSOLE Uses SysUtils; procedure TestInteger(out i:integer); begin i:=i+1; end; procedure TestString(out s:string); Begin s:= s+xiaoT; end; var vi:integer; vs:string; begin vi:=2; TestInteger(vi); writeln(Inttostr(vi); vs:=Hello; Teststring(vs); writeln(vs); readln; end.,4.2.1

19、 参数类型,4. out参数 变量参数(Var参数)和输出参数(Out参数)的共同点: 它们传递的都是引用(地址),即不会给变量再分配新的内 存。 区别:Var参数对应的变量,其值的改变均来自于程序的执行,即代码编写者对其值具有完全的控制;而Out参数对应的变量,在其作为Out参数传递给某一例程时,在程序控制交给例程之前,变量占用的内存在有些情况下被释放了,即变量的值的改变还收到自动初始化的影响。这里的“释放内存”是指含有数据地址指针的情况(字符串,记录类型等),而对于整数、实数等简单类型,则不会有任何操作。,4.2.2 无类型参数*,所谓无类型参数,就是在过程或函数声明和定义时不指定参数的数

20、据类型,程序代码示例如下: Procedure MyProc (Var Value); 上例中,Value参数没有指定数据类型,但前面必须加var、const或out,加var、out表示参数的值是可以改变的,加const表示参数是只读的。如果没有使用这些参数类型,则表示为值参数,而值参数必须指定类型。,4.2.3 缺省参数,Delphi允许在过程或函数头指定参数的缺省值。这样调用时该参数可以加上,也可以省略。缺省值仅允许用于有类型的值参数和常量参数。要提供缺省值,需要在参数声明的末尾使用等号“=”,并跟随一个与参数类型赋值兼容的常量表达式。,4.2.3 缺省参数,缺省参数使用主要规则是:调用

21、时只能从最后一个参数开始进行省略。也就是说,如果要省略一个参数,就必须省略它后面所有的参数。 缺省参数的使用规则还包括: 带缺省值的参数必须放在参数表的最后面。 缺省值必须是常量。显然,这限制了缺省参数的数据类型,例如动态数组的缺省参数值只能是nil;至于记录类型,则根本不能用作缺省参数。 缺省参数必须通过值参数或常量参数传递。引用参数 var不能有缺省值,4.2.3 缺省参数,例如: Procedure MyProc(Str:String;Value:integer=0); 下面两个调用过程是等价的: MyProc(Happy); MyProc(Happy,0);,4.3 过程与函数的使用,

22、前面我们详细介绍了过程、函数以及它们的参数,接下来,重点介绍如何使用过程和函数,分两个方面讲解:一是过程和函数的调用,另一个是过程和函数的重载,4.3.1 调用过程和函数,调用过程或函数时,程序控制将由调用点传递给例程体。可以通过使用例程声明的名称或者通过使用指向例程的程序型变量来实现调用。,4.3.1 调用过程和函数,调用过程或函数时应切记: 用于传递有类型的常量参数和值参数的表达式,必需与相应的形式参数是赋值兼容的。 用于传递变量参数和out参数的表达式,其类型必需与相应形式参数的类型等同,除非形式参数是无类型的。 只有可赋值的表达式可以被用于传递变量参数和out参数。 如果过程或函数的形

23、式参数是无类型的,那么数字和含数值的真实常量都不能作为实际参数传递。 调用使用了缺省参数值的过程或函数时,跟随在第一个接受缺省值之后的所有实际参数,都必需使用缺省值;形如MyFunc( , ,tempVar)的调用是不合法的。,4.3.1 调用过程和函数,调用函数的例子: ReturnValue:=MyFunction(); If MyFunction()10 then,4.3.2 过程与函数的重载,可以在相同的作用域(即为可访问范围,后面章节有详细介绍)中以相同的名称声明多个(一个以上)例程,称为重载(overloading)。重载的例程必需以指示字overload声明,并且参数列表必需有所

24、区别。重载的思想其实很简单:编译器允许使用同一名称定义多个参数不同的函数或过程,而实际上,编译器是通过检测参数来确定需要调用的例程(它们是不同的例程)。,4.3.2 过程与函数的重载,重载的举例: Function Divide(x,y:real):Real;overload; Begin result:=x/y; End; Function Divide(x,y:integer):Integer;overload; Begin result:=x div y; End;,4.4 本章小结,过程和函数统称为例程,它们包括程序头、声明和一段可以被程序中不同位置调用的语句块。它们明显的区别在于:函数是执行时返回值的例程,过程是不返回值的例程。 使用过程和函数可以降低程序的复杂性,提高代码的重用性。过程和函数的设计以功能单一,代码短小为佳。 Delphi中函数返回值是通过对函数标识符或Result变量赋值的方式实现的。,4.4 本章小结,Delphi提供了几个特殊的指示字,以区分默认的声明和调用方式。常用的指示字包括各种调用约定指示字、调用外部例程的External指示字、用于预先声明的Forward指示字等。 所谓过程或函数的引用本质上是一个程序指针,它指向该过程或函数的地

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论