5.1.11C Programming

Multi-dimensional arrays

1,792 words8 min readdifficulty · medium

WHAT is a multi-dimensional array?

WHY does C call it "array of arrays"? Because C only truly has 1D arrays. int a[3][4] is read as int (a[3])[4] — an array of 3 things, where each thing is int[4]. This single fact explains everything below.


HOW is it stored? (Row-major order)

C lays the elements out row by row. This is called row-major order.

For int a[3][4], memory order is:

a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] ... a[2][3]
Figure — Multi-dimensional arrays

The pointer view (WHY a[i][j] works)

In C, a[i] is exactly *(a + i) and a[i][j] is *(*(a+i)+j).


Declaring & initializing

int m[2][3] = { {1, 2, 3},
                {4, 5, 6} };          // explicit, clearest
 
int n[2][3] = {1, 2, 3, 4, 5, 6};     // same data, flat list (row-major fill)
 
int z[2][3] = {0};                    // all zero
 
int p[][3] = {{1,2,3},{4,5,6}};       // first dim inferred = 2; inner dim MUST be given

Passing to functions

void print(int rows, int cols, int a[][cols]);   // C99 VLA param, or:
void print2(int a[][4], int rows);               // fixed inner dimension

WHY you must specify the inner dimension(s): the function only receives a pointer (a decays to int(*)[4]). To compute a[i][j] inside, the compiler still needs CC to do iC+j.


Recall Feynman: explain to a 12-year-old

Imagine a long shelf with 12 boxes in a row. You pretend it's 3 shelves of 4 boxes to make it easy to talk about "row 2, box 1". But really it's one straight line! To find box "row 2, box 1", you count: skip 2 whole shelves (that's 2×4=82\times4=8 boxes) then move 1 more — box number 9. The computer does this counting trick every time you write a[2][1]. That's why it must know how many boxes are on each shelf (the columns), but it doesn't care how many shelves there are.


Flashcards

How does C store a 2D array in memory?
As one contiguous block in row-major order — all of row 0, then all of row 1, etc.
Why must you specify the column size (but not the row size) when declaring int a[][C] or a parameter?
Address = base + (i*C + j)*size; computing it needs C but never R, so R may be omitted.
What is the address formula for a[i][j] in T a[R][C] with base B?
B+(iC+j)sizeof(T)B + (i\cdot C + j)\cdot \text{sizeof}(T).
Rewrite a[i][j] using pointers only.
*(*(a + i) + j).
For int a[3][4], what type does a decay to?
int (*)[4] — pointer to an array of 4 ints.
What does a[1,2] mean in C and why?
It's the comma operator: 1,2 evaluates to 2, so it means a[2] (a whole row), NOT element (1,2).
3D address: for a[i][j][k] in T a[X][Y][Z], what multiplies index i?
YZY\cdot Z (product of all dimensions to its right).
In int m[2][3]={1,2,3,4,5,6}; what is m[1][0]?
4 (flat list fills row-major: row1 = {4,5,6}).

Connections

  • C Arrays (1D) — multi-D is just an "array of arrays".
  • Pointers in C — subscripting is pointer arithmetic.
  • Array Decay — why a becomes int(*)[C] when passed.
  • Pointer to Array vs Array of Pointersint (*p)[4] vs int *p[4].
  • sizeof Operator — element & whole-array size.
  • Row-major vs Column-major — C vs Fortran/MATLAB storage.
  • Variable Length Arrays (C99)int a[][cols] parameters.

Concept Map

is really

because C has only

stored as

laid out by

gives formula

needs only

omits

so you must pass

indexed via

equivalent to

a+i jumps

fills

Multi-dim array

Array of arrays

1D arrays

Contiguous flat memory

Row-major order

addr = base + i*C + j *s

Column count C

Row count R

All dims except first

a i j

*( *(a+i) + j )

One full row

Initializer lists

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, multi-dimensional array sunne mein lagta hai jaise grid (rows aur columns) hai, par C ke andar actually wo ek lambi single line of memory hoti hai. Jaise int a[3][4] matlab 12 ints ek ke baad ek rakhe hain — pehle poori row 0, phir row 0, phir row 1, phir row 2. Isko row-major order kehte hain. Grid sirf hamare sochne ke liye hai; computer toh seedhi line par count karta hai.

Ab address kaise nikalta hai? Maan lo tumhe a[i][j] chahiye. Pehle i poori rows skip karo — har row mein C elements hote hain, toh i*C elements jump. Phir us row ke andar j aur aage badho. Total skip = i*C + j elements, aur bytes ke liye sizeof se multiply: address = base + (i*C + j)*sizeof(int). Yahaan dhyan do — formula mein rows ki ginti R kahin nahi aati, sirf columns C aata hai. Isi liye function mein ya declaration mein tumhe column size dena zaroori hai, row size optional.

Ek common galti: log a[1,2] likh dete hain (Python/MATLAB ki aadat). C mein , comma operator hai, toh 1,2 ka matlab sirf 2 ban jaata hai aur a[1,2] actually a[2] ho jaata hai — pura row! Sahi tareeka hai a[1][2]. Doosri galti: int a[][] likhna — inner dimension blank nahi chhod sakte, warna compiler i*C+j calculate hi nahi kar paayega.

Yaad rakhne ka mantra: "Rows Run first, Columns Count." 3D ke liye rule simple extend hota hai — har index ko uske right wali saari dimensions ke product se multiply karo. Bas yahi pura khel hai!

Go deeper — visual, from zero

Test yourself — C Programming

Connections