Data Structures

AS Level

Rows & Columns

Master two-dimensional (2D) arrays — the data structure that stores elements in rows and columns. Learn to declare a grid, populate it with nested loops, trace every step, traverse it row by row, fill it with random numbers at IGCSE and AS Level, and search it for a target value using CIE pseudocode.

1.1 What Is a 2D Array?

A two-dimensional (2D) array is a data structure that stores elements in rows and columns, forming a grid-like structure. Each element is uniquely identified by two indices: its row index and its column index. If a 1D array is a list, a 2D array is a table.

  • Declaration specifies two index ranges separated by a comma: DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER.
  • The first range 1:3 is the rows (1 to 3); the second range 1:5 is the columns (1 to 5).
  • Total elements = rows × columns = 3 × 5 = 15.
  • Typical uses: game boards (chess, tic-tac-toe), seating plans, spreadsheets and matrices.

Example: declare a 3 × 5 grid of integers

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
// 3 rows (1..3) and 5 columns (1..5) — 15 cells in total

Key idea: The first index is always the row, the second is always the column. Read matrix[2, 3] aloud as “matrix row 2, column 3” to keep them straight — this matches how you would describe a cell in a spreadsheet.

1.2 Single Element Assignment & Access

Once a 2D array is declared, every cell starts empty. You can write a value into a single cell using an assignment statement, or read a value out of a cell into a variable.

  • Assign: matrix[2, 4] <- 1985 writes 1985 into the cell at row 2, column 4.
  • Access: value <- matrix[2, 3] reads the cell at row 2, column 3 and stores it in value.
  • Row index always comes first, column index second — exactly the same order as the declaration.

Example: assign to one cell, then read from another

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE value : INTEGER

matrix[2, 4] <- 1985   // Write 1985 into row 2, column 4
value <- matrix[2, 3]  // Read row 2, column 3 into 'value'
OUTPUT value           // Outputs whatever was stored at [2, 3]

Assign to row 3, column 5

matrix[3, 5] <- 42

Read from row 1, column 2

value <- matrix[1, 2]

Common mistake: Swapping the indices — writing matrix[4, 2] <- 1985 when you meant row 2, column 4. Always remember: row first, column second. The cell matrix[4, 2] is a completely different position from matrix[2, 4].

1.3 Populating with Nested Loops

To populate every cell of a 2D array, use nested loops: an outer FOR loop walks through the rows, and an inner FOR loop walks through the columns of each row. The classic worked example builds a multiplication table by storing row * column in each cell.

Example: fill a 3 × 5 grid with a multiplication table

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE row, col : INTEGER

FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    matrix[row, col] <- row * col
  NEXT col
NEXT row

After the loops, the array holds the grid:

×Col 1Col 2Col 3Col 4Col 5
Row 112345
Row 2246810
Row 33691215

Trace Table — every step of the nested loops

This trace table shows each step of execution. There are 15 steps in total — one for every cell in the 3 × 5 grid.

Steprowcolumnrow × columnvalue stored in matrix[row, column]
1111 × 11
2121 × 22
3131 × 33
4141 × 44
5151 × 55
6212 × 12
7222 × 24
8232 × 36
9242 × 48
10252 × 510
11313 × 13
12323 × 26
13333 × 39
14343 × 412
15353 × 515

How the nested loops work

  • Row 1 starts → column goes 1 → 2 → 3 → 4 → 5 → Row 1 is now fully complete.
  • Row 2 starts → column again goes 1 → 2 → 3 → 4 → 5 → Row 2 is now fully complete.
  • Row 3 starts → column again goes 1 → 2 → 3 → 4 → 5 → Row 3 is now fully complete.
  • Only when Row 3 finishes does the program stop.

Key question: How many times does the assignment statement matrix[row, col] <- row * col run? Answer: 3 × 5 = 15 times (rows × columns). The body of the inner loop runs once for every (row, column) pair in the grid.

1.4 Traversal — Outputting Every Element

Traversal is the operation of visiting every element of a 2D array in turn. We use the same nested-loop pattern as for populating — outer loop for rows, inner loop for columns — but the body of the inner loop outputs each cell instead of writing to it.

  • Use an outer FOR loop for rows and an inner FOR loop for columns.
  • In the inner loop, OUTPUT matrix[row, col], " " prints the current cell followed by a space.
  • After the inner loop, an empty OUTPUT "" moves the cursor to a new line — so each row appears on its own line.
  • This is called row-major traversal: all of row 1 is printed before any of row 2.

