Arrays 运行时索引为负的数组
我有点卡住了。我想要一个这样的数组: 整数的数组[-3..Index,1..otherIndex]代码> 但我还需要在运行时根据给定的参数初始化这个数组。 因此,启动时未设置Arrays 运行时索引为负的数组,arrays,delphi,Arrays,Delphi,我有点卡住了。我想要一个这样的数组: 整数的数组[-3..Index,1..otherIndex] 但我还需要在运行时根据给定的参数初始化这个数组。 因此,启动时未设置索引和其他索引 我想我不能在动态数组中初始化负索引,但我如何在运行时初始化这样一个静态数组?将数组包装在记录中 type TMyArray = record private FData: array of integer; ..... public class function New(Siz
索引
和其他索引
我想我不能在动态数组中初始化负索引,但我如何在运行时初始化这样一个静态数组?将数组包装在记录中
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
对中,您将3添加到x
索引中/从y
索引中减去1,从而访问从0开始的实际数组
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
,则必须自己进行清理
但是,可以使用记录技巧中的接口添加自动清理/析构函数,请参见和 如果您有一个下限(例如-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;
从计算角度来看,这是非常理想的(没有过程调用),但在中也有点危险,因为没有启用范围检查。分配一个大小合适的动态数组,并将其包装在执行索引计算的代码中。或者使用GetMem使其更简单。此声明遵守常量表达式规则(请参阅文档)。当我尝试使用新方法访问FData时,我会得到一个“E2124”。记录类型中不允许使用默认指令,至少我的编译器是这么说的。@Vollmilchbb:新函数应编码为SetLength(Result.FData,FSizeX*FSizeY)。由于它是一个静态函数,因此没有“Self”,函数结果是需要分配的新数组。函数TMyArray.GetItem(x,y:integer):integer;开始结果:=FData[(x+3)+(y-1)*FSizeX];结束代码>使编译器有更多机会成功优化Isuspect@Vollmilchbb,记录中不允许使用默认的。我刚才跳过了一个代码>。有许多更干净的选项不需要函数调用