Multidimensional Arrays, Arrays of Arrays & Array Operations
Declare true multidimensional arrays and arrays of arrays, use dimension-specific attributes ('Range (2), 'Length (1)), write nested aggregates, implement matrix operations, use component-wise logical operators on Boolean arrays, and know about packed arrays and the Ada.Numerics real-array packages.
Ada supports two kinds of 'arrays of more than one dimension': true multidimensional arrays M (I, J) whose bounds are all part of one object, and arrays whose components are themselves arrays, B (I) (J). The choice affects slicing and assignment. Boolean arrays additionally support and/or/xor/not, making them compact bit sets.
True Multidimensional Arrays
'type Matrix is array (Positive range <>, Positive range <>) of Integer;' declares a two-dimensional unconstrained type. Components are accessed as M (I, J). Attributes take a dimension number: M'First (1), M'Last (2), M'Range (1), M'Length (2). Aggregates nest: [[1, 2, 3], [4, 5, 6]] is 2 × 3, and [others => [others => 0]] fills any matrix. Iterated aggregates build identity matrices: [for I in 1 .. 3 => [for J in 1 .. 3 => (if I = J then 1 else 0)]]. You cannot slice a multidimensional array.
• M (I, J); attributes per dimension: M'Range (1), M'Length (2). • Nested aggregates [[...], [...]]. • No slicing of multidimensional arrays. • 'for X of M' visits every component (row-major).
Arrays of Arrays
'type Board is array (1 .. 3) of Row;' where Row is itself an array type. Access is Game (2) (2), and a whole row is an ordinary array object: Game (1) := "O.O"; and rows can be sliced and passed on their own. The component type must be constrained (all rows have the same length); for jagged structures use arrays of access values or containers.
• B (I) (J) — two index steps. • A row is an array value: assign, pass, slice it. • Component (row) type must be constrained.
Boolean Arrays, Packed Arrays and Numeric Libraries
For one-dimensional Boolean arrays, and, or, xor and not work component by component — F1 and F2 is a set intersection. Adding 'with Pack' (or pragma Pack) asks the compiler to store one bit per Boolean, useful for flags and hardware registers. For numerical work, Ada.Numerics.Real_Arrays provides Real_Vector and Real_Matrix types with +, -, *, Transpose, Solve, Inverse, Determinant and Eigenvalues — you rarely need to write matrix multiplication yourself outside of learning exercises.
• Boolean arrays: and / or / xor / not component-wise. • with Pack → one bit per Boolean. • Ada.Numerics.Real_Arrays / Complex_Arrays for linear algebra.
Code Examples
Multiply and Transpose size their results from the arguments' attributes. A × Aᵀ gives [[14, 32], [32, 77]] (1+4+9 = 14, 4+10+18 = 32, 16+25+36 = 77). The board is an array of arrays; the flag operations are component-wise. Output: A'Length (1) = 2, A'Length (2) = 3 A: 1 2 3 4 5 6 Transpose (A): 1 4 2 5 3 6 A * I3: 1 2 3 4 5 6 A * Transpose (A): 14 32 32 77 O.O .X. ... F1 : 1 1 0 0 1 F2 : 1 0 1 0 0 F1 and F2 : 1 0 0 0 0 F1 or F2 : 1 1 1 0 1 not F1 : 0 0 1 1 0
M (I) (J) -- M is array (...,...) of Integer True two-dimensional arrays use one index list; B (I) (J) is for arrays of arrays.
for J in M'Range loop -- inner dimension for J in M'Range (2) loop
Without a dimension number, 'Range refers to dimension 1.
Row_Slice := M (2, 1 .. 3);
-- copy with a loop, or use an array of arrays if rows must be sliced
Multidimensional arrays cannot be sliced.
How do you get the number of columns of a 2-D array M? A. M'Length B. M'Length (2) C. M'Columns D. M'Last B. M'Length (2).
Which can be sliced? A. A 2-D array M (I, J) B. A row of an array of arrays, B (I) (2 .. 3) C. Neither D. Both
B. A row of an array of arrays is a 1-D array and can be sliced.
What is [True, False] and [True, True]? A. False B. [True, False] C. Compile error D. True B. [True, False] — component-wise and.
Which package provides matrix inversion for Float? A. Ada.Matrix B. Ada.Numerics.Real_Arrays C. Ada.Containers.Vectors D. Interfaces.BLAS Trace the matrix example.
Real output: A'Length (1) = 2, A'Length (2) = 3 A: 1 2 3 4 5 6 Transpose (A): 1 4 2 5 3 6 A * I3: 1 2 3 4 5 6 A * Transpose (A): 14 32 32 77 O.O .X. ... F1 : 1 1 0 0 1 F2 : 1 0 1 0 0 F1 and F2 : 1 0 0 0 0 F1 or F2 : 1 1 1 0 1 not F1 : 0 0 1 1 0
with Ada.Text_IO; use Ada.Text_IO;
procedure L20_Matrix is
-- A true two-dimensional array type
type Matrix is array (Positive range <>, Positive range <>) of Integer;
-- An array of arrays (each row is itself an array object)
type Row is array (1 .. 3) of Character;
type Board is array (1 .. 3) of Row;
-- Boolean arrays support the logical operators component-wise
type Flags is array (1 .. 5) of Boolean;
procedure Print (M : Matrix) is
begin
for I in M'Range (1) loop
for J in M'Range (2) loop
Put (Integer'Image (M (I, J)));
end loop;
New_Line;
end loop;
end Print;
function Multiply (A, B : Matrix) return Matrix is
Result : Matrix (A'Range (1), B'Range (2)) := [others => [others => 0]];
begin
if A'Length (2) /= B'Length (1) then
raise Constraint_Error with "dimension mismatch";
end if;
for I in A'Range (1) loop
for J in B'Range (2) loop
for K in A'Range (2) loop
Result (I, J) := Result (I, J) + A (I, K) * B (K - A'First (2) + B'First (1), J);
end loop;
end loop;
end loop;
return Result;
…