Example: print a 3 × 5 grid as a grid

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE row, col : INTEGER
// ... (assume matrix is already filled) ...
FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    OUTPUT matrix[row, col], " "
  NEXT col
  OUTPUT ""
NEXT row

If matrix holds the multiplication table from section 1.3, the output is:

1 2 3 4 5
2 4 6 8 10
3 6 9 12 15

Print row 2 (loop columns)

DECLARE col : INTEGER
FOR col <- 1 TO 5
  OUTPUT matrix[2, col], " "
NEXT col

Print column 3 (loop rows)

DECLARE row : INTEGER
FOR row <- 1 TO 3
  OUTPUT matrix[row, 3], " "
NEXT row

Exam 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.

1.5 Random Population — RANDOM vs RAND

A common task is to fill a 2D array with random numbers. The syntax differs between IGCSE / O Level and AS Level — make sure you use the right one for your syllabus.

IGCSE / O Level — RANDOM()

DECLARE Marks : ARRAY[1:3, 1:5] OF REAL
DECLARE x, y : INTEGER
FOR x <- 1 TO 3
  FOR y <- 1 TO 5
    Marks[x, y] <- RANDOM() * 100
  NEXT y
NEXT x

RANDOM() returns a real in 0 ≤ x < 1. Multiplying by 100 scales it to 0 ≤ x < 100 — a real value in the range 0 to 100 (exclusive of 100). Use INT(RANDOM() * 100) if you need an integer.

AS Level — RAND(n)

DECLARE Marks : ARRAY[1:3, 1:5] OF INTEGER
DECLARE x, y : INTEGER
FOR x <- 1 TO 3
  FOR y <- 1 TO 5
    Marks[x, y] <- RAND(101)
  NEXT y
NEXT x

RAND(n) returns an integer in the range 0 to n-1. So RAND(101) returns an integer 0..100 inclusive (101 possible values). It returns an INTEGER directly — no need to wrap with INT().

Important difference: RANDOM() (IGCSE) takes no argument and returns a real 0..<1. RAND(n) (AS Level) takes an integer n and returns an integer 0..n-1. The classic off-by-one trap is using RAND(100) when you wanted 0..100 — that gives you 0..99. To include 100, use RAND(101).

1.6 Searching in 2D Arrays & Worked Tasks

A linear search of a 2D array uses two nested loops to scan every cell. A BOOLEAN flag called found records whether the target has been located. Initialise it to FALSE before the loops; if any cell matches, set it to TRUE and output the row and column. After the loops, if found is still FALSE, output a “not found” message.

Example: search a 5 × 5 array for a target value

DECLARE array : ARRAY[1:5, 1:5] OF INTEGER
DECLARE targetValue : INTEGER
DECLARE found : BOOLEAN
DECLARE row, col : INTEGER

targetValue <- 10
found <- FALSE

// Nested loops to search for the target value
FOR row <- 1 TO 5
  FOR col <- 1 TO 5
    IF array[row, col] = targetValue THEN
      found <- TRUE
      OUTPUT "Found at ROW ", row, " COLUMN: ", col
    END IF
  NEXT col
NEXT row

IF NOT found THEN
  OUTPUT "Target value not found in the array"
END IF

Worked task: Contacts search

A 2D array Contacts stores the names and phone numbers of 250 contacts. Column 1 stores the contact name and column 2 stores the contact number. Write a pseudocode algorithm to input a contact name, search the array, and output the matching contact number. If the contact name is not found, output “Contact not found”.

DECLARE Contacts : ARRAY[1:250, 1:2] OF STRING
DECLARE SearchName : STRING
DECLARE found : BOOLEAN
DECLARE i : INTEGER

OUTPUT "Enter contact name to search: "
INPUT SearchName
found <- FALSE

FOR i <- 1 TO 250
  IF Contacts[i, 1] = SearchName THEN
    found <- TRUE
    OUTPUT "Phone number: ", Contacts[i, 2]
  END IF
NEXT i

IF NOT found THEN
  OUTPUT "Contact not found"
END IF

Activity: Treasure Hunt

An 8 × 8 two-dimensional array named map represents a grid of locations in a treasure-hunt game. Some cells contain the word “Treasure” while others contain “Empty”. Write a program to search the grid for the treasure and output the first location where it is found in the format Treasure found at Row X, Column Y. If no treasure is found, output No treasure found on the map.

