访问元素的基本原理
Segment := Seg(Buffer^);
Offset := Ofs(Buffer^);
......
_Temp := Ptr(Segment, Offset + (_Index - 1) * AtomSize);
Move(_Temp^, _Val, AtomSize);
Get := @_Val;
......
而Segment和Offset的作用除了可以减少调用函数的时间之外,
还有一个作用就是判断类有没有调用构造函数。
在构造的时候,可以把分配好的空间的段地址和偏移地址,
赋值给Segment和Offset。用这个可以判断构造函数是否被运行。
Function TDynamicArray.Ready : Boolean;
Begin
Ready := (Segment = Seg(Buffer^)) and (Offset = Ofs(Buffer^));
End;
这是我编写的一个类,实现了动态数组,而可分配空间最大只有65535个字节。
但是至少实现了一种访问指针的较为基本的方法。
这个方法十分的不直接,程序代码的可读性非常的差。
Unit DynmcArr;
{Dynamic Array Unit Release Beta 1}
Interface
Uses Base;
Type
TDynamicArray = Object
Public
Constructor TDynamicArray(_AtomSize, _AtomCount : Word; Debug : Boolean);
Function Get(_Index : Word; Var _Val) : Pointer;
Function Put(_Index : Word; Var _Val) : Pointer;
Function Index : Word;
Function GetCurrent(Var _Val) : Pointer;
Function SetCurrent(Var _Val) : Pointer;
Function Prior(Var _Val) : Pointer;
Function Next (Var _Val) : Pointer;
Destructor Free;
Function Ready : Boolean;
Private
Buffer :^Char;
__Index : Word;
AtomSize : Word;
AtomCount : Word;
_Temp :^Char;
Segment : Word;
Offset : Word;
End;
Implementation
Constructor TDynamicArray.TDynamicArray(_AtomSize, _AtomCount : Word; Debug : Boolean);
Var L : Longint;
Begin
AtomSize := _AtomSize;
AtomCount := _AtomCount;
L := _AtomSize;
L := L * _AtomCount;
If (L > $FFFF) then
Begin
Writeln('Dynamic Class Interval Error #001 Memory Overflow!');
Halt(0);
End
else
If (MaxAvail < AtomSize * AtomCount) then
Writeln('Dynamic Class Interval Error #003 Not Enough Memory!')
else
Begin
GetMem(Buffer, AtomSize * AtomCount);
FillChar(Buffer^, AtomSize * AtomCount, 0);
Segment := Seg(Buffer^);
Offset := Ofs(Buffer^);
__Index := 1;
If Debug then
Begin
Writeln('Dynamic Avail Information :');
Writeln('Segment Address :', WordToHex(Segment) : 6, 'H');
Writeln('Offset Address :', WordToHex(Offset) : 6, 'H');
Writeln('Class Avail (Bytes) :', L : 7);
Writeln('Current Index Locate At', __Index:7);
End;
End;
End;
Function TDynamicArray.Get(_Index : Word; Var _Val) : Pointer;
Begin
If Not Ready then
Begin
Writeln('Dynamic Class Interval Error #004 Class Not Initialized!');
Halt(0);
End;
If (_Index > AtomCount) then
Begin
Writeln('Dynamic Class Interval Error #002 Baunds Out Of Index!');
Get := Nil;
Halt(0);
End
else
Begin
_Temp := Ptr(Segment, Offset + (_Index - 1) * AtomSize);
Move(_Temp^, _Val, AtomSize);
Get := @_Val;
End;
End;
Function TDynamicArray.Put(_Index : Word; Var _Val) : Pointer;
Begin
If Not Ready then
Begin
Writeln('Dynamic Class Interval Error #004 Class Not Initialized!');
Halt(0);
End;
If (_Index > AtomCount) then
Begin
Writeln('Dynamic Class Interval Error #002 Baunds Out Of Index!');
Put := Nil;
Halt(0);
End
else
Begin
_Temp := Ptr(Segment, Offset + (_Index - 1) * AtomSize);
Move(_Val, _Temp^, AtomSize);
Put := @_Val;
End;
End;
Function TDynamicArray.Index : Word;
Begin
If Not Ready then
Begin
Writeln('Dynamic Class Interval Error #004 Class Not Initialized!');
Halt(0);
End;
Index := __Index;
End;
Function TDynamicArray.GetCurrent(Var _Val) : Pointer;
Begin
GetCurrent := Get(__Index, _Val);
End;
Function TDynamicArray.SetCurrent(Var _Val) : Pointer;
Begin
SetCurrent := Put(__Index, _Val);
End;
Function TDynamicArray.Prior(Var _Val) : Pointer;
Begin
If (__Index > 1) then Dec(__Index);
Prior := Get(__Index, _Val);
End;
Function TDynamicArray.Next(Var _Val) : Pointer;
Begin
If (__Index < AtomCount) then Inc(__Index);
Next := Get(__Index, _Val);
End;
Destructor TDynamicArray.Free;
Begin
If Not Ready then
Begin
Writeln('Dynamic Class Interval Error #004 Class Not Initialized!');
Halt(0);
End;
FreeMem(Buffer, AtomSize * AtomCount);
End;
Function TDynamicArray.Ready : Boolean;
Begin
Ready := (Segment = Seg(Buffer^)) and (Offset = Ofs(Buffer^));
End;
Begin
End.