每天都有新的发现.
3月5日:
-----------------------
幂的运算符
fp中 a**b
相当于delphi 中pow(a,b)
-----------------------
2进制:%x
8进制:&x
16进制:$x
char型:#x
e.g.
#%1010111
&12356
-----------------------
array of TYPE
e.g.
function sum(A: array of Integer):integer;
var
i:integer;
begin
result:=0;
for i:=0 to high(a) do
inc(result,a[i]);
end;
sum([5, 7, 4, 4]);
return 5+7+4+4=20
-----------------------
一个关于const和type的灵活运用的例子
type
tpoint=record x,y:integer; end;
tdirect=(e,w,n,s);
const
a:tpoint=(x:1;y:2);
d:array[tdirect]of tpoint=((x:1;y:0),(x:1;y:0),(x:1;y:0),(x:1;y:0));
就是这样调用
d[e].x d[w].y
cool!
-----------------------
oj的时候有一个开关ONLINE_JUDGE
如fp中run delphi的语法,而本地用delphi
{IFDEF ONLINE_JUDGE}
{Mode Delphi}
{ENDIF}
再如
{IFNDEF ONLINE_JUDGE}
Assign(Input,'i.txt');
Reset(Input);
Assign(Output,'o.txt');
Rewrite(Output);
{ENDIF}
Main;
{IFNDEF ONLINE_JUDGE}
Close(Input);
Close(Output);
{ENDIF}
表示oj的时候用standard input and output
-----------------------
补充一个c++的神奇的运算符"?="
aa>?=b 等价于 if a>b then a:=b
这在连续求最值时很好用
-----------------------
唉,刚刚学,可惜我一个也看不懂。留着等我能看懂时再说吧。
这是在又一个找到的pascal语法。
OBJECT PASCAL PROGRAMING (WRITED BY C.Y.C ATTENTION SYSTEM DEVELOPMENT CO,.)
1.标记(TOKEN)
1.1 特别符号(Symbols)
字母(Letters) : A..Z , a..z
数字(Digits) : 0..9
十六进位数字(Hex Digits) : 0..9,A..F(OR a..f)
空白(Blank) : ASCII 32
单字元符号:+-*/=<>[].,():;^@{}$#
多字元符号:<=,>=,:=,..,(*,*),(.,.)
1.2 识别字(Identifiers)
表示:常数,型态,变数,程序,函数,程式单元,程式,栏位....
长度:63位内有效,不分大小写
字首:字母,_
识别字不得重复,若有重复必需采 限定识别字 : Unit1.IdentName
1.3 标笺(Label) : 0..9999 or 识别字
1.4 字元字串
'ATTN' ----------- ATTN
'You''ll see' ---- Yoy'll see
'' --------------- 空字串
' ' -------------- 空白字元
'Line 1'#13#10'Line 2' ------ Line 1
Line 2
1.5 注释
{ xxxxxxxx
xxxxxx
xxxxx }
// xxxxxxxx
2.常数宣告 (使用标记 = )
2.1一般常数宣告
CONST
Min = 0;
Max = 100;
Center = ( Max - Min ) Div 2;
Blank = Chr(32);
NumChr = Ord('Z') - Ord('A') + 1;
ErrMsg = 'Out Of Rang';
ErrDtl = 'Out Of Rang' + ':Item 10';
Numeric = [ '0'..'9' ];
Alpha = [ 'A'..'Z','a'..'z'];
AlphNum = Alpha + Numeric;
2.1型态常数(Typed constant)宣告
CONST
MaxInt : Integer = 9999;
FixReal : Real = -0.12;
ListStr : String[4] = 'This';
AA : Pchar = 'abcedf';
Dim : Array[0..1,0..1,0..1] of Integer = (((0,1),(2,3)),((4,5),(6,7)));
{ Dim(0,0,0) = 0 Dim(0,0,1) = 1
Dim(0,1,0) = 2 Dim(0,1,1) = 3
Dim(1,0,0) = 4 Dim(1,0,1) = 5
Dim(1,1,0) = 6 Dim(1,1,1) = 7 }
--------------------------------
TYPE
Trec = record
fl1,fl2 : Integer;
end;
CONST
IntRec : Trec = ( fl1:1;fl2:2);
------------------------------------------
3.型态宣告 (使用标记 = ) : 当宣告一个变数时,必须指明其型态
3.1 例子(1)
TYPE
Trang = Integer;
TNumber = Integer;
TColor = ( Red , Green , Blue );
TCharVal = Ord('A')..Ord('Z');
TtestIndex = 1..100;
TtestValue = -99..99;
TtestList = Array[TtestIndex] of Ttestvalue;
ptestList = ^TtestList; =>指标型态
Tdate = Class
Year : Integer;
Month : 1..12;
Day : 1..31;
Procedure SetDate(D,M,Y:Integer);
Function ShowDate : String;
end;
TMeasureList = Array[1..50] of TMeasuredate;
Tname = String[80]; =>定长度
Tsex = (Male , Female); =>0 1
PpersonData = record
Name , FirstName : Tname;
Age : Integer;
Married : Boolean;
TFather,TChild,TSibling : PPersonData;
Case s: Tsex of =>0和1之间
Maie : ( Bearded : Boolean );
Female : (Pregnant : Boolean );
End;
TPersonBuf = Array[0..Size(TPsersonData) - 1 ] of Byte;
TPeople = File Of TPersonData; =>定type
3.2 简单型态
3.2.1序数型态
(1)整数型态:
基础型态(Fundmental)
Shortint -128..127 8-bit
Smallint -32768..32767 16-bit
Longint -2147483648..2147483647 32-bit
Byte 0..255 8-bit
Word 0.65535 16-bit
通用型态(Generic)
Integer -2147483648..2147483647 32-bit
Cardinal 0..2147483647 32-bit
若16bit
Integer -32768..32767 16-bit
Cardinal 0.65535 16-bit
(2)字元型态
基础型态(Fundmental)
AnsiChar ASCII 1-Byt
WideChar Unicode 2-Byt
通用型态(Generic)
Char ASCII 1-Byt
(3)列举型态(Enumerated Type)
==============================================
TColor = ( Red , Green , Blue );
==============================================
(4)逻辑型态(Boolean Type)
基础型态(Fundmental)
ByteBool 0..1 1-Byt
WordBool 0..1 2-Byt
LongBool 0..1 4-Byt
通用型态(Generic)
Boolean 1-Byt
==============================================
Married : Boolean;
False < True
Ord(False) = 0
Ord(True) = 1
Succ(False)=True
Pred(True)=False
==============================================
(5)子集型态(Subrang type)
==============================================
TtestIndex = 1..100;
==============================================
3.2.2实数型态
型态 有效位数 位元组大小
Real 11-12 6
Single 7-8 4
Douible 15-16 8
ExTended 10-20 10
Comp 19-20 8
Currency 19-20 8
===================================================
例子 Real 6byt 共48 bit
1-1 2-40 41-48
s f e
有效值 v
if ( e > 0 ) and ( e <= 255 ) then
v = (-1)**s * 2 ** (e - 129) * (1.f)
else if e = 0 then v = 0;
===================================================
3.3 字串型态
3.3.1 基础型态(Fundmental)
(1) ShortString 短字串 1-255 (又称pascal string)
(2) AnsiString 长字串 1-2G
(3) PChr Null-Terminated string
3.3.2 通用型态(Generic)
String 32位元时 等於 AnsiString
16位元时 等於 ShortString
===================================================
(1) 字串为一以零为基底的字元阵列(Zero-base character array)
例
-----------------------
TYPE
TStringBuf = Array[0..79] of Char;
const
StringBuf : TStringBuf = 'This is test';
-----------------------
(2) var s : ShortString
Length(s) = Ord(s[0])
(3) 长字串以4-byt指标,指到动态配置之记忆体,没有[0]之长度数值
一个动态记忆体配置之长字串会自动以一空字元(null Character)结束
(4) PChr 以字元阵列来储存,结尾以(null Character)结束,使用指标来管理
(5) PChr型态与String型态在指定叙述上是相容
例:
-----------------------------
var p:pchr;
begin
p := 'this is test';
end;
-----------------------------
Procedure PrintStr(Str:Pchr);
呼叫时可用
PrintStr('This is test');
-----------------------------
3.4 结构型态(Strictured type)
3.4.1 阵列型态(Array type)
TDim1 = Array[0..79] of Char;
TDim2 = Array[1..3,1..10] of Char;
VAR
Dim1 : Tdim1;
I : Integer;
begin
for I := Low(Dim1) to High(Dim1) do
Dim1[I] := #32;
end;
===================================================
3.4.2 记录型态(Record Type)
TYPE
TdateRec = Record
Year : Integer;
Month : 1..12;
Day : 1..31;
end;
何谓变动栏位 ?
3.4.3 集合型态(Set Type)
TYPE
Tmenber = ( Lee , White , Ston );
Tmenbers = Set Of Tmenber;
var Members : Tmenbers;
begin
Menbers := [ White , Ston ];
end;
集合型态不能超过256个可能值
3.4.4 档案型态(File Type)
(1)记录型态档案
TYPE
Temployee = record
name : string[10];
address : string[50];
end;
TemployeeFile = File Of Temployee;
var
EmployeeFile : TemployeeFile;
同 EmployeeFile : File Of Temployee;
(2)文件型态档案
TMyTextFile = TextFile;
var
MyTextFile : TMyTextFile;
or
MyTextFile : TextFile;
ReadText : String;
-----------------------------
AssignFile( MyTextFile , 'c:/MyFile.txt');
Reset( MyTextFile );
While Not Eof( MyTextFile ) do
begin
Readln( MyTextFile , ReadText );
end;
CloseFile( MyTextFile );
注:Rewrite(MyTextFile); 开启唯写
Writeln(MyTextFile , ReadText);
(3)其它型态档案
TBook = File Of Char;
TnumFile = File Of Integer;
3.4.5 类别型态(Class Type)
TDBText = class(TCustomLabel)
private
FDataLink: TFieldDataLink;
procedure DataChange(Sender: TObject);
function GetDataField: string;
function GetDataSource: TDataSource;
function GetField: TField;
function GetFieldText: string;
procedure SetDataField(const Value: string);
procedure SetDataSource(Value: TDataSource);
procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
protected
function GetLabelText: string; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure SetAutoSize(Value: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Field: TField read GetField;
published
property Align;
property Alignment;
property AutoSize default False;
property Color;
property DataField: string read GetDataField write SetDataField;
property DataSource: TDataSource read GetDataSource write SetDataSource;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Transparent;
property ShowHint;
property Visible;
property WordWrap;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
end;
元件之可见性
注-1:同一unit中Private,Protect,Public,published皆同Public
不同unit时其特性不同
Private : 所属unit才有可见性
Protect : 只有继承时才有可见性
Public : 所有uses者皆有可见性
published : 所有uses者皆有可见性,且提供元件设计时之栏位可见性
注-2:若宣告没有注明4P,则表示
3.5 指标型态(Pointer type)
3.5.1 字元指标(character pointer)
在 system unit 中,有下列宣告
TYPE
PAnsiChar = ^AnsiChar;
PWideChar = ^WideChar;
PChar = PAnsiChar;
所以在2.0版中,PChar和PAnsiChar 是一样的
3.5.2 通用指标
TYPE
TMyPointer = Pointer;
通用指标可以被型态转换後来参考
3.6 程序型态(Procedure type)
3.6.1 全域程序指标
TYPE
TStrProc = Procedure( Const s: String );
TMyFunc = Function( X:Integer ) : String;
3.6.2 方法程序指标
TYPE
TNotifyEven = Procedure(Sender :Tobject) of Object;
3.6.3 程序数值
一个程序型态变数可以被指定程序数值
TYPE
TMainForm = Class(TForm)
Procedure ButtonClick(Sender:Tobject);
end;
VAR
MyForm : TMainForm;
MyFunc : TMathFunc;
Function ChgFunc(X:Integer):Integer;Far;
Begin
Result := X + X;
end;
MyFunc := ChgFunc;
X := MyFunc(X);
==========================================
一个程序变数未被指定数值时其数值是 nil,
但未被指定数值之程序或函数不能执行,
故安全之呼叫是
If Assigned(OnClick) Then OnClick(Self);
3.7 变动型态(Variant type)
(1) 变动型态和其它型态一起使用会作自动型态转换 =>使用arrey
Var
V1,V2,V3,V4,V5 : Variant;
I : Integer;
D:Double; 浮点
S:String;
Begin
V1 := 1;
V2 := 1234.5678;
V3 := 'This is test';
V4 := '1000';
V5 := V1 + V2 + V4;
I := V1;
D := V2;
S := V3;
I := V4;
S := V5;
end;
虽然变动型态提供很大弹性,但它耗用更多记忆体,也比静态型态来得慢
(2)变动阵列
var
A : Variant; =>变动型态
I : Integer;
Begin
A := VarArrayCreate([0,4],VarOleStr);
For I := 0 to 4 Do A[I] := 'AAAA';
VarArrayRedim( A , 9 ); =>加大
For I := 5 to 9 Do A[I] := 'BBBB';
end;
4.变数宣告 (使用标记 : ) : 当宣告一个变数时,必须指明其型态
4.1 例子
X,Y,Z : Double;
I,J,K : Integer;
Dig :0..9;
C : Color;
Done,Error : Boolean; =>通常为一个byts
Operater : ( Plus , Munus , Times );
H1,H2 : Set Of Color;
Today : Date;
MyDim : Array[1..10,1..5] Of Double;
4.2 全域变数 : 在程序和函数之外宣告之变数
4.3 区域变数 : 在程序和函数之内宣告之变
4.3 变数初始化值 : MyInt : Integer = 123;
4.4 限定词 :
4.4.1阵列索引 : MyDim[I][J] 同MyDim[I,J]
4.4.2栏位指示词 : MyRec.MyField {在一个with叙述中可以省略栏位指示 参考
4.4.3物件指示词 : form1.Button1.Caption
4.4.4指标和动态变数: p1^,@p1
4.5 变数型态转换
TYPE
TbyteRec = record
Fl1 , Fl2: Byte;
end;
VAR
W : Word;
B : Byte;
Begin
W := 256 * 10 + 128;
B := TbyteRec(W).Fl1;
*** word ─────>换成byte型态
B := TbyteRec(W).Fl2;
end;
With Sender as Mdbedit do =>代上一层型态
Text := 'This is test';
Mdbedit( Sender ).Text := 'This is test';
5.运算式语法
5.1 运算元及运算优先次序
(1)@,not 单运算子运算元 =>@变数住置
(2)*,/,div,mod,and,shl,shr,as 乘除
(3)+,-,or,xor 加减
(4)=,<>,<,>,<=,>=,in,is 关系
5.2 () 有优先运算评量, 由内外之运算优先
5.3 相同优先次序,则由左至右之运算优先
5.4 捷径评量(short-Circuit)
while (I <= Length(S)) and
(S[I] <> ' ') do
Inc(I)
捷径评量严格执行由左至右之运算,一旦运算结果己可知後便停止,可使得
一些原本不合法之运算架构变成可以运算
5.5 运算元分类
5.5.1 数学运算元 : +,-,*,/
div 整数相除之商
mod 整数相除之余数
5.5.2 逻辑运算元 : not , And , Or , Xor , Shl , Shr
5.5.3 字串运算元 : +
S := 'aaaaa' + 'bbbb';
5.5.4 集合运算元 : + , - , *
+ :连集 -:差集 *:交集
5.5.5 关系运算元:=,<>,<,>,<=,>=,in =>in 判断有效值
In : 成员
type
Month = ( Jan , Feb , Mar , Apr , May , Jun , Jul , Aug , Sep , Oct , Nov , Dec );
Spring = set of Feb..Apr..Mar;
Mstr = array[ 0 .. 11 ] of string[ 3 ];
const
CMstr : Mstr = ( 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec' );
var
M : Month;
SSpring : Spring;
begin
SSpring := [ Feb..Apr ];
writeln( 'The Spring Month is : ' );
for M := Jan to Dec do
if M in SSpring then
writeln( CMstr[ Ord( M ) ] );
end;
5.5.6 类别运算元:is , As
if ( Sender is Mbutten ) and
( Mbutten( Sender ).tag <> 0 ) then ...;
with Sender As Mdbedit do
text := 'aaaaaa';
5.5.7 位置运算元:@
5.5.8 指标运算元:^
var
M , N : integer;
P1 , P2 : ^integer; => 指标
begin
M := 6;
P1 := @M; =>@位置
Label1.Caption := 'P1^ = ' + IntToStr( P1^ );
P2 := P1;
N := P2^;
Label2.Caption := 'N = ' + IntToStr( N );
end;
6.叙述语法
6.1 goto
label aa;
var i : integer;
begin
.
.
if (i = 0) then goto aa;
aa:begin
.
.
end;
end;
6.2 if
if ( x > 10 ) and
( y > 5 ) then
z := x + y
else z := 2 * ( x + y );
6.3 case
var
s : string;
r : integer;
begin
if s <> '' then
begin
case s[1] of =>S之第一个BYTE
'1' : r := 1; =>由小到大
'2' : r := 2;
'3' : r := 3;
else r := 4;
end;
end;
6.4 while
While ( i > 0 ) do
begin
x = X + I;
I = I - 1;
end;
while True do
begin
if ( i = 0 ) then break; =>break 中断
x = X + I;
I = I - 1;
end;
6.5 Repeat => 先做再检查
repeat
k:= i mod j;
i := j;
j := k;
until j = 0;
6.6 for
for i := 1 to 10 do
begin
if i = 5 then continue;
x := X + I;
end;
7.程式区块
7.1 单元结构
unit <单元名称>
interface
uses < list of units>;
Implementation
uses < list of units>;
end.
7.2 单元叫用
uses < unitname list>;
unitname 会自动加上延伸档名 .dcu
其它单元己编释过,故不是 include source file 方式
若使用单元有使用到相同变数,必须采限定识别
unit.IdName
7.3 间接单元参考
program prog;
uses unit1;
const a = b;
begin
end.
unit unit1;
interface
uses unit2;
const b = c;
implementation
end.
unit unit2;
interface
const c = 1;
implementation
const d = 2;
end.
7.4 单元间交互参考
允许交互参考,但不能产生循环参考(Circular unit references),若有发生必
须有一单元之uses 放在 implementation 下
program prog;
uses unit1;
const a = b;
begin
end.
unit unit1;
interface
uses unit2;
const b = c;
implementation
end.
unit unit2;
interface
const c = 1;
implementation
uses unit1;
const d = b;
end.
8.程序与函式
8.1 程序: procedure 程序名( 参数;参数..);
label
type
var
procedure
function
begin
end;
例如: Procedure print( pStr : String );
begin
writeln( Pstr );
end;
8.2 函数: function 程序名( 参数;参数..):传回资料型态;
label
const
type
var
procedure
function
begin
end;
例如 function add( n1 , n2 : Integer ) : Integer;
begin
add := n1 + n2;
end;
8.3 传值呼叫与传址呼叫
procedure Add( Var sum : Integer ; n1 , n2 : integer );
begin ---
sum := n1 + n2;
n1 := 0;
n2 := 0;
end;
procedure test;
var
sum , a , b : integer;
begin
a := 100;
b := 200;
add( sum , a , b );
end;
8.3 forward (前置宣告)
前置宣告不须使用在 interface 之公有宣告!,公有宣告形同forword 作用
procedure add( Var sum : integer ;n1 , n2 : integer ); forward;
procedure base;
var sum : integer;
begin
add(sum,4,5);
end;
procedure add ( Var sum : integer ;n1 , n2 : integer );
begin
sum := n1 + n2;
end;
8.4 External (外部函数宣告)
Function MessageBox( Hwnd : Integer ;
text , caption : Pchar;
Flags : Integer ) : Integer ; Stdcall;
external 'User32.dll' Name 'MessageBoxa';
8.5 呼叫惯例
编译器指令 次序 清除 呼叫惯例
register 由左至右 函数 使用暂存器 pascal
pascal 由左至右 函数 使用堆叠 pascal or c
cdecl 由右至左 呼叫者 使用堆叠 pascal or c
stdcall 由右至左 函数 使用堆叠 Windows Api
9.例外处理
9.1 raise( 引发 )
注意-1 : raise 启动一个物件,而不是一个物件,通常呼叫例外类别的 Create
来快速建立
例:SysUtils Execption
constructor Exception.Create(const Msg: string);
begin
FMessage := Msg;
end;
constructor Exception.CreateFmt(const Msg: string;
const Args: array of const);
begin
FMessage := Format(Msg, Args);
end;
--------------------------------------------------
Function StrToIntRange( Var s:string;Min,Max:Longint):Longint;
begin
Result := StrToInt(s);
If ( Result < Min ) or
( result > Max ) then
raise ERangeError.CreateFmt( %d is not within the valid range of %d..%d',
end; [result,Min,Max]);
注意-2 :控制不会从一个raise 叙述中回传,但在例外程式区块中允许再度
引发例外,
9.2 Try ... Except
语法
try
.
.
except
on Errorclass1 do ..;
on Errorclass2 do ..;
on Errorclass3 do ..;
else
;
end;
没有on ... do 之语法
try
.
.
except
end;
例子-1
try
result := sum div num;
except
on EZeroDivide do result := 0;
on EOverFlow do result := 0;
on EMatherror do result := 0;
else
result := 0;
end;
9.3 Try ... Finally
例:
reset(F);
try
processFile(F);
finally
closeFile(F);
end;
9.4 exit , break , continue 与 try .. finally 之运作
例:
procedure TForm1.MButton1Click(Sender: TObject);
var
I : integer;
s : string;
begin
I := 10;
s := '正常结束!';
try
while I <> 0 do
begin
I := I - 1;
if I = 5 then
begin
s := 'exit 结束';
exit;
end;
end;
finally
Showmessage(s);
end;
end;
10.DLL (动态库}
10.1 DLL 特徵
project 使用之单元是采静态连结(Statically Linked),而DLLs 采动态连结
(Dynamically Linked),故Projectl 中并包含DDLs之拷贝
DLLs 可用任何遵守windows DLL 之开发工具来开发或使用,适合多种开发工具
同时开发环境
10.2 DLL 使用
(1) 藉由名称(循序寻找)
Procedure ImportByName; External 'TestLib.dll';
(2) 藉由重新名称
Procedure ImportByNewName;
External 'TestLib.dll' name 'ImportByName';
(3) 藉由序号(找到程式的最快方法)
Procedure ImportByOrdName;
External 'TestLib.dll' Index 1;
(4) Windows Api 之呼叫
Function MessageBox( Hwnd: Integer ; Text,Caption:Pchr
Flags:Integer):Integer;Stdcall;
External 'User32.dll' Name 'MessageBox';
(5)动态库之输入程式单元
(例-1):Delphi 之开发环境中之 uses windows
(例-2):
unit DateTime;
interface
type
TTimeRec = Record
ss : integer;
mi : Integer;
hh : Integer;
end;
type
TDateRec = Record
yy:Integer;
mm:Integer;
dd:Integer;
end;
Procedure SetTime(Var Time:TTimeRec);
Procedure GetTime(Var Time:TTimeRec);
Procedure SetDate(Var Date:TDateRec);
Procedure GetDate(Var Date:TDateRec);
Implementation
Procedure SetTime; External 'DATETIME' index 1;
Procedure GetTime; External 'DATETIME' index 2;
Procedure SetDate; External 'DATETIME' index 3;
Procedure GetDate; External 'DATETIME' index 4;
end;
------------------------------------------------------
program ShowTime;
uses WinCrt , DateTime;
var
Time : TtimeRec;
begin
GetTime(Time);
With Time Do
WriteLn( 'Time is',hh,':',mi,':',ss);
end;
-----------------------------------------------------
(6)DDLs 之动态使用
program ShowTime;
uses WinProcs , WinTypesWinCrt;
type
TTimeRec = Record
ss : integer;
mi : Integer;
hh : Integer;
end;
TGETTime = Procedure( var Time : TTimeRec );
Var
Time : TTimeRec;
Handle : THandle;
GetTime : TGetTime;
Begin
Handle := LoadLibrary('DATETIME.DLL');
if Handle >= 32 then
Begin
@GetTime := GetProcAddress( Handle , 'GETTIME' );
If @GetTime <> nil Then
Begin
GetTime(Time)
With Time do
WriteLn('Time is ',hh,':',mi,':',ss);
end;
FreeLibrary(handle);
end;
end.
10.3 DDLs 之撰写
10.3.1 例子
library minmax;
function Min( X , Y : Integer ) : Integer;
StdCall;
Begin
If X < Y Then Min := X
else Min := Y;
end;
function Max( X , Y : Integer ) : Integer;StdCall;
Begin
If X > Y Then Max := X
else Max := Y;
end;
exports
Min index 1 name Min Resident;
Max index 2 name Max Resident;
Begin
end.
PascalFAQ之语法专题
程序首部的参数Input和Output是什么意思?
它们代表默认输入输出设备,但它们只在老式的Pascal语言中有存在意义。在Borland/Turbo Pascal和Free Pascal中,程序首部不需要任何参数,但为了兼容旧式的Pascal程序,编译器会忽略程序首部的所有参数。
如何获得函数返回值的地址?
在Borland/Turbo Pascal中,只能通过函数名来设置函数返回值,编译器并不提供获取函数返回值地址的方法。虽然也可以通过底层的方法来获得函数返回值的地址,但该方法不适合在信息学奥林匹克中使用。在Free Pascal中,如果使用Turbo Pascal语法,则和Borland/Turbo Pascal一样,如果使用Object Pascal语法,则可以通过使用标识符Result来像变量一样访问函数返回值,@Result返回的就是函数返回值地址。
数值参数、变量参数和常量参数有什么区别?
数值参数、变量参数和常量参数代表三种不同传递方式的子程序参数类型,它们分别用于不同的场合,使用不同的参数类型会产生不同的子程序调用执行速度、栈空间占用量和传递效果。
子程序在调用时会在栈中为数值参数分配一块新的空间,并把实际参数的值赋给数值参数,然后数值参数就可以像局部变量一样使用。子程序结束后,数值参数所占用的栈空间会自动释放,数值参数的值的改变不会影响到实际参数。数值参数可接受的实际参数为:常量、表达式和变量。
子程序在调用时会在栈中为变量参数分配四个字节的空间,并把实际参数的地址赋给这四个字节,对变量参数的访问就是通过该四个字节组成的指针来对实际参数进行访问,其访问速度比数值参数慢一些。子程序结束后,这四个字节的空间就会自动释放,变量参数的值的改变等价于实际参数的值的改变。变量参数可接受的实际参数为:变量。
对于常量参数,子程序在调用时会根据其数据类型和大小来决定是分配一块新的空间来存放实际参数的值还是分配四个字节来存放实际参数的地址,其决定根据与实际参数是否变量无关。常量参数的访问类似于常量,只能获取它的值而不能进行赋值,唯一的例外是可以使用@操作符来获得常量参数的地址。常量参数可接受的实际参数为:常量、表达式和变量。
注意,由于文件类型比较特殊,文件类型的参数只能作为变量参数传递。
如何使两个子程序可以互相调用?
Pascal要求每个标识符在使用前必须预先定义,如果两个子程序要互相调用,那么就至少有一个子程序必须在其实现之前预先声明,即预定义子程序,这可以用保留字forward完成。forward用于预定义子程序,把它放在子程序首部的后面,那么这个子程序首部就预定义了一个子程序,而其具体的实现部分可以在其它地方给出。下面是一个简单的样例:
procedure ProcA; forward;
procedure ProcB;
begin
ProcA;
end;
procedure ProcA;
begin
ProcB;
end;
注意,forward不能用于预定义单元中已在接口部分声明的子程序。