Arrays · Lesson 17 of 35
2D Arrays and Matrices in C
Some data is naturally a grid: a timetable, a game board, a spreadsheet, a matrix in maths, the pixels of an image. A two-dimensional array stores it in rows and columns. Matrix programs – addition, transpose, multiplication – are standard first-year lab exercises.
In this lesson
- Declaring, initialising and printing 2D arrays
- Row-major memory layout
- Row and column sums
- Matrix addition, transpose and multiplication
Declaring and printing a 2D array
#include <stdio.h>
int main(void) {
int marks[3][4] = { // 3 students (rows) × 4 subjects (columns)
{78, 85, 62, 90},
{55, 70, 88, 61},
{91, 64, 79, 83},
};
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 4; c++) {
printf("%4d", marks[r][c]);
}
printf("\n");
}
printf("Student 2, subject 3: %d\n", marks[1][2]);
return 0;
}
78 85 62 90 55 70 88 61 91 64 79 83 Student 2, subject 3: 88
Row-major layout
Memory is one long line, so C stores a 2D array row after row ("row-major order"). marks[r][c] is at position r × columns + c:
int m[2][3] = {{1,2,3},{4,5,6}} in memory
- 1m[0][0]
- 2m[0][1]
- 3m[0][2]
- 4m[1][0]
- 5m[1][1]
- 6m[1][2]
That's why, when you pass a 2D array to a function, the number of columns must be given: void print(int m[][4], int rows). Looping row by row (outer loop over rows) also reads memory in order, which is faster.
Row and column totals
#include <stdio.h>
#define ROWS 3
#define COLS 4
int main(void) {
int sales[ROWS][COLS] = { // 3 shops × 4 quarters
{120, 135, 150, 160},
{90, 110, 95, 130},
{200, 180, 210, 220},
};
int col_total[COLS] = {0};
for (int r = 0; r < ROWS; r++) {
int row_total = 0;
for (int c = 0; c < COLS; c++) {
row_total += sales[r][c];
col_total[c] += sales[r][c];
}
printf("Shop %d total: %d\n", r + 1, row_total);
}
printf("Quarter totals:");
for (int c = 0; c < COLS; c++) printf(" %d", col_total[c]);
printf("\n");
return 0;
}
Shop 1 total: 565 Shop 2 total: 425 Shop 3 total: 810 Quarter totals: 410 425 455 510
Matrix operations
#include <stdio.h>
#define N 2
#define M 3
void print_matrix(int rows, int cols, int m[rows][cols]) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) printf("%5d", m[r][c]);
printf("\n");
}
}
int main(void) {
int a[N][M] = {{1, 2, 3}, {4, 5, 6}};
int b[N][M] = {{6, 5, 4}, {3, 2, 1}};
int sum[N][M];
for (int r = 0; r < N; r++)
for (int c = 0; c < M; c++) sum[r][c] = a[r][c] + b[r][c];
printf("A + B:\n");
print_matrix(N, M, sum);
int t[M][N]; // transpose: rows become columns
for (int r = 0; r < N; r++)
for (int c = 0; c < M; c++) t[c][r] = a[r][c];
printf("Transpose of A:\n");
print_matrix(M, N, t);
int p[N][N] = {{0}}; // A (2x3) × transpose (3x2) = 2x2
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < M; k++) p[i][j] += a[i][k] * t[k][j];
printf("A x A^T:\n");
print_matrix(N, N, p);
return 0;
}
A + B:
7 7 7
7 7 7
Transpose of A:
1 4
2 5
3 6
A x A^T:
14 32
32 77Matrix multiplication rule
- Sizes(r × k) × (k × c) gives (r × c) – inner sizes must match
- Each result cellp[i][j] = sum over k of a[i][k] × b[k][j]
- Three nested loopsi over rows, j over columns, k over the shared size
The function uses a variable-length array parameter (int m[rows][cols], C99), so one print function works for any size.
Practice
Try it yourself
Print the sum of the main diagonal of a 3×3 matrix and check whether it's an identity matrix.
Show solution
#include <stdio.h> #include <stdbool.h> int main(void) { int m[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; int trace = 0; bool identity = true; for (int r = 0; r < 3; r++) { for (int c = 0; c < 3; c++) { if (r == c) trace += m[r][c]; if (m[r][c] != (r == c ? 1 : 0)) identity = false; } } printf("diagonal sum = %d, identity = %s\n", trace, identity ? "yes" : "no"); return 0; }diagonal sum = 3, identity = yes
Quick check
How many ints does int a[4][5] hold?
20.
In what order does C store a 2D array?
Row-major: all of row 0, then row 1, and so on.
When can you multiply an (r × k) and a (p × c) matrix?
When k equals p; the result is r × c.
Summary
- A 2D array is rows × columns, indexed
a[row][col], stored row by row. - Pass the column count to functions (or use VLA parameters).
- Addition is cell by cell; transpose swaps indexes; multiplication uses three nested loops.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.