21.1 Two-Dimensional Arrays
- A 2D array has rows and columns — think of it as a table or grid.
- Declaration uses two index ranges separated by a comma:
DECLARE Grid : ARRAY[1:3, 1:4] OF INTEGER. - Access a single element with two indices:
Grid[2, 3]means row 2, column 3. - Typical uses: matrices, game boards, spreadsheets and seating plans.
Example: declare and fill a 3×4 grid
DECLARE Grid : ARRAY[1:3, 1:4] OF INTEGER
DECLARE Row, Col : INTEGER
FOR Row <- 1 TO 3
FOR Col <- 1 TO 4
OUTPUT "Enter value for [", Row, ",", Col, "]: "
INPUT Grid[Row, Col]
NEXT Col
NEXT RowKey idea: The first index is always the row, the second is always the column. Read Grid[2, 3] aloud as “Grid row 2, column 3” to keep them straight.
Two-Dimensional Arrays
21.2 Accessing 2D Array Elements
- Access a specific cell with
Grid[Row, Col]. - To print every element, use two nested FOR loops: outer for rows, inner for columns.
- An empty
OUTPUT ""after the inner loop moves the cursor to the next line. - To access a specific row, fix the row index and loop through columns. To access a specific column, fix the column index and loop through rows.
Example: print all elements of a 3×4 grid
FOR Row <- 1 TO 3
FOR Col <- 1 TO 4
OUTPUT Grid[Row, Col], " "
NEXT Col
OUTPUT ""
NEXT RowAccess row 2 (loop columns)
DECLARE Col : INTEGER
FOR Col <- 1 TO 4
OUTPUT Grid[2, Col], " "
NEXT ColAccess column 3 (loop rows)
DECLARE Row : INTEGER
FOR Row <- 1 TO 3
OUTPUT Grid[Row, 3], " "
NEXT RowExam tip: When the question asks you to “print row K” or “print column K”, decide which index is fixed. The fixed index stays a literal; the changing index is the loop variable.
Accessing 2D Array Elements
21.3 Sum of 2D Array Elements
- Use nested loops to walk through every cell of the grid.
- Initialise Total to 0 once, before both loops start.
- Accumulate with
Total <- Total + Grid[Row, Col]inside both loops. - For row sums, reset RowSum to 0 at the start of each row and output it after the inner loop. For column sums, swap the loop roles.
Example: sum of all elements in a 3×4 grid
DECLARE Total : INTEGER
Total <- 0
FOR Row <- 1 TO 3
FOR Col <- 1 TO 4
Total <- Total + Grid[Row, Col]
NEXT Col
NEXT Row
OUTPUT "Total: ", TotalCommon mistake: Writing Total <- 0 inside the inner loop. This resets the running total to 0 on every cell visit and you end up with only the last value. Always initialise the accumulator once, outside both loops.
Sum of 2D Array Elements
21.4 Searching in 2D Arrays
- A linear search through a 2D array uses two nested loops to scan every cell.
- Declare a Found flag (BOOLEAN) and two position variables
FoundRowandFoundCol(INTEGER). - When
Grid[Row, Col] = SearchVal, setFound <- TRUEand record the position. - After the loops, use
IF Foundto decide whether to print the position or “Not found”.
Example: search for a value in a 3×4 grid
DECLARE SearchVal : INTEGER
DECLARE Found : BOOLEAN
DECLARE FoundRow, FoundCol : INTEGER
Found <- FALSE
OUTPUT "Enter value to search: "
INPUT SearchVal
FOR Row <- 1 TO 3
FOR Col <- 1 TO 4
IF Grid[Row, Col] = SearchVal THEN
Found <- TRUE
FoundRow <- Row
FoundCol <- Col
ENDIF
NEXT Col
NEXT Row
IF Found THEN
OUTPUT "Found at [", FoundRow, ",", FoundCol, "]"
ELSE
OUTPUT "Not found"
ENDIFKey idea: The simple FOR-loop version keeps scanning after a match. That is fine for small grids. To exit early, switch to WHILE loops guarded by NOT Found.
Searching in 2D Arrays
21.5 Sorting Arrays (Bubble Sort)
- Bubble sort repeatedly compares adjacent elements and swaps them if they are out of order.
- After each pass, the largest unsorted element “bubbles” to its correct position at the end.
- Sorting
nelements needs at mostn - 1passes. - Swapping requires a Temp variable to hold one value while the other is overwritten.
Example: bubble sort 5 elements into ascending order
DECLARE Numbers : ARRAY[1:5] OF INTEGER
DECLARE I, J : INTEGER
DECLARE Temp : INTEGER
FOR I <- 1 TO 5
OUTPUT "Enter number: "
INPUT Numbers[I]
NEXT I
FOR I <- 1 TO 4
FOR J <- 1 TO 5 - I
IF Numbers[J] > Numbers[J + 1] THEN
Temp <- Numbers[J]
Numbers[J] <- Numbers[J + 1]
Numbers[J + 1] <- Temp
ENDIF
NEXT J
NEXT I
OUTPUT "Sorted:"
FOR I <- 1 TO 5
OUTPUT Numbers[I]
NEXT IExam tip: The inner loop runs from 1 to n - I. The - I part skips the cells that are already in their final sorted position at the end of the array — that is what makes each successive pass shorter.
Sorting Arrays (Bubble Sort)
21.6 Population, Trace Tables & Activities
A powerful way to fill a 2D array is with a formula based on the row and column indices. The classic example stores row * column in each cell — this builds a multiplication table. Understanding how many times the assignment runs and being able to produce a trace table is an essential exam skill.
Populate by formula — a 3×5 multiplication table:
DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE row, column : INTEGER
FOR row <- 1 TO 3
FOR column <- 1 TO 5
matrix[row, column] <- row * column
NEXT column
NEXT row
// The grid now looks like this:
// Row 1: 1 2 3 4 5
// Row 2: 2 4 6 8 10
// Row 3: 3 6 9 12 15Trace table — each step of the nested loop execution:
| row | column | row × column | matrix[row, column] |
|---|---|---|---|
| 1 | 1 | 1 × 1 | 1 |
| 1 | 2 | 1 × 2 | 2 |
| 1 | 3 | 1 × 3 | 3 |
| 1 | 4 | 1 × 4 | 4 |
| 1 | 5 | 1 × 5 | 5 |
| 2 | 1 | 2 × 1 | 2 |
| 2 | 2 | 2 × 2 | 4 |
| 2 | 3 | 2 × 3 | 6 |
| 2 | 4 | 2 × 4 | 8 |
| 2 | 5 | 2 × 5 | 10 |
| 3 | 1 | 3 × 1 | 3 |
| 3 | 2 | 3 × 2 | 6 |
| 3 | 3 | 3 × 3 | 9 |
| 3 | 4 | 3 × 4 | 12 |
| 3 | 5 | 3 × 5 | 15 |
Key question: How many times does the assignment statement run? The outer loop runs 3 times (once per row) and the inner loop runs 5 times (once per column) for each row. So the total is 3 × 5 = 15 times — the product of the row count and the column count, which equals the total number of cells in the grid.
Random population — IGCSE vs AS Level:
You can also fill a 2D array with random numbers. The function depends on the level:
IGCSE / O Level
RANDOM() returns a REAL between 0 and 1. Multiply by 100 (and round) to get 0..100.
Marks[x, y] <- ROUND(RANDOM() * 100)AS Level
RAND(n) returns an INTEGER from 0 to n−1. RAND(101) gives 0..100.
Marks[x, y] <- RAND(101)Activity 1 — Contacts search: A 2D array Contacts stores 250 contacts: column 1 = name, column 2 = phone number. Input a name, search the array, and output the matching phone number (or “Contact not found”).
DECLARE Contacts : ARRAY[1:250, 1:2] OF STRING
DECLARE SearchName : STRING
DECLARE row : INTEGER
DECLARE found : BOOLEAN
found <- FALSE
INPUT SearchName
FOR row <- 1 TO 250
IF Contacts[row, 1] = SearchName THEN
found <- TRUE
OUTPUT "Phone number: ", Contacts[row, 2]
ENDIF
NEXT row
IF NOT found THEN
OUTPUT "Contact not found"
ENDIFActivity 2 — Treasure Hunt: An 8×8 array map contains “Treasure” or “Empty” in each cell. Search for the first treasure and output its position (or “No treasure found on the map”).
DECLARE map : ARRAY[1:8, 1:8] OF STRING
DECLARE row, col : INTEGER
DECLARE found : BOOLEAN
found <- FALSE
FOR row <- 1 TO 8
FOR col <- 1 TO 8
IF map[row, col] = "Treasure" AND NOT found THEN
found <- TRUE
OUTPUT "Treasure found at Row ", row, ", Column ", col
ENDIF
NEXT col
NEXT row
IF NOT found THEN
OUTPUT "No treasure found on the map."
ENDIFPattern: for “find the first match” tasks, add a found flag and check AND NOT found so you only report the first occurrence. For “find all matches”, drop the flag and output every match inside the loop.
Population, Trace Tables & Activities
21.7 Key Points Summary
2D arrays use two indices: Array[Row, Col].
Nested loops are needed to iterate through 2D arrays.
Outer loop = rows, inner loop = columns.
Bubble sort compares adjacent elements and swaps them.
Bubble sort needs (n - 1) passes for n elements.
Use a Temp variable when swapping two array elements.
For row sums, reset the accumulator inside the outer loop.
2D arrays and bubble sort are AS Level topics.
Exam tip: Whenever an exam question mentions a “grid”, “matrix”, “board” or “table”, reach for a 2D array and nested loops. When it asks you to “sort”, “arrange in order” or “into ascending sequence”, reach for bubble sort with a Temp-based swap.