Tables in memory Ready
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

A table stored as one row

int m[2][3] is an array of 2 rows, and each row is an array of 3 ints. You use it like a table — m[row][column] — but memory is a single line, so C stores row 0 first, then row 1 (row-major order). When you pass any array to a function, C passes the address of its first element: the function works on the caller's cells, not on a copy, and it needs the size as an extra parameter.

int m[2][3] = {{1, 2, 3},
               {4, 5, 6}};

// m[1][2] is 6: row 1, column 2
// memory: 1 2 3 4 5 6  →  m[i][j] is element i * 3 + j

void show(int m[][3], int rows);   // 2-D: the column count is required
int sum(const int a[], int n);      // 1-D: the size comes separately
int m[2][3] = {{1, 2, 3}, {4, 5, 6}} — start address 0x1000
Element Value Position in memory Address
m[0][0] 1 0 × 3 + 0 = 0 0x1000
m[0][2] 3 0 × 3 + 2 = 2 0x1008
m[1][0] 4 1 × 3 + 0 = 3 0x100c
m[1][1] 5 1 × 3 + 1 = 4 0x1010
m[1][2] 6 1 × 3 + 2 = 5 0x1014

2-D arrays

  1. type name[rows][columns]; — the first index is the row, the second the column.
  2. Initialise row by row: {{1, 2, 3}, {4, 5, 6}}; missing values become 0.
  3. The row count may be left out: int m[][3] = {…}; — the column count may not.
  4. Nested loops: the outer loop over rows (i), the inner over columns (j).
  5. Row-major memory: m[i][j] sits at position i × columns + j.

Arrays and functions

  1. f(arr) sends the address of arr[0] — the array is never copied.
  2. So the function can change the caller's elements.
  3. Inside, sizeof cannot tell the length: pass the size as another parameter.
  4. Write const int a[] when the function must only read the array.
  5. For 2-D arrays the column count must be in the parameter: int m[][3].

Matrix operations

  1. Addition: C[i][j] = A[i][j] + B[i][j] — the same size needed.
  2. Transpose: T[j][i] = M[i][j] — rows become columns.
  3. Multiplication: C[i][j] = sum over k of A[i][k] × B[k][j].
  4. A (r × n) times B (n × c) gives r × c: the inner sizes must match.
  5. Matrix multiplication is not commutative: A × B is usually not B × A.
Walkthrough

Row sums in a function, and a transpose

Every line, explained.

1 #include <stdio.h>
2 #define R 2
3 #define C 3
4
5 void printRowSums(int m[][C], int rows) The column count is part of the parameter type.
6 {
7 for (int i = 0; i < rows; i++) {
8 int sum = 0; A fresh sum for every row.
9 for (int j = 0; j < C; j++)
10 sum += m[i][j];
11 printf("row %d: %d\n", i, sum); Prints row 0: 6 and row 1: 15
12 }
13 }
14
15 int main(void)
16 {
17 int m[R][C] = {{1, 2, 3}, {4, 5, 6}};
18 int t[C][R]; The transpose is 3 × 2.
19 for (int i = 0; i < R; i++)
20 for (int j = 0; j < C; j++)
21 t[j][i] = m[i][j]; Swap the indexes.
22 printRowSums(m, R); Only the address of m is passed.
23 printf("t[2][1] = %d\n", t[2][1]); t[2][1] = m[1][2]: prints 6
24 return 0;
25 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Swapping rows and columns

✗ Wrong
int m[2][3];
m[2][1] = 5;   // there is no row 2
✓ Right
int m[2][3];
m[1][2] = 5;   // row 1, column 2

The first index is the row (0–1 here), the second the column (0–2).

m[i, j] instead of m[i][j]

✗ Wrong
x = m[1, 2];
✓ Right
x = m[1][2];

Inside [ ] the comma is the comma operator: m[1, 2] means m[2] — a whole row.

Leaving out the column count

✗ Wrong
void show(int m[][], int r);
✓ Right
void show(int m[][3], int r);

To find m[i][j] the compiler must know the row length (i × columns + j).

Using sizeof on an array parameter

✗ Wrong
int sum(int a[]) {
    int n = sizeof a / sizeof a[0];   // wrong
    …
✓ Right
int sum(const int a[], int n) { … }

In a function a is only an address, so sizeof a is the size of a pointer. Pass the length.

Not resetting a per-row total

✗ Wrong
int sum = 0;
for (i …) { for (j …) sum += m[i][j];
            printf("%d", sum); }
✓ Right
for (i …) { int sum = 0;
            for (j …) sum += m[i][j];
            printf("%d", sum); }

Without a fresh sum each row, the second row's total includes the first.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

int m[3][4]; — how many ints does it hold?

Question 2

int m[2][3] = {{1, 2, 3}, {4, 5, 6}}; — what is m[1][0]?

Question 3

In int m[2][3], which element comes right after m[0][2] in memory?

Question 4

void z(int a[], int n) { a[0] = 0; } — int v[2] = {5, 6}; z(v, 2); What is v[0]?

Question 5

A is 2 × 3 and B is 3 × 4. What size is A × B?

Assessment

2-D Arrays & Arrays in Functions quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.