Arrays
Dynamic arrays are reference types with reference counting — but not copy-on-write:
14.1 Static arrays
Any ordinal subrange can be an index type.
Grid[I, J] and Grid[I][J] are equivalent.
Static arrays are value types: assignment copies all elements; passing by value copies too.
Use Low, High, Length, and SizeOf instead of hard-coded bounds.
Enable {$R+} during development to catch out-of-range indexes.
var
Scores: array[1..5] of Integer;
Counts: array['a'..'z'] of Integer; // index by Char
Hours: array[TDay] of Double; // index by an enumeration
Grid: array[0..2, 0..2] of Char; // 2-D
Cube: array[1..4, 1..4, 1..4] of Byte; // 3-D
const
Months: array[1..12] of string =
('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
Identity: array[0..1, 0..1] of Integer = ((1, 0), (0, 1));14.2 Example: frequency count
program LetterFreq;
{$mode objfpc}{$H+}
var
Counts: array['a'..'z'] of Integer;
S: string;
C: Char;
begin
FillChar(Counts, SizeOf(Counts), 0);
S := LowerCase('The quick brown fox jumps over the lazy dog');
for C in S do
if C in ['a'..'z'] then
Inc(Counts[C]);
for C := 'a' to 'z' do
if Counts[C] > 1 then
Writeln(C, ': ', Counts[C]);
end.14.3 Dynamic arrays
Dynamic arrays are reference types with reference counting — but not copy-on-write:
var
A: array of Integer; // or: TArray<Integer> in Delphi / FPC delphi mode
M: array of array of Double; // jagged 2-D
I: Integer;
begin
SetLength(A, 5); // indices 0..4, zero-initialized
for I := 0 to High(A) do
A[I] := I * I;
SetLength(A, 10); // grows; existing elements kept
Writeln(Length(A)); // 10
SetLength(M, 3, 4); // rectangular 3x4
M[2, 3] := 1.5;
A := [5, 3, 8]; // array constructor (Delphi XE7+, FPC 3.2+)
A := A + [13, 21]; // concatenation (Delphi XE7+; FPC 3.2 delphi mode or {$modeswitch arrayoperators})
Insert(99, A, 1); // insert 99 at index 1 (Delphi XE7+, FPC 3.2+)
Delete(A, 0, 1); // delete 1 element at index 0
A := nil; // frees the array (same as SetLength(A, 0))
end.var
X, Y: array of Integer;
begin
X := [1, 2, 3];
Y := X; // Y and X share the same data!
Y[0] := 100;
Writeln(X[0]); // 100
Y := Copy(X); // independent copy (Copy(X, Start, Count) for a slice)
Y[0] := 1;
Writeln(X[0]); // still 100
end.14.4 Sorting and searching
Library alternatives: TArray.Sort<T> and TArray.BinarySearch<T> (Delphi System.Generics.Collections; FPC Generics.Collections provides TArrayHelper<T>), TList<T>.Sort, TStringList.Sort.
type
TIntArray = array of Integer;
procedure InsertionSort(var A: array of Integer);
var
I, J, Key: Integer;
begin
for I := 1 to High(A) do
begin
Key := A[I];
J := I - 1;
while (J >= 0) and (A[J] > Key) do
begin
A[J + 1] := A[J];
Dec(J);
end;
A[J + 1] := Key;
end;
end;
function BinarySearch(const A: array of Integer; Target: Integer): Integer;
var
Lo, Hi, Mid: Integer;
begin
Lo := 0;
Hi := High(A);
while Lo <= Hi do
begin
Mid := Lo + (Hi - Lo) div 2;
if A[Mid] = Target then Exit(Mid)
else if A[Mid] < Target then Lo := Mid + 1
else Hi := Mid - 1;
end;
Result := -1;
end;14.5 Matrix example
type
TMatrix = array[1..3, 1..3] of Double;
function Multiply(const A, B: TMatrix): TMatrix;
var
I, J, K: Integer;
begin
for I := 1 to 3 do
for J := 1 to 3 do
begin
Result[I, J] := 0;
for K := 1 to 3 do
Result[I, J] := Result[I, J] + A[I, K] * B[K, J];
end;
end;14.6 Array summary
Open array parameter Size fixed at compile time no (SetLength) any ordinal range inline (stack/global/record) heap, ref-counted caller's storage array[a..b, c..d] array of array of T one dimension only