在 pascal 中,我敢于清理数组的唯一方法是简单地遍历它并清除它,但效率极低。我不能通过为其分配一个空数组来简单地重新初始化它吗?
program arrays;
var
working, empty : array [1..10] of integer;
begin
working[3] := 5;
working:= empty;
end.
这样做可以吗,这会适得其反吗?
在 pascal 中,我敢于清理数组的唯一方法是简单地遍历它并清除它,但效率极低。我不能通过为其分配一个空数组来简单地重新初始化它吗?
program arrays;
var
working, empty : array [1..10] of integer;
begin
working[3] := 5;
working:= empty;
end.
这样做可以吗,这会适得其反吗?
如果要清除数组,请编写:
working:= empty;
实际上会通过将数组内容复制到...来进行清除,在您的情况下是无效的,因为它是一个全局变量,因此用 0 初始化。empty
working
empty
恕我直言,定义此类全局变量不是一个好习惯。全局变量在大多数情况下都是邪恶的(除非您知道自己在做什么),并且在声明它们用 0 初始化的情况下是没有意义的。
实际上,如果empty
是在栈上初始化的(即var
方法内的a),此时就填充了栈上的任何东西,即一些随机数据。
如果您想快速初始化一个不包含任何引用计数类型(如string
)的数组,您可以编写:
fillchar(working,sizeof(working),0);
如果您的数组包含托管类型,您可以编写:
finalize(workingWithStringInside); // to safely release internal managed types
fillchar(workingWithStringInside,sizeof(workingWithStringInside),0);
这是可能的更快的代码(比变量副本更快),并且听起来是一个更好的选择。
这绝对没问题。代码的语义正是您所需要的。当然,Delphi 编译器会发出代码来执行简单而高效的内存复制。编译器能够做到这一点,因为您有一个固定长度的数组,其元素是简单的值类型。如果 FPC 没有产生非常相似的代码,我会感到惊讶。
即使您的数组包含托管类型(它不包含),赋值运算符也会生成尊重这些托管类型的代码。
作为最后的评论,充满零的数组应该是一个常数。
一种简单的方法是不要在类型中设置变量的长度...并使用 SetLength 为您初始化数组...来自 Delphi 帮助:当 S 是必须初始化的类型的动态数组时,新分配的空间设置为 0 或 nil。
type
TIntArray = Array of Integer;
procedure WorkArrays(var aWorking: array of integer);
begin
if High(aWorking) >= 0 then
aWorking[0] := 1;
if High(aWorking) >= 3 then
aWorking[3] := 5;
end;
procedure WorkArrays2(var aWorking: array of integer);
begin
if High(aWorking) >= 1 then
aWorking[1] := 4;
if High(aWorking) >= 9 then
aWorking[9] := 7;
end;
procedure WorkArrays3(var aWorking: TIntArray);
begin
SetLength(aWorking, 0);
SetLength(aWorking, 4);
aWorking[0] := 1;
aWorking[3] := 5;
end;
procedure WorkArrays4(var aWorking: TIntArray);
begin
SetLength(aWorking, 0);
SetLength(aWorking, 10);
aWorking[1] := 4;
aWorking[9] := 7;
end;
procedure TForm58.ShowArrays(aWorking: array of integer);
var
a_Index: integer;
begin
for a_Index := Low(aWorking) to High(aWorking) do
Memo1.Lines.Add(IntToStr(aWorking[a_Index]));
end;
procedure TForm58.ShowArrays2(aWorking: TIntArray);
var
a_Index: integer;
begin
for a_Index := Low(aWorking) to High(aWorking) do
Memo1.Lines.Add(IntToStr(aWorking[a_Index]));
end;
procedure TForm58.Button1Click(Sender: TObject);
var
a_MyArray: array of integer;
a_MyArray1: TIntArray;
begin
//SetLength(aWorking, 0);
SetLength(a_MyArray, 3);//note this is a Zero based Array...0 to 2
WorkArrays(a_MyArray);//note aWorking[3] will not show...because High is 2...
ShowArrays(a_MyArray);
SetLength(aWorking, 0);
SetLength(a_MyArray, 10);//note this is a Zero based Array...0 to 9
WorkArrays2(a_MyArray);
ShowArrays(a_MyArray);
WorkArrays3(a_MyArray1);
ShowArrays2(a_MyArray1);
WorkArrays4(a_MyArray1);
ShowArrays2(a_MyArray1);
end;