我有点卡住了。我想要一个像这样的数组:
Array [-3..Index, 1..otherIndex] of Integer;
但是我还需要根据给定的参数在运行时初始化这个数组。
因此,Index
和otherIndex
未设置为开始。
我认为我无法在动态数组中初始化负索引但是如何在运行时初始化这样的静态数组呢?
答案 0 :(得分:4)
将数组包装在记录中。
type
TMyArray = record
private
FData: array of integer;
.....
public
class function New(Size1, Size2: cardinal): TMyArray; static;
function Free; //only needed if you utilize GetMem.
property Item[x, y: integer]: integer read GetItem write SetItem; default;
end;
在New
函数中,您使用SetLength来初始化数组
SetLength(Result.FData, SizeX*SizeY)
。
在GetItem
/ SetItem
对中,您从x
索引中添加3到y
索引/减1,从而访问从0开始的实数数组。 / p>
<强> GetMem例程强>
另一种方法是使用GetMem分配一块内存
请注意,GetMem 不会将其内存归零,因此如果要对阵列进行零初始化,则必须调用ZeroMemory
来清理缓冲区。
GetItem
然后看起来像:
{$pointermath on}
TMyArray = record
private
FData: PInteger;
FSizeX, FSizeY: cardinal; //The size of the array.
.....
//You can use the same code for dynarray and GetMem.
function TMyArray.GetItem(x,y: integer): integer;
begin
//Inc(x,3); Dec(y,1);
Result := FData[(x+3)+(y-1)*FSizeX];
end;
由于Item
是默认属性,因此您只需编写i := MyArray[-3,2];
<强>清理强>
如果你使用动态数组,当记录超出范围时,Delphi会自动为你清理内存
如果您使用GetMem
,则必须自行清理。
答案 1 :(得分:0)
如果您有下限(例如-high(smallint)),您可以执行以下操作:
type
TNegIntArr = Array[-High(SmallInt)..High(SmallInt)] of Integer;
PNegIntArr = ^TNegIntArr;
procedure use(numNeg : integer; arrLen : integer);
var buf : TIntegerDynArray;
arr : PNegIntArr ;
begin
SetLength(buf, arrLen);
arr := @buf[numNeg];
dec(PByte(arr), Cardinal(@arr ^[0]) - Cardinal(@arr^[Low(TNegIntArr)]);
// you can now savely access the array:
for counter := -numNeg to arrLen - numNeg - 1 do
arr^[counter] := counter;
end;
从计算的角度来看,这是非常优化的(没有过程调用),但由于没有启用范围检查,因此也有点危险。