ARRAYS
here's a very simple example...
Const MaxBooleans = (High(Cardinal) - $F) div sizeof(boolean); Type TBoolArray = array[1..MaxBooleans] of boolean; PBoolArray = ^TBoolArray; Var B : PBoolArray; N : integer; BEGIN N := 63579; {= allocate an arbitrary array size.. =} GetMem(B, N*sizeof(boolean)); {= do something with it... =} B^[3477] := FALSE; {= restore the memory to the heap =} {$IFDEF VER80} FreeMem(B, N*sizeof(boolean)); {$ELSE} FreeMem(B); {$ENDIF} END.
From: luribe@slip.net (Luis C. Uribe)
Here are some functions that you can use to handle 2-dim arrays, they can be extended to more dimensions easily. SetV and GetV are made to store and retrieve values from an array of type VArray that you declare as you want. For example:
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 {allocate memory for array V of size N} try GetMem(V, N); except ShowMessage('ERROR allocating memory. Size:' + IntToStr(N)); Result := True; exit; end; FillChar(V^, N, 0); {in case Long strings involved, need to 0} Result := False; end; procedure SetV(var X : Varray;const N,ir,ic : LongInt;const value : double); begin {store in 2-dim array X of size ? 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 {returns value X[ir,ic] for 2-dim array with N columns} Result := X[N*(ir-1) + ic]; end;
From: Lord of Darkness <j.biddiscombe@rl.ac.uk>
the simplest way is create the array dynamically
Myarray := GetMem(rows * cols * sizeof(byte,word,single,double etc)
do a fetch_num function like
function fetch_num(r,c:integer) : single;
result := pointer + row + col*rows
and then instead of myarray[2,3]
do myarray.fetch_num(2,3)
wrap it all up in an object and you're laughing. I've done a multidimensional (up to 8) dynamic complex array class which is based on this principle and it works a treat.
From: m.a.vaughan@larc.nasa.gov (Mark Vaughan)
here's one way to create simple one-dimensional and two-dimensional dynamic array classes.
(* -- -- unit to create two very simple dynamic array classes -- TDynaArray : a one dimensional array -- TDynaMatrix : a two dimensional dynamic array -- *) unit DynArray; INTERFACE uses SysUtils; Type TDynArrayBaseType = double; Const vMaxElements = (High(Cardinal) - $f) div sizeof(TDynArrayBaseType); {= guarantees the largest possible array =} Type TDynArrayNDX = 1..vMaxElements; TArrayElements = array[TDynArrayNDX] of TDynArrayBaseType; {= largest array of TDynArrayBaseType we can declare =} PArrayElements = ^TArrayElements; {= pointer to the array =} EDynArrayRangeError = CLASS(ERangeError); TDynArray = CLASS Private fDimension : TDynArrayNDX; fMemAllocated : word; Function GetElement(N : TDynArrayNDX) : TDynArrayBaseType; Procedure SetElement(N : TDynArrayNDX; const NewValue : TDynArrayBaseType); Protected Elements : PArrayElements; Public Constructor 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); {= build the matrix class using an array of TDynArray objects =} Type TMatrixNDX = 1..vMaxMatrixColumns; TMatrixElements = array[TMatrixNDX] of TDynArray; {= each column of the matrix will be a dynamic array =} PMatrixElements = ^TMatrixElements; {= a pointer to an array of pointers... =} TDynaMatrix = CLASS Private 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; Public Constructor 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 methods -- *) 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) then raise EDynArrayRangeError.CreateFMT('Index out of range : %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) then raise EDynArrayRangeError.CreateFMT('Index out of range : %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) then raise EDynArrayRangeError.CreateFMT('Index out of range : %d', [N]); Elements^[N] := NewValue; END; {==TDynArray.SetElement==} (* -- -- TDynaMatrix methods -- *) Constructor TDynaMatrix.Create(NumRows : TDynArrayNDX; NumColumns : TMatrixNDX); Var col : TMatrixNDX; BEGIN {==TDynaMatrix.Create==} inherited Create; fRows := NumRows; fColumns := NumColumns; {= acquire memory for the array of pointers (i.e., the array of TDynArrays) =} GetMem( mtxElements, fColumns*sizeof(TDynArray) ); fMemAllocated := fColumns*sizeof(TDynArray); {= now acquire memory for each column of the matrix =} for col := 1 to fColumns do BEGIN 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 do BEGIN 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) then raise EDynArrayRangeError.CreateFMT('Row index out of range : %d', [row]); if (column < 1) OR (column > fColumns) then raise EDynArrayRangeError.CreateFMT('Column index out of range : %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) then raise EDynArrayRangeError.CreateFMT('Row index out of range : %d', [row]); if (column < 1) OR (column > fColumns) then raise EDynArrayRangeError.CreateFMT('Column index out of range : %d', [column]); mtxElements^[column].Elements^[row] := NewValue; END; {==TDynaMatrix.SetElement==} END.
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 do for col := 1 to M.Columns do M[row, col] := row + col/10; writeln('Matrix'); for row := 1 to M.Rows do BEGIN for col := 1 to M.Columns do write(M[row, col]:5:1); writeln; END; writeln; writeln('Transpose'); for col := 1 to M.Columns do BEGIN for row := 1 to M.Rows do write(M[row, col]:5:1); writeln; END; M.Free; END.