LearnFrenzy
Sign in Take a free test

Arrays · Lesson 17 of 35

2D Arrays and Matrices in C

4 min read Updated Nov 7, 2026 Saurabh Samir

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;
}

Output

  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;
}

Output

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;
}

Output

A + B:
    7    7    7
    7    7    7
Transpose of A:
    1    4
    2    5
    3    6
A x A^T:
   14   32
   32   77

Matrix multiplication rule

  1. Sizes(r × k) × (k × c) gives (r × c) – inner sizes must match
  2. Each result cellp[i][j] = sum over k of a[i][k] × b[k][j]
  3. 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

  1. 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;
    }

    Output

    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.

Next lesson

Search LearnFrenzy

Esc

Quick links