var
X: Real;
I: Integer;
begin
X := A[0];
for I := 1 to N - 1 do
if X < A[I] then X := A[I];
Max := X;
end;
在语句块内部,你可以重复给Result或函数名赋值,只要这个值的类型和函数声明的返回值类型相同即可。当函数的执行结束时,Result或函数名最后被赋予的值当作函数的返回值。比如,
function Power(X: Real; Y: Integer): Real;
var
I: Integer;
begin
Result := 1.0;
I := Y;
while I > 0 do
begin
if Odd(I) then Result := Result * X;
I := I div 2;
X := Sqr(X);
end;
end;
Result和函数名总是表示同一个值,因此
function MyFunction: Integer;
begin
MyFunction := 5;
Result := Result * 2;
MyFunction := Result + 1;
end;
返回值11。但Result和函数名并不是能完全互换的,当函数名出现在赋值语句的左边时,编译器假设它用来跟踪(存储)返回值(就像Result);在任何其它情况下,编译器把它解释为对它的递归调用。而对Result,它可以作为变量用在运算、类型转换、集合构造器、索引以及调用其它例程。
只要启用了扩展语法({$X+}),Result在每个函数中被隐含声明,不要试图重新声明它。
若还没有给Result或函数名赋值,程序就结束了,则函数的返回值没有被定义(
并不是所有的函数都是真正的函数;有些是内置在编译器中的。这种差别通常并不重要,因为内置函数看上去和用起来都像是普通的函数,但是你无法获得内置函数的地址。 undefined
- 81 - )。 )
Procedures and functions
Calling conventions(调用约定)
在声明过程或函数时,你可以使用下面的指示字之一来指明调用约定:register、pascal、cdecl、stdcall以及safecall。比如,
function MyFunction(X, Y: Real): Real; cdecl;
...
调用约定决定了参数被传递给例程的顺序,它们也影响从堆栈中删除参数、传递参数时寄存器的使用,以及错误和异常处理。默认的调用约定是register。
? register和pascal调用从左到右传递参数,也就是说,最左边的参数最早被计算并传递,最右边的
参数最后被计算和传递;cdecl、stdcall和safecall调用从右到左传递参数;
? 除了cdecl调用,过程和函数在返回之前从堆栈中移除参数,而使用cdecl,当调用返回时,调用者
从堆栈中移除参数;
? register调用能使用多达3个CPU寄存器传递参数,而其它调用则全部使用堆栈传递参数; ? safecall调用实现了异常“防火墙”,在Windows下,它实现了进程间COM错误通知。 下面的表格对调用约定进行了总结:
指示字
register
pascal
cdecl
stdcall
safecall 参数顺序 Left-to-right Left-to-right Clean-up 使用寄存器传递参数? No No No
默认的register调用是最有效的,因为它通常避免了要创建堆栈结构(stack frame)(访问公布属性的方法必须使用register);当调用来自C/C++编写的共享库中的函数时,cdecl是有用的;通常,当调用外部代码时,推荐使用stdcall和safecall。在Windows中,系统API使用stdcall和safecall,其它操作系统通常使用cdecl(注意,stdcall比cdecl更有效)。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-23665-57.html
美照再一发