Delphi SetLength пользовательская индексация

В 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 (говорят) вместо этого?

6
задан Andreas Rejbrand 1 May 2010 в 13:24
поделиться

3 ответа

Нет, в Delphi динамические массивы всегда индексируются с нуля.

15
ответ дан 8 December 2019 в 14:41
поделиться

Единственное, что вы можете сделать, чтобы имитировать это поведение, - это использовать указатели.

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;  

Обратите внимание, что вы теряете любую проверку диапазона, и комбинировать это с ненулевыми начальными массивами - ОЧЕНЬ ОЧЕНЬ плохая идея!

0
ответ дан 8 December 2019 в 14:41
поделиться

Если вам действительно нужна такая индексация, то вы можете написать простую функцию "перевода", которая будет получать индекс в диапазоне от 2 до N и возвращать индекс от 0 до N-2, просто вычитая 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;

Надеюсь, это поможет

.
0
ответ дан 8 December 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: