6

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まで(たとえば)インデックス付けすることは可能ですか?

4

4 に答える 4

15

いいえ、Delphi では、動的配列は常にゼロからインデックス付けされます。

于 2010-05-01T13:38:18.363 に答える
1

はい!裏技を使って!
最初に新しい型を宣言します。レコードは少し使いやすいので、クラスの代わりにレコード タイプを使用します。

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;

実際には、特定の範囲で配列を作成するのは簡単なトリックであり、必要に応じてより柔軟にすることができます。またはクラスに変換します。個人的には、このような単純なタイプのレコードが好きです。

于 2010-10-27T11:00:36.433 に答える
0

この動作を模倣するためにできる唯一のことは、ポインターを使用することです..

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;  

範囲チェックを失うことに注意してください。ゼロ以外の開始配列と組み合わせることは、非常に悪い考えです!

于 2010-05-02T19:43:10.323 に答える
0

このインデックスが本当に必要な場合は、パラメータから 2 を引くだけで、2 から N の範囲のインデックス数値を受け取り、0 から N-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;

お役に立てれば

于 2010-08-18T20:08:46.453 に答える