10.2.2 Two-Dimensional Arrays and Nested Loops
A two-dimensional array stores values in a rectangular arrangement. Each element is selected by an index pair: one index identifies the row and the other identifies the column. Nested loops allow a program to visit every position systematically.
By the end of this section, you should be able to:
- Decide when a problem is better represented by a 2D array than a 1D array.
- Interpret row and column bounds in a 2D array declaration.
- Calculate the number of rows, columns and total elements.
- Access, assign, input and output an individual cell using an index pair.
- Use nested loops to initialise, read and display a complete 2D array.
- Trace the order in which nested loops move through a grid.
When Is a 2D Array Suitable?
Imagine a greenhouse divided into planting rows and sensor columns. One soil-moisture reading is stored for every intersection. A single position cannot be identified by only one number: the program needs both the planting row and the sensor column.
| Data to store | Likely structure | Reason |
|---|---|---|
| One reading for each of eight checkpoints | 1D array | Each value needs one checkpoint index. |
| One reading for each row-column position in a greenhouse | 2D array | Each value needs a row index and a column index. |
| One passenger name for each seat in several rows | 2D array | The seat is located by row and seat number. |
Rows, Columns and Index Pairs
The following grid uses row indexes 2 to 5 and column indexes 10 to 14. These index values describe positions; they do not have to begin at 0 or 1.
| Row \ Column | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|
| 2 | 48 | 52 | 45 | 57 | 50 |
| 3 | 61 | 55 | 59 | 63 | 54 |
| 4 | 46 | 49 | 51 | 58 | 53 |
| 5 | 64 | 60 | 56 | 62 | 47 |
The value 59 is located at row 3, column 12, so it is addressed as
SoilMoisture[3, 12].
SoilMoisture[3, 12] does not mean βelement 3 then element 12β.
It identifies one cell at the intersection of row 3 and column 12.
Declaring a 2D Array
A declaration includes one bound range for each dimension and one data type for all stored elements.
DECLARE <identifier> : ARRAY[<rowLower>:<rowUpper>, <columnLower>:<columnUpper>] OF <dataType>
DECLARE SoilMoisture : ARRAY[2:5, 10:14] OF INTEGER
| Declaration part | Meaning |
|---|---|
SoilMoisture | The identifier for the complete 2D array. |
2:5 | Valid row indexes are 2, 3, 4 and 5. |
10:14 | Valid column indexes are 10, 11, 12, 13 and 14. |
INTEGER | Every cell stores a whole-number moisture reading. |
Calculate the size
Number of rows = 5 - 2 + 1 = 4
Number of columns = 14 - 10 + 1 = 5
Total elements = 4 * 5 = 20
Accessing and Updating One Cell
In this course, the first index identifies the row and the second identifies the column.
Assign a value
SoilMoisture[3, 12] β 59
Save input directly into a cell
INPUT SoilMoisture[5, 14]
Output one cell
OUTPUT SoilMoisture[2, 11]
Update an existing value
SoilMoisture[4, 13] β SoilMoisture[4, 13] + 2
| Expression | Meaning |
|---|---|
SoilMoisture | The complete 2D array. |
SoilMoisture[3, 12] | One element at row 3, column 12. |
SoilMoisture[Row, Column] | The cell selected by the current values of two index variables. |
SoilMoisture[3] is incomplete because the column index is missing.
Why Nested Loops Are Needed
One loop can visit every row or every column, but not both dimensions by itself. A nested loop places one loop inside another so that every row-column combination is reached.
FOR Row β 2 TO 5
FOR Column β 10 TO 14
OUTPUT SoilMoisture[Row, Column]
NEXT Column
NEXT Row
For row 2, the inner loop visits columns 10 to 14. It then starts again at column 10 when the outer loop advances to row 3.
1 TO numberOfElements unless the declaration uses those indexes.
Processing a Complete Grid
Initialise every element
FOR Row β 2 TO 5
FOR Column β 10 TO 14
SoilMoisture[Row, Column] β 0
NEXT Column
NEXT Row
Input every reading
FOR Row β 2 TO 5
FOR Column β 10 TO 14
INPUT SoilMoisture[Row, Column]
NEXT Column
NEXT Row
Display the array as a grid
FOR Row β 2 TO 5
FOR Column β 10 TO 14
OUTPUT SoilMoisture[Row, Column]
NEXT Column
OUTPUT Newline
NEXT Row
The inner loop outputs all values from one row. OUTPUT Newline is placed after the inner
loop so that the next array row begins on a new output line.
Calculate the total of all cells
TotalMoisture β 0
FOR Row β 2 TO 5
FOR Column β 10 TO 14
TotalMoisture β TotalMoisture + SoilMoisture[Row, Column]
NEXT Column
NEXT Row
OUTPUT TotalMoisture
Tracing the Traversal Order
With rows in the outer loop and columns in the inner loop, the program completes one row before moving to the next. The first seven positions are:
| Step | Row | Column | Element visited |
|---|---|---|---|
| 1 | 2 | 10 | SoilMoisture[2, 10] |
| 2 | 2 | 11 | SoilMoisture[2, 11] |
| 3 | 2 | 12 | SoilMoisture[2, 12] |
| 4 | 2 | 13 | SoilMoisture[2, 13] |
| 5 | 2 | 14 | SoilMoisture[2, 14] |
| 6 | 3 | 10 | SoilMoisture[3, 10] |
| 7 | 3 | 11 | SoilMoisture[3, 11] |
Reversing the loops would visit the same cells in a different order: one complete column at a time. The required order depends on how the data should be processed or displayed.
Interactive: 2D Array Grid Visualiser
Use the existing widget to select a row-column position, change one cell and trace the order used by nested loops. The small demonstration grid keeps the traversal visible while using the same principles as a larger 2D array.
Common Mistakes and Misconceptions
- Using only one index for an element in a 2D array.
- Reversing the intended row-column order.
- Assuming that row and column indexes must begin at 0 or 1.
- Calculating the total size without first finding the size of each dimension.
- Using nested-loop limits that do not match the declaration.
- Placing
OUTPUT Newlineinside the inner loop, which puts every cell on a separate line. - Forgetting that the inner loop restarts for every outer-loop iteration.
- Confusing a 2D array with an array of records. Arrays of records were covered in Section 10.1.2.
Practice
Task 1: Interpret a declaration
DECLARE SeatState : ARRAY[4:9, 20:27] OF CHAR
- State the lower and upper row bounds.
- State the lower and upper column bounds.
- Calculate the number of rows.
- Calculate the number of columns.
- Calculate the total number of elements.
- Write the expression for row 6, column 24.
Task 2: Write pseudocode
- Declare
Rainfallwith rows 1 to 6 and columns 3 to 9, storing REAL values. - Assign
18.6to row 4, column 7. - Write nested loops that set every cell to
0.0. - Write nested loops that input every value.
- Write nested loops that output each array row on a separate line.
Task 3: Trace nested loops
FOR Row β 1 TO 2
FOR Column β 5 TO 7
OUTPUT Grid[Row, Column]
NEXT Column
NEXT Row
- List the six elements in the exact order visited.
- How many times does the inner loop execute in total?
- What value does
Columnrestart with whenRowbecomes 2?
Review
| Question | Strong answer should include |
|---|---|
| What is a 2D array? | A rectangular arrangement of elements selected using two indexes. |
| How is one element addressed? | Use the array identifier and an index pair, normally row then column. |
| How is the total size calculated? | Calculate each dimension with upper β lower + 1, then multiply. |
| Why are nested loops useful? | They generate every combination of valid row and column indexes. |
| Where should a new line be output when displaying a grid? | After the inner column loop, once a complete row has been output. |
| What happens to the inner loop for each new row? | It restarts from its lower bound and completes its full range again. |