3

Pascal では、あえてアレイをクリーニングする唯一の方法は、単純にアレイを反復処理してクリアすることでしたが、これは非常に非効率的です。空の配列を割り当てて再初期化することはできませんか?

program arrays;
  var
    working, empty : array [1..10] of integer;
begin
  working[3] := 5;
  working:= empty;
end.

これを行っても問題ありませんが、これは裏目に出る可能性がありますか?

4

3 に答える 3

8

配列をクリアしたい場合は、次のように記述します。

working:= empty;

実際には、配列の内容を... にコピーすることにより、クリアを行います。これはグローバル変数であるため、0 で初期化されるため、あなたの場合は voidです。emptyworkingempty

私見では、そのようなグローバル変数を定義することはお勧めできません。グローバル変数はほとんどの場合 (自分が何をしているのかわかっていない限り) 悪であり、それらを 0 で初期化するように宣言する場合は意味がありません。

実際、emptyがスタック上で (つまり、varメソッド内で) 初期化された場合、その時点でスタック上にあるもの、つまりランダム データで埋められます。

参照カウント型 ( など) を含まない配列を高速に初期化したい場合は、次のようstringに記述できます。

fillchar(working,sizeof(working),0);

また、配列にマネージド型が含まれている場合は、次のように記述できます。

finalize(workingWithStringInside); // to safely release internal managed types
fillchar(workingWithStringInside,sizeof(workingWithStringInside),0);

これは可能な限り高速なコード (変数のコピーよりも高速) であり、より適切なオプションのように思えます。

于 2013-08-07T16:53:34.387 に答える
5

これは絶対に問題ありません。コードのセマンティクスはまさに必要なものです。確かに、Delphi コンパイラはコードを発行して、単純で効率的なメモリ コピーを実行します。要素が単純な値型である固定長配列があるため、コンパイラはそれを行うことができます。FPC が非常によく似たコードを生成しなかったとしたら、私は驚くでしょう。

配列にマネージド型が含まれていたとしても (含まれていません)、代入演算子によって、それらのマネージド型を尊重するコードが生成されます。

最後のコメントとして、ゼロでいっぱいの配列は定数でなければなりません。

于 2013-08-07T15:46:18.133 に答える
0

簡単な方法は、型で変数の長さを設定しないことです...そして 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;
于 2013-08-08T16:04:47.497 に答える