Learn
8.2.1.2 | DECLARE AND USE TWO-DIMENSIONAL ARRAYS
01 | ONE SCORE PER STUDENT IS NOT ENOUGH
A one-dimensional array can store one score for each student. Now imagine three students each completing four tests. The program must remember both which student and which test a score belongs to.
A two-dimensional array, or 2D array, uses two indices to select one element. An element is one storage position. An index is the number identifying a position along one dimension.
A grid helps us visualise the data. In this lesson the first index selects the student’s row and the second selects the test’s column. These roles are our stated convention; they must stay consistent throughout the program.
02 | READ THE GRID BEFORE THE CODE
Rows run horizontally across the table; columns run vertically down it. Row two and column three meet at the element containing nine.
The headings identify positions, while the cells contain score values. The score nine is not an index. Scores[2, 3] selects the cell where those two indexed positions meet.
| Student row | Test column 1 | Test column 2 | Test column 3 | Test column 4 |
|---|---|---|---|---|
| 1 | 8 | 6 | 7 | 5 |
| 2 | 4 | 10 | 9 | 6 |
| 3 | 7 | 5 | 8 | 10 |
03 | DECLARE BOTH INDEX RANGES
A 2D declaration gives a lower and upper bound for each dimension, separated by a comma. The lower bound is the first permitted index; the upper bound is the last.
Scores has row indices one through three and column indices one through four. OF INTEGER states that every element holds the same INTEGER data type.
The declaration creates the structure but does not assign the twelve scores shown above. Initialise elements before reading them. Do not assume declarations automatically fill the array with zeros.
DECLARE Scores : ARRAY[1:3, 1:4] OF INTEGER
| Part | Meaning |
|---|---|
| Scores | Name of the whole array |
| 1:3 | First dimension: three student rows |
| 1:4 | Second dimension: four test columns |
| OF INTEGER | Every stored score is INTEGER |
04 | COUNT THE TOTAL ELEMENTS
Each dimension’s size is upper bound minus lower bound plus one. Multiply those sizes to find the total number of elements.
Three rows with four elements each give twelve elements. Adding three and four gives seven, which is not the number of stored positions.
Bounds need not start at one. ARRAY[0:2, 0:3] also has three by four elements, but valid index pairs differ. Cambridge generally uses one-based examples, while the syllabus allows a first index of zero. Read each declaration explicitly.
| Bounds | First dimension size | Second dimension size | Total elements |
|---|---|---|---|
| [1:3, 1:4] | 3 | 4 | 12 |
| [0:2, 0:3] | 3 | 4 | 12 |
| [2:4, 5:8] | 3 | 4 | 12 |
05 | ASSIGN ONE VALUE USING TWO INDICES
Scores[2, 3] ← 9 stores nine at student row two, test column three. Use a comma between the indices inside one pair of square brackets.
The declaration uses colons to show ranges. An element access uses one evaluated index per dimension. It does not use the entire ranges again.
Cambridge’s notation here is Scores[2, 3], not Scores[2][3]. Other programming languages may represent similar data differently, so keep the required pseudocode format.
Scores[2, 3] ← 9 Scores[1, 4] ← 5 Scores[3, 1] ← 7
06 | INITIALISE THE EXAMPLE GRID
The following assignments supply all twelve values. They are deliberately listed individually so you can connect each pair of indices to its cell in the table.
Values need not all be different. Several cells hold seven or ten, but they remain separate elements because their index pairs differ.
Later, nested loops can initialise or read many elements with fewer repeated instructions. A shorter method must still assign the intended values to the correct positions.
Scores[1, 1] ← 8 Scores[1, 2] ← 6 Scores[1, 3] ← 7 Scores[1, 4] ← 5 Scores[2, 1] ← 4 Scores[2, 2] ← 10 Scores[2, 3] ← 9 Scores[2, 4] ← 6 Scores[3, 1] ← 7 Scores[3, 2] ← 5 Scores[3, 3] ← 8 Scores[3, 4] ← 10
07 | READ THE VALUE AT THE INTERSECTION
Reading Scores[2, 3] gives nine. Reading Scores[3, 2] gives five. Swapping the indices changes which cell is selected, so the results need not be equal.
SelectedScore receives the value, not the index pair. OUTPUT then displays that value. Reading does not remove or change the source element.
Scores[2, 4] + Scores[3, 4] adds two score values from test column four: six plus ten gives sixteen.
DECLARE SelectedScore : INTEGER DECLARE PairTotal : INTEGER SelectedScore ← Scores[2, 3] PairTotal ← Scores[2, 4] + Scores[3, 4] OUTPUT SelectedScore OUTPUT PairTotal
08 | REPLACE OR INCREASE ONE ELEMENT
An assignment replaces only the selected element. Scores[2, 3] ← 11 changes nine to eleven at that position. It does not replace row two or column three as a whole.
Scores[2, 3] ← Scores[2, 3] + 1 then reads eleven, adds one and stores twelve back. All other elements stay unchanged.
The array still has twelve positions. An element update does not append a new row, add a column or enlarge the declared bounds.
Scores[2, 3] ← 11 Scores[2, 3] ← Scores[2, 3] + 1 OUTPUT Scores[2, 3]
09 | VARIABLES CAN SUPPLY BOTH INDICES
StudentNumber and TestNumber can select a score at runtime. They must hold INTEGER values within their corresponding bounds.
When StudentNumber is two and TestNumber is three, Scores[StudentNumber, TestNumber] means Scores[2, 3]. In the original grid, that element contains nine.
The values of the index variables are not changed by reading the element. You can use suitable INTEGER expressions as indices too, provided their evaluated results remain in bounds.
DECLARE StudentNumber : INTEGER DECLARE TestNumber : INTEGER StudentNumber ← 2 TestNumber ← 3 OUTPUT Scores[StudentNumber, TestNumber]
10 | CHECK BOTH DIMENSIONS BEFORE ACCESS
A valid row does not compensate for an invalid column. Scores[2, 5] is outside the declared column range, even though row two is valid. Scores[4, 1] has a valid column but an invalid row.
All four limits must hold before the access below. Assume the index variables already contain INTEGER values and all scores have been initialised.
Out-of-bounds access is an error; do not expect it to create an element or wrap around. Checking bounds also does not initialise a cell that has never been assigned.
IF (StudentNumber >= 1) AND (StudentNumber <= 3) AND (TestNumber >= 1) AND (TestNumber <= 4)
THEN
OUTPUT Scores[StudentNumber, TestNumber]
ELSE
OUTPUT "Student or test index is outside the array"
ENDIF11 | EXPLORE READS AND WRITES IN THE GRID
The interactive grid starts with all twelve scores assigned. Choose a row and column, then read the selected value or replace it with a new INTEGER. The row and column headings show exactly which dimension each control selects.
| Student / test | 1 | 2 | 3 | 4 |
|---|
The demo permits negative INTEGER values to illustrate the element type. A real test-score system would usually add a suitable score-range check.
12 | COPY VALUES WITHOUT LINKING CELLS
Scores[1, 1] ← Scores[2, 3] copies the current value at row two, column three into row one, column one. With the original grid, both cells then contain nine.
A later assignment of twelve to Scores[2, 3] does not update Scores[1, 1]. That earlier copy still holds nine. The elements are independent storage positions.
Remember to evaluate the right-hand expression using its current value, then write the left-hand target. The index pairs identify the source and destination.
Scores[1, 1] ← Scores[2, 3] Scores[2, 3] ← 12 OUTPUT Scores[1, 1] OUTPUT Scores[2, 3]
13 | INPUT CAN WRITE DIRECTLY INTO A CELL
An INPUT destination can be a 2D element. This instruction receives a score for student two’s third test and stores it at the selected position.
The same task can use two valid index variables. INPUT provides the stored value, while the variables select where it goes. Receiving a new value replaces that cell’s old value.
This example assumes suitable INTEGER input. Neither the data type declaration nor a prompt automatically performs every required validation check.
OUTPUT "Enter student two score for test three" INPUT Scores[2, 3] OUTPUT "Stored score: ", Scores[2, 3]
14 | NESTED LOOPS VISIT EVERY ELEMENT
An outer loop can choose the student row and an inner loop can visit all four test columns. The inner loop completes before the outer loop advances to the next student.
This visits [1,1], [1,2], [1,3], [1,4], then row two’s four elements, then row three’s. The OUTPUT executes three times four, or twelve times. This is called traversal: visiting the elements in a planned order.
All elements must already contain values before this read-through. Match each loop’s bounds to its array dimension, and use different counter names for the two loops.
DECLARE Student : INTEGER
DECLARE Test : INTEGER
FOR Student ← 1 TO 3
FOR Test ← 1 TO 4
OUTPUT "Student ", Student, ", test ", Test, ": ", Scores[Student, Test]
NEXT Test
NEXT Student15 | CHOOSE CLEAR DIMENSION MEANINGS
A 2D array need not represent students and tests. It could represent seats by row and position, temperatures by day and time, or a game board by row and column. State what each dimension means.
Every element still has one declared type. A board declared OF CHAR stores characters; a temperature grid OF REAL stores numeric readings. A 2D array is not a mixed-type spreadsheet simply because a table helps visualise it.
A useful explanation is: “The first index chooses student two; the second chooses test three. Their intersection contains nine, therefore Scores[2, 3] returns nine.”
Before using an element, check both bounds, its declared type and whether its value has been assigned. The next lesson develops index variables and expressions further.