Вот несколько функций для операций с двухмерными массивами. Самый простой путь для создания собственной библиотеки. Процедуры SetV и GetV позволяют читать и сохранять элементы массива VArray (его Вы можете объявить как угодно). Например:
type
VArray: array[1..1] of double;
var
X: ^VArray;
NR, NC: Longint;
begin
NR := 10000;
NC := 100;
if AllocArray(pointer(X), N * Sizeof(VArray)) then
exit;
SetV(X^, NC, 2000, 5, 3.27); { X[2000,5] := 3.27 }end;
function AllocArray(var V: pointer; const N: longint): Boolean;
begin{распределяем память для массива V размера N}try
GetMem(V, N);
except
ShowMessage('ОШИБКА выделения памяти. Размер:' + IntToStr(N));
Result := True;
exit;
end;
FillChar(V^, N, 0); {в случае включения длинных строк заполняем их нулями}
Result := False;
end;
procedure SetV(var X: Varray; const N, ir, ic: LongInt; const value:
double);
begin{заполняем элементами двухмерный массив X размером ? x N : X[ir,ic] := value}
X[N * (ir - 1) + ic] := value;
end;
function GetV(const X: Varray; const N, ir, ic: Longint): double;
begin{возвращаем величины X[ir,ic] для двухмерного массива шириной N столбцов}
Result := X[N * (ir - 1) + ic];
end;
Раздел 2:
Самый простой путь - создать массив динамически
Myarray := GetMem(rows * cols * sizeof(byte,word,single,double и пр.)
сделайте функцию fetch_num типа
function fetch_num(r,c:integer) : single;
result := pointer + row + col*rows
и затем вместо myarray[2,3] напишите
myarray.fetch_num(2,3);
поместите эти функции в ваш объект и работа с массивами станет пустячным делом. Я экспериментировал с многомерными (вплоть до 8) динамическими сложными массивами и эти функции показали отличный результат.
Раздел 3
Вот способ создания одно- и двухмерных динамических массивов:
(*
--
-- модуль для создания двух очень простых классов обработки динамических массивов
-- TDynaArray : одномерный массив
-- TDynaMatrix : двумерный динамический массив
--
*)unit DynArray;
interfaceuses
SysUtils;
type
TDynArrayBaseType = double;
const
vMaxElements = (High(Cardinal) - $F) div sizeof(TDynArrayBaseType);
{= гарантирует максимально возможный массив =}type
TDynArrayNDX = 1..vMaxElements;
TArrayElements = array[TDynArrayNDX] of TDynArrayBaseType;
{= самый большой массив TDynArrayBaseType, который мы может объявить =}
PArrayElements = ^TArrayElements;
{= указатель на массив =}
EDynArrayRangeError = class(ERangeError);
TDynArray = classprivate
fDimension: TDynArrayNDX;
fMemAllocated: word;
function GetElement(N: TDynArrayNDX): TDynArrayBaseType;
procedure SetElement(N: TDynArrayNDX; const NewValue: TDynArrayBaseType);
protected
Elements: PArrayElements;
publicconstructor Create(NumElements: TDynArrayNDX);
destructor Destroy; override;
procedure Resize(NewDimension: TDynArrayNDX); virtual;
property dimension: TDynArrayNDX
read fDimension;
property Element[N: TDynArrayNDX]: TDynArrayBaseType
read GetElement
write SetElement;
default;
end;
const
vMaxMatrixColumns = 65520 div sizeof(TDynArray);
{= построение матрицы класса с использованием массива объектов TDynArray =}type
TMatrixNDX = 1..vMaxMatrixColumns;
TMatrixElements = array[TMatrixNDX] of TDynArray;
{= каждая колонка матрицы будет динамическим массивом =}
PMatrixElements = ^TMatrixElements;
{= указатель на массив указателей... =}
TDynaMatrix = classprivate
fRows: TDynArrayNDX;
fColumns: TMatrixNDX;
fMemAllocated: longint;
function GetElement(row: TDynArrayNDX;
column: TMatrixNDX): TDynArrayBaseType;
procedure SetElement(row: TDynArrayNDX;
column: TMatrixNDX;
const NewValue: TDynArrayBaseType);
protected
mtxElements: PMatrixElements;
publicconstructor Create(NumRows: TDynArrayNDX; NumColumns: TMatrixNDX);
destructor Destroy; override;
property rows: TDynArrayNDX
read fRows;
property columns: TMatrixNDX
read fColumns;
property Element[row: TDynArrayNDX; column: TMatrixNDX]: TDynArrayBaseType
read GetElement
write SetElement;
default;
end;
implementation(*
--
-- методы TDynArray
--
*)constructor TDynArray.Create(NumElements: TDynArrayNDX);
begin{==TDynArray.Create==}inherited Create;
fDimension := NumElements;
GetMem(Elements, fDimension * sizeof(TDynArrayBaseType));
fMemAllocated := fDimension * sizeof(TDynArrayBaseType);
FillChar(Elements^, fMemAllocated, 0);
end; {==TDynArray.Create==}destructor TDynArray.Destroy;
begin{==TDynArray.Destroy==}
FreeMem(Elements, fMemAllocated);
inherited Destroy;
end; {==TDynArray.Destroy==}procedure TDynArray.Resize(NewDimension: TDynArrayNDX);
begin{TDynArray.Resize==}if (NewDimension < 1) thenraise EDynArrayRangeError.CreateFMT('Индекс вышел за границы диапазона : %d',
[NewDimension]);
Elements := ReAllocMem(Elements, fMemAllocated, NewDimension *
sizeof(TDynArrayBaseType));
fDimension := NewDimension;
fMemAllocated := fDimension * sizeof(TDynArrayBaseType);
end; {TDynArray.Resize==}function TDynArray.GetElement(N: TDynArrayNDX): TDynArrayBaseType;
begin{==TDynArray.GetElement==}if (N < 1) or (N > fDimension) thenraise EDynArrayRangeError.CreateFMT('Индекс вышел за границы диапазона : %d',
[N]);
result := Elements^[N];
end; {==TDynArray.GetElement==}procedure TDynArray.SetElement(N: TDynArrayNDX; const NewValue:
TDynArrayBaseType);
begin{==TDynArray.SetElement==}if (N < 1) or (N > fDimension) thenraise EDynArrayRangeError.CreateFMT('Индекс вышел за границы диапазона : %d',
[N]);
Elements^[N] := NewValue;
end; {==TDynArray.SetElement==}(*
--
-- методы TDynaMatrix
--
*)constructor TDynaMatrix.Create(NumRows: TDynArrayNDX; NumColumns: TMatrixNDX);
var
col: TMatrixNDX;
begin{==TDynaMatrix.Create==}inherited Create;
fRows := NumRows;
fColumns := NumColumns;
{= выделение памяти для массива указателей (т.е. для массива TDynArrays) =}
GetMem(mtxElements, fColumns * sizeof(TDynArray));
fMemAllocated := fColumns * sizeof(TDynArray);
{= теперь выделяем память для каждого столбца матрицы =}for col := 1 to fColumns dobegin
mtxElements^[col] := TDynArray.Create(fRows);
inc(fMemAllocated, mtxElements^[col].fMemAllocated);
end;
end; {==TDynaMatrix.Create==}destructor TDynaMatrix.Destroy;
var
col: TMatrixNDX;
begin{==TDynaMatrix.Destroy;==}for col := fColumns downto 1 dobegin
dec(fMemAllocated, mtxElements^[col].fMemAllocated);
mtxElements^[col].Free;
end;
FreeMem(mtxElements, fMemAllocated);
inherited Destroy;
end; {==TDynaMatrix.Destroy;==}function TDynaMatrix.GetElement(row: TDynArrayNDX;
column: TMatrixNDX): TDynArrayBaseType;
begin{==TDynaMatrix.GetElement==}if (row < 1) or (row > fRows) thenraise
EDynArrayRangeError.CreateFMT('Индекс строки вышел за границы диапазона : %d', [row]);
if (column < 1) or (column > fColumns) thenraise
EDynArrayRangeError.CreateFMT('Индекс столбца вышел за границы диапазона : %d', [column]);
result := mtxElements^[column].Elements^[row];
end; {==TDynaMatrix.GetElement==}procedure TDynaMatrix.SetElement(row: TDynArrayNDX;
column: TMatrixNDX;
const NewValue: TDynArrayBaseType);
begin{==TDynaMatrix.SetElement==}if (row < 1) or (row > fRows) thenraise
EDynArrayRangeError.CreateFMT('Индекс строки вышел за границы диапазона : %d', [row]);
if (column < 1) or (column > fColumns) thenraise
EDynArrayRangeError.CreateFMT('Индекс столбца вышел за границы диапазона : %d', [column]);
mtxElements^[column].Elements^[row] := NewValue;
end; {==TDynaMatrix.SetElement==}end.
Тестовая программа для модуля DynArray
uses DynArray, WinCRT;
const
NumRows: integer = 7;
NumCols: integer = 5;
var
M: TDynaMatrix;
row, col: integer;
begin
M := TDynaMatrix.Create(NumRows, NumCols);
for row := 1 to M.Rows dofor col := 1 to M.Columns do
M[row, col] := row + col / 10;
writeln('Матрица');
for row := 1 to M.Rows dobeginfor col := 1 to M.Columns do
write(M[row, col]: 5: 1);
writeln;
end;
writeln;
writeln('Перемещение');
for col := 1 to M.Columns dobeginfor row := 1 to M.Rows do
write(M[row, col]: 5: 1);
writeln;
end;
M.Free;
end.
Программный проект на языке Delphi, который включает в себя три основные секции:
Секция 1: В этой секции содержатся простые процедуры для работы с динамическими массивами в Delphi. Процедура AllocArray выделяет память для динамического массива, процедура SetV устанавливает значение в конкретной позиции в массиве, а функция GetV возвращает значение в конкретной позиции в массиве.
Секция 2: В этой секции представлен более сложный подход к созданию динамических массивов с помощью классов. Класс TDynArray представляет собой одномерный динамический массив, а класс TDynaMatrix - двумерный динамический массив (матрица). Оба класса имеют свойства и методы для управления элементами и размерами массива.
Секция 3: В этой секции содержится тестовое программное обеспечение, которое демонстрирует использование класса TDynaMatrix. Программа создает матрицу с 7 строками и 5 столбцами, инициализирует ее элементы, а затем печатает матрицу в обоих порядке - по строкам и по столбцам.
Вот некоторые наблюдения и предложения:
В Секции 2 было бы полезно добавить больше комментариев и объяснений, чтобы сделать код более понятным.
Класс TDynaMatrix мог бы получить дополнительные методы для общих операций, таких как изменение размера массива, вставка или удаление элементов.
В тестовом программном обеспечении может быть полезно добавить механизмы обработки ошибок, если размеры матрицы не являются корректными (например, если количество строк равно нулю).
Вы также можете добавить больше функциональности в тестовое программное обеспечение, демонстрируя использование процедур SetV и GetV с динамическим массивом.
Было бы хорошей идеей разделить реализацию классов от тестового программного обеспечения, чтобы классы можно было использовать независимо в других проектах.
В целом, этот проект предоставляет солидную основу для работы с динамическими массивами в Delphi. С дополнительной функциональностью и улучшениями он мог бы стать еще более мощным и универсальным.
Массив в Delphi - статья, описывающая создание и использование массивов в языке программирования Delphi, включая примеры кода для операций с двухмерными массивами, создания динамических одномерных и двумерных массивов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.