在 Delphi 中,可以创建类型为的数组
var
Arr: array[2..N] of MyType;
N - 1
这是一个从 2 到 N 索引的元素数组。
如果我们改为声明一个动态数组
var
Arr: array of MyType
然后N - 1
通过以下方式分配元素
SetLength(Arr, N - 1)
那么元素将从0索引到N-2。是否可以将它们从2索引到N(比如说)?
在 Delphi 中,可以创建类型为的数组
var
Arr: array[2..N] of MyType;
N - 1
这是一个从 2 到 N 索引的元素数组。
如果我们改为声明一个动态数组
var
Arr: array of MyType
然后N - 1
通过以下方式分配元素
SetLength(Arr, N - 1)
那么元素将从0索引到N-2。是否可以将它们从2索引到N(比如说)?
不,在 Delphi 中,动态数组总是从零开始索引。
是的!通过使用一个技巧!
首先声明一个新类型。我使用记录类型而不是类,因为记录更容易使用。
type
TMyArray = record
strict private
FArray: array of Integer;
FMin, FMax:Integer;
function GetItem(Index: Integer): Integer;
procedure SetItem(Index: Integer; const Value: Integer);
public
constructor Create(Min, Max: integer);
property Item[Index: Integer]: Integer read GetItem write SetItem; Default;
property Min: Integer read FMin;
property Max: Integer read FMax;
end;
定义了记录类型后,您现在需要实现一些代码:
constructor TMyArray.Create(Min, Max: integer);
begin
FMin := Min;
FMax := Max;
SetLength(FArray, Max + 1 - Min);
end;
function TMyArray.GetItem(Index: Integer): Integer;
begin
Result := FArray[Index - FMin];
end;
procedure TMyArray.SetItem(Index: Integer; const Value: Integer);
begin
FArray[Index - FMin] := Value;
end;
声明类型后,您现在可以开始使用它:
var
Arr: TMyArray;
begin
Arr := TMyArray.Create(2, 10);
Arr[2] := 10;
创建具有特定范围的数组实际上是一个简单的技巧,如果您愿意,可以使其更加灵活。或将其转换为类。就个人而言,我只是更喜欢这些简单类型的记录。
模仿这种行为的唯一方法就是使用指针。
type
TMyTypeArr = array [ 0..High(Integer) div sizeof( MyType ) - 1 ] of Mytype;
PMyTypeArr = ^TMyTypeArr;
var
x: ;
A: PMyTypeArr;
begin
SetLength( A, 2 );
x := PMyTypeArr( @A[ 0 ] ); Dec( PMyType( x ), 2 ); // now [2,4> is valid.
x[2] := Get_A_MyType();
end;
请注意,您会丢失任何范围检查,并将其与非零起始数组结合起来是一个非常非常糟糕的主意!
如果你真的需要这个索引,那么你可以编写一个简单的“翻译”函数,它将接收一个从 2 到 N 范围内的索引图,并返回一个从 0 到 N-2 的索引,只需从参数中减去 2 , 例如:
function translate(i : integer) : integer;
begin
result := i - 2;
end;
你可以这样调用你的数组:
array[translate(2)]
当然,您还可以在函数内进行范围检查,也许您可以给它一个更短的名称。
或者更好的是,使用这样的函数包装对数组的整个访问:
function XYZ(i : integer) : MyType;
begin
// Do range checking here...
result := MyArray[i - 2];
end;
希望这可以帮助