例程(routine)是Pascal的一个重要概念,例程由一系列语句组成,例程名是唯一的,通过例程名你可以多次调用它,这样程序中只需要一个例程就够了,由此避免了代码多次重复,而且代码也容易修改维护。从这个角度看,你可以认为例程是一种基本的代码封装机制。
过程与函数Pascal中的例程有两种形式:过程和函数。理论上说,过程是你要求计算机执行的操作,函数是能返回值的计算。
两者突出的不同点在于:函数能返回计算结果,即有一个返回值,而过程没有。两种类型的例程都可以带多个给定类型的参数。看官方文档的说法统一称为了方法
不过实际上函数和过程差别不大,因为你可以调用函数完成一系列操作,跳过其返回值(用可选的出错代码或类似的东西代替返回值);也可以通过过程的参数传递计算结果
下例定义了一个过程、两个函数,两个函数的语法略有不同,结果是完全相同的。
procedureHello;beginShowMessage('Helloworld!');;functionDouble1(Value:Integer):Integer;beginDouble1:=Value*2;;//or,asanalternativefunctionDouble2(Value:Integer):Integer;beginResult:=Value*2;;流行的做法是用Result给函数赋返回值,而不是用函数名,我认为这样的代码更易读。
一旦定义了这些例程,你就可以多次调用,其中调用过程可执行操作;调用函数能计算返回值。如下:
(Ser:TObject);beginHello;;(Ser:TObject);varX,Y:Integer;beginX:=Double(StrToInt());Y:=Double(X);ShowMessage(IntToStr(Y));;代码封装概念
你调用Double1函数时,你不需要知道该函数的具体实现方法。如果以后发现了更好的双倍数计算方法,你只需要改变函数的代码,而调用函数的代码不必改变(尽管代码执行速度可能会加快!)。Hello过程也一样,你可以通过改变这个过程的代码,修改程序的输出
当调用一个现有的Delphi函数、过程或任何VCL方法时,你应该记住参数的个数及其数据类型。不过,只要键入函数或过程名及左括号,Delphi编辑器中会出现即时提示条,列出函数或过程的参数表供参考。
引用参数Pascal例程的传递参数可以是值参也可以是引用参数。值参传递是缺省的参数传递方式:即将值参的拷贝压入栈中,例程使用、操纵的是栈中的拷贝值,不是原始值。
当通过引用传递参数时,没有按正常方式把参数值的拷贝压栈(避免拷贝值压栈一般能加快程序执行速度),而是直接引用参数原始值,例程中的代码也同样访问原始值,这样就能在过程或函数中改变参数的值。引用参数用关键字var标示。
参数引用技术在大多数编程语言中都有,C语言中虽没有,但C++中引入了该技术。在C++中,用符号表示引用;
这种方式其实传递的就是指针,或者称为变量和对象的内存地址
下面是利用引用传递参数的例子,引用参数用var关键字表示:
procedureDoubleTheValue(varValue:Integer);beginValue:=Value*2;;
在这种情况下,参数既把一个值传递给过程,又把新值返回给调用过程的代码。当你执行完以下代码时:
varX:Integer;beginX:=10;DoubleTheValue(X);
x变量的值变成了20,因为过程通过引用访问了X的原始存储单元,由此改变了X的初始值。
通过引用传递参数对有序类型、传统字符串类型及大型记录类型才有意义。实际上Delphi总是通过值来传递对象,因为Delphi对象本身就是引用。因此通过引用传递对象就没什么意义(除了极特殊的情况),因为这样相当于传递一个引用到另一个引用。
常量参数除了引用参数外,还有一种参数叫常量参数。由于不允许在例程中给常量参数赋新值,因此编译器能优化常参的传递过程。编译器会选用一种与引用参数相似的方法编译常参(C++术语中的常量引用),但是从表面上看常参又与值参相似,因为常参初始值不受例程的影响。
例如:如果编译下面Delphi将出现错误:
functionDoubleTheValue(constValue:Integer):Integer;beginValue:=Value*2;//compilererrorResult:=Value;;开放数组参数
与C语言不同,Pascal函数及过程的参数个数是预定的。如果参数个数预先没有确定,则需要通过开放数组来实现参数传递。
一个开放数组参数就是一个固定类型开放数组的元素。也就是说,参数类型已定义,但是数组中的元素个数是未知数。见下例:
functionSum(constA:arrayofInteger):Integer;varI:Integer;beginResult:=0;forI:=Low(A)toHigh(A)doResult:=Result+A[I];;beginSum([1,2]);Sum([1,2,4]);Readln;.类型变化的开放数组参数
除了类型固定的开放数组外,Delphi还允许定义类型变化的甚至无类型的开放数组。这种特殊类型的数组元素可随意变化,能很方便地用作传递参数。
arrayofconst类型的数组就能实现把不同类型、不同个数元素组成的数组一下子传递给例程。如下面Format函数的定义
functionFormat(constFormat:string;constArgs:arrayofconst):string;
上面第二个参数是个开放数组,该数组元素可随意变化。如你可以按以下方式调用这个函数:
N:=20;S:='Total:';:=Format('Total:%d',[N]);:=Format('Int:%d,Float:%f',[N,12.4]);:=Format('%s%d',[S,N*2]);参数默认值可以在过程或函数的声明部分(形参列表)为参数指定一个默认值,只允许对有类型的常量参数和值参数指定默认值
格式如下:
修饰符参数名称:参数类型=默认值;
代码示例:
procedurefillArray(a:Integer;value:Integer=0);begin//此处省略部分代码;//调用beginfillArray(100);fillArray(100,1);;