Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  115

•  TDictionary Custom Sort  3 304

•  Fast Watermark Sources  3 055

•  3D Designer  4 807

•  Sik Screen Capture  3 304

•  Patch Maker  3 522

•  Айболит (remote control)  3 623

•  ListBox Drag & Drop  2 982

•  Доска для игры Реверси  81 497

•  Графические эффекты  3 909

•  Рисование по маске  3 218

•  Перетаскивание изображений  2 602

•  Canvas Drawing  2 724

•  Рисование Луны  2 548

•  Поворот изображения  2 157

•  Рисование стержней  2 156

•  Paint on Shape  1 561

•  Генератор кроссвордов  2 220

•  Головоломка Paletto  1 760

•  Теорема Монжа об окружностях  2 205

•  Пазл Numbrix  1 678

•  Заборы и коммивояжеры  2 049

•  Игра HIP  1 274

•  Игра Go (Го)  1 220

•  Симулятор лифта  1 465

•  Программа укладки плитки  1 211

•  Генератор лабиринта  1 537

•  Проверка числового ввода  1 346

•  HEX View  1 484

•  Физический маятник  1 351

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Шаблон массива переменной длины



Автор: Ed Jordan

Может ли кто мне подсказать как динамически создать массив записей и получить доступ к отдельным элементам?

Определите тип массива, которым может содержать максимальное количество записей, затем определите тип, являющийся указателем на массив. Идея заключается в том, чтобы не создавать экземпляр самого большого массива; а вместо этого использовать указательный тип и GetMem для распределения памяти для необходимого вам количества записей.

Я разработал то, что я называю шаблоном массива переменной длины "для бедных людей"...


unit %s;

{ -----------------------------------------------------------

ШАБЛОН МАССИВА ПЕРЕМЕННОЙ ДЛИНЫ

Вы можете использовать этот шаблон для создания массива
переменной длины любого типа данных.

Для того, чтобы превратить шаблон с модуль, прогоните его
через текстовый процессор, выполните во всем файле операцию
поиска/замены для замены знака процента на ваш тип данных.
----------------------------------------------------------- }

interface

const

  %MaxCapacity = High(Cardinal) div SizeOf(%);

type

  T%Index = 0..%MaxCapacity - 1;

  T%s = array[T%Index] of %;
  P%s = ^T%s;

function %sSize(Capacity: T%Index): Cardinal;
function Get%s(Capacity: T%Index): P%s;
function Resize%s(var P: P%s;

  OldCapacity, NewCapacity: T%Index): P%s;
procedure Free%s(var P: P%s; Capacity: T%Index);

implementation
uses SysUtils;

function %sSize(Capacity: T%Index): Cardinal;
begin

  Result := Capacity * SizeOf(%);
end;

function Get%s(Capacity: T%Index): P%s;
begin

  GetMem(Result, %sSize(Capacity));
end;

function Resize%s(var P: P%s;

  OldCapacity, NewCapacity: T%Index): P%s;
begin

  ReAllocMem(P, %sSize(OldCapacity), %sSize(NewCapacity));
end;

procedure Free%s(var P: P%s; Capacity: T%Index);
begin

  FreeMem(P, %sSize(Capacity));
  P := nil;
end;

end.

Приведенный выше модуль определяет тип массива и тип-указатель на массив, далее я приведу четыре полезные подпрограммы для работы с ним.

Вот модуль, использующий после операции поиска и замены (см. выше) тип записи 'MyRecord', содержащий также определение этой записи. Поскольку "MyRecords" было очень длинным для имени модуля, я укоротил его. Имейте в виду, что PMyRecords - тип вашего переменного массива, если вы используете этот модуль.


unit MyRecs;
interface

type

  MyRecord = record
    AnInt: Integer;
    AString: string[10];
  end;

const

  MyRecordMaxCapacity = High(Cardinal) div SizeOf(MyRecord);

type

  TMyRecordIndex = 0..MyRecordMaxCapacity - 1;

  TMyRecords = array[TMyRecordIndex] of MyRecord;
  PMyRecords = ^TMyRecords;

function MyRecordsSize(Capacity: TMyRecordIndex): Cardinal;
function GetMyRecords(Capacity: TMyRecordIndex): PMyRecords;
function ResizeMyRecords(var P: PMyRecords;

  OldCapacity, NewCapacity: TMyRecordIndex): PMyRecords;
procedure FreeMyRecords(var P: PMyRecords; Capacity: TMyRecordIndex);

implementation
uses SysUtils;

function MyRecordsSize(Capacity: TMyRecordIndex): Cardinal;
begin

  Result := Capacity * SizeOf(MyRecord);
end;

function GetMyRecords(Capacity: TMyRecordIndex): PMyRecords;
begin

  GetMem(Result, MyRecordsSize(Capacity));
end;

function ResizeMyRecords(var P: PMyRecords;

  OldCapacity, NewCapacity: TMyRecordIndex): PMyRecords;
begin

  ReAllocMem(P, MyRecordsSize(OldCapacity),
    MyRecordsSize(NewCapacity));
end;

procedure FreeMyRecords(var P: PMyRecords; Capacity: TMyRecordIndex);
begin

  FreeMem(P, MyRecordsSize(Capacity));
  P := nil;
end;

end.

Наконец, вот пример использования массива переменной длины. Помните, что указатель должен использоваться с символом "^"...


procedure TForm1.Button1Click( Sender: TObject );
var
  P: PMyRecords;
begin
  P := GetMyRecords( 10 );
  try
    P^[ 0 ].AnInt := 2001;
    P^[ 0 ].AString := 'Космическая одиссея';
  finally
    FreeMyRecords( P, 10 );
  end;
end;








Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте