Rule
Row × Col
Each Cij is a dot product of row i of A with column j of B.
Matrix multiplication combines rows of A with columns of B via dot products — not cell-by-cell products. This tutorial covers the dimension rule, the triple nested loop, zero-initialization, a live preview, worked C examples (3×3 and 2×2), edge cases, and O(n³) complexity.
Row × Col
Each Cij is a dot product of row i of A with column j of B.
(m×n)(n×p)
Columns of A must equal rows of B; product is m × p.
i, j, k
Outer result indices, inner shared dimension for the sum.
result = 0
Clear the output before accumulating with +=.
3×3 AB
See both factors and the product instantly.
≠ Aij*Bij
Element-wise multiply is a different operation.
If A is m × n and B is n × p, then matrix multiplication produces C = AB of shape m × p, where each entry is Cij = ∑k Aik Bkj.
In C interviews you write three nested loops, zero the result first, and contrast this with addition or element-wise multiply.
It is the classic 2D-array interview problem: dimension rules, triple loops, and accumulation — skills that underpin graphics, ML kernels, and linear-algebra libraries.
Each output cell is one row·column sum.
A cols must equal B rows.
Clear result before accumulating products.
Classic cost for square n×n factors.
In short: zero C, then for each i,j accumulate C[i][j] += A[i][k] * B[k][j] over the shared dimension k.
Given compatible matrices A and B, compute C = AB using the row–column rule and print the factors plus the product.
/* A 3×3, B 3×3 → C 3×3
* C[0][0] = 1*9 + 2*6 + 3*3 = 30
* C[i][j] = sum_k A[i][k] * B[k][j]
*/ | Item | Type | Description |
|---|---|---|
a, b | 2D arrays | Factors; for square samples, both are N × N. |
result | 2D array | Product; must be zeroed before accumulation. |
N | macro | Square size (3 or 2 in the examples). |
function multiply(A, B, C, n): // n×n matrices
for i from 0 to n - 1:
for j from 0 to n - 1:
C[i][j] ← 0
for k from 0 to n - 1:
C[i][j] ← C[i][j] + A[i][k] * B[k][j] | Operation | Rule | Loops |
|---|---|---|
| Matrix multiply (this page) | Row·column sums | Triple nest |
| Element-wise / Hadamard | Aij * Bij | Double nest; same shape |
| Addition | Aij + Bij | Double nest; same shape |
| Goal | Pattern |
|---|---|
| Zero cell | result[i][j] = 0; |
| Accumulate | result[i][j] += a[i][k] * b[k][j]; |
| Shared index | k walks A’s columns / B’s rows |
| Compatibility | cols(A) == rows(B) |
| Square cost | O(n³) for n × n |
Related matrix operations — only true multiplication uses the shared-dimension k loop.
Σ Aik BkjThis page — row times column
Aij+BijSame shape; no k loop
Aij*BijSame shape; element-wise only
zero firstAlways clear result before +=
Reach for matrix multiplication when composing linear maps or combining grids by rows and columns.
Tests 2D indexing, triple loops, and dimension awareness.
Composing transformation matrices.
Weight matrices times activations (conceptually).
Clarify when the prompt wants true product vs element-wise.
Refuse when columns of A ≠ rows of B.
Key benefit: one algorithm that proves you understand both the algebra and the nested-loop implementation details.
Uses the same 3×3 integer matrices as Example 1. Press the button to print both factors and AB.
Two complete C programs — a classic 3×3 product and a smaller 2×2 you can check by hand. Click View Output to reveal sample console results.
Zero the result, then accumulate with three nested loops.
Same matrices and output pattern as the classic walkthrough: multiply_matrices fills the result; display_matrix prints with tabs.
#include <stdio.h>
#define N 3
void multiply_matrices(int a[N][N], int b[N][N], int result[N][N]) {
int i, j, k;
for (i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
result[i][j] = 0;
}
}
for (i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
for (k = 0; k < N; ++k) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
void display_matrix(int matrix[N][N]) {
int i, j;
for (i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
int main(void) {
int first_matrix[N][N] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int second_matrix[N][N] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int result[N][N];
multiply_matrices(first_matrix, second_matrix, result);
printf("First Matrix:\n");
display_matrix(first_matrix);
printf("\nSecond Matrix:\n");
display_matrix(second_matrix);
printf("\nResult Matrix:\n");
display_matrix(result);
return 0;
} The innermost index k pairs a[i][k] with b[k][j]. Initializing result to zero matters because each result[i][j] is a sum of products.
Same triple-loop pattern with a size you can verify on paper.
Top-left output is 1·5 + 2·7 = 19. Zero-init is combined with the k loop in one nest.
#include <stdio.h>
#define N 2
void multiply_matrices(int a[N][N], int b[N][N], int result[N][N]) {
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
result[i][j] = 0;
for (int k = 0; k < N; ++k) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
void display_matrix(const char *title, int m[N][N]) {
printf("%s\n", title);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d ", m[i][j]);
}
printf("\n");
}
}
int main(void) {
int a[N][N] = {
{1, 2},
{3, 4}
};
int b[N][N] = {
{5, 6},
{7, 8}
};
int r[N][N];
multiply_matrices(a, b, r);
display_matrix("A", a);
printf("\n");
display_matrix("B", b);
printf("\n");
display_matrix("AB", r);
return 0;
} Combining zero-init with the k loop in one nest is a compact variant; mathematically it matches Example 1.
Confirm columns of A equal rows of B (fixed N in the samples).
Set every result[i][j] to 0 before accumulating.
For each i, j, add A[i][k]*B[k][j] for all k.
For the 3×3 sample, top-left is 30; full result matches the printed table.
Trace C[0][0]: row 0 of A dotted with column 0 of B.
| k | A[0][k] | B[k][0] | Product | Running sum |
|---|---|---|---|---|
0 | 1 | 9 | 9 | 9 |
1 | 2 | 6 | 12 | 21 |
2 | 3 | 3 | 9 | 30 |
So C[0][0] = 30. Repeat the same pattern for every other (i, j).
Where matrix-multiplication thinking shows up beyond the interview prompt.
Master nested control flow and shared indices.
Example: i, j, then k.
Compose rotations, scales, and projections.
Example: graphics pipelines.
Lead into O(n³) and blocked algorithms.
Example: interview follow-ups on speed.
Show why addition/division pages use different loops.
Example: previous matrix tutorials.
AB ≠ BA in general — a favorite quiz point.
Example: swap factors and recompute.
Products of ints can overflow before the final sum.
Example: suggest long long when needed.
Pro Tip: state the dimension rule and zero-init out loud before writing the triple loop.
Why this approach earns interview points.
Code mirrors the sum-of-products formula one-for-one.
Change bounds for rectangular m×n by n×p.
O(n³) is the expected answer for square classic code.
2×2 and one cell of 3×3 dry-run cleanly on a whiteboard.
Pro Tip: mention blocked / tiled multiply only as a follow-up after the correct triple loop.
Small habits that keep matrix-multiplication code clean in interviews.
Say (m×n)(n×p) → m×p before coding.
Garbage in result ruins every += sum.
Write a[i][k] * b[k][j] — not swapped.
Compute C[0][0] on paper before trusting the full nest.
Suggest long long when entries or n grow large.
Pro Tip: the walkthrough table for C[0][0] is the fastest way to lock in the k loop before typing.
Mistakes that commonly break matrix-multiplication solutions in C.
Uninitialized result makes += start from garbage.
→ Set every cell to 0 before the k loop.
C[i][j] = A[i][j] * B[i][j] is Hadamard, not AB.
→ Use the shared k sum of products.
Using b[j][k] instead of b[k][j] flips columns.
→ Memorize a[i][k] * b[k][j].
Multiplying incompatible shapes is undefined.
→ Require cols(A) == rows(B).
Order matters for matrices.
→ Keep left and right factors in the intended order.
Rules that trip beginners — check these before calling the solution done.
You cannot multiply m×n by p×q unless n = p.
Matrix multiplication is not commutative in general.
Intermediate products may overflow int; consider wider types.
Always clear the output buffer before +=.
Row or column vectors still follow the same dimension rule.
Multiplying by the identity leaves the other matrix unchanged — good sanity check.
Examples use literals in main. To accept typed input, add nested scanf loops and verify dimensions before multiplying.
| Sample | Result highlight |
|---|---|
| 3×3 demo | Top-left of AB is 30; full matrix as printed |
| 2×2 demo | AB = [[19, 22], [43, 50]] |
Try these variations to lock in the pattern.
54Cij = sumk AikBkj; inner sizes of A and B must match.result, then three nested loops with += a[i][k]*b[k][j].n for square n×n matrices.Quick Takeaway: match inner dimensions, zero the result, then accumulate a[i][k]*b[k][j] for every output cell.
| Setting | Time | Extra space |
|---|---|---|
Two n × n matrices, classic triple loop | O(n3) | O(1) beyond outputs |
m×n by n×p | O(m · n · p) | O(1) beyond outputs |
Matrix multiplication is the step up from addition: match the shared dimension, zero the result, and run three nested loops that accumulate row·column products. Master the 3×3 and 2×2 samples so you can generalize sizes on demand.
Practice both examples above, then continue to matrix subtraction for another element-wise warm-up.
Zero C, then C[i][j] += A[i][k] * B[k][j] for all i, j, k — with matching inner sizes.
(m×n)(n×p) rule before codinga[i][k] * b[k][j] consistentlyO(n³) for square classic loopsint overflowImplement it the interview-friendly way.
Row · column
DefinitionMust match
Shapei, j, k
CodeThen +=
InitO(n³)
AnalysisMatrix multiplication links rows of A with columns of B. You need A to be m × n and B to be n × p—the two n’s must match—then AB is m × p.
Learn how to subtract two matrices element-wise with 2D arrays in C.
8 people found this page helpful