DECLARE map : ARRAY[1:8, 1:8] OF STRING
DECLARE found : BOOLEAN
DECLARE row, col : INTEGER

found <- FALSE

FOR row <- 1 TO 8
  FOR col <- 1 TO 8
    IF map[row, col] = "Treasure" THEN
      found <- TRUE
      OUTPUT "Treasure found at Row ", row, ", Column ", col
    END IF
  NEXT col
NEXT row

IF NOT found THEN
  OUTPUT "No treasure found on the map."
END IF

Activity: Find the word “Start”

You are given a 2D array words with three rows and five columns, filled with various words. The word “Start” is hidden in one of the positions within this array. Write a program that navigates through the array to locate and output the position of the word “Start” in the format Start found at Row X, Column Y.

DECLARE words : ARRAY[1:3, 1:5] OF STRING
DECLARE found : BOOLEAN
DECLARE row, col : INTEGER

found <- FALSE

FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    IF words[row, col] = "Start" THEN
      found <- TRUE
      OUTPUT "Start found at Row ", row, ", Column ", col
    END IF
  NEXT col
NEXT row

IF NOT found THEN
  OUTPUT "Start not found in the array"
END IF

Key Points Summary

A 2D array stores elements in rows and columns, forming a grid.

Declare with two index ranges: ARRAY[1:R, 1:C] OF Type.

Total elements = rows × columns.

matrix[row, col] — row index first, column index second.

Populate and traverse with two nested FOR loops.

Outer loop = rows, inner loop = columns (row-major order).

OUTPUT "" after the inner loop moves printing to a new line.

IGCSE: RANDOM() * 100 gives a real 0..100. AS Level: RAND(101) gives an integer 0..100.

Linear search uses nested loops + a BOOLEAN found flag.

RAND(n) returns integers 0..n-1, so use RAND(K+1) for 0..K inclusive.

Exam tip: Whenever an exam question mentions a “grid”, “matrix”, “board”, “table” or “map”, reach for a 2D array and nested loops. When it asks you to “search for the first occurrence”, use a BOOLEAN found flag and stop scanning as soon as found becomes TRUE.

Question Bank

Answer all questions, then press Submit Quiz to see your score.

0/12 answered

Question 1Multiple Choice

How is a 2D array with 3 rows and 5 columns of integers declared in CIE pseudocode?

Question 2True / False

The statement matrix[2, 4] <- 1985 sets the element at row 2 and column 4 of the 2D array matrix to the value 1985.

Question 3Multiple Choice

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE row, col : INTEGER
FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    matrix[row, col] <- row * col
  NEXT col
NEXT row
OUTPUT matrix[3, 5]

Question 4Multiple Choice

For an outer FOR loop running rows 1 to 3 and an inner FOR loop running columns 1 to 5, how many times does the assignment statement inside the inner loop execute?

Question 5True / False

An empty OUTPUT "" placed after the inner column loop moves the cursor to a new line, so each row of a 2D array appears on its own line.

Question 6Multiple Choice

At AS Level, which statement fills Marks[x, y] with a random INTEGER in the range 0 to 100 inclusive?

Question 7Multiple Choice

In the Contacts worked task, what does the program output if the contact name entered by the user is NOT found in the Contacts array?

Question 8True / False

At AS Level, RAND(101) returns an integer in the range 0 to 100 inclusive (that is, one of 0, 1, 2, ..., 100).

Question 9Multiple Choice

DECLARE matrix : ARRAY[1:3, 1:5] OF INTEGER
DECLARE row, col : INTEGER
DECLARE targetValue : INTEGER
DECLARE found : BOOLEAN
FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    matrix[row, col] <- row * col
  NEXT col
NEXT row
OUTPUT "Enter value to search: "
INPUT targetValue
found <- FALSE
FOR row <- 1 TO 3
  FOR col <- 1 TO 5
    IF matrix[row, col] = targetValue THEN
      found <- TRUE
      OUTPUT "Found at ROW ", row, " COLUMN: ", col
    END IF
  NEXT col
NEXT row
IF NOT found THEN
  OUTPUT "Target value not found in the array"
END IF

Question 10True / False

In a linear search of a 2D array, the BOOLEAN found flag must be initialised to FALSE before the loops begin.

Question 11Multiple Choice

In the Treasure Hunt activity, what are the dimensions of the map array?

Question 12Multiple Choice

Which is the correct AS Level pseudocode to assign a random integer from 0 to 9 (inclusive) to the variable DiceRoll?

Answer all 12 questions to enable submission.