Nearby lessons

59 of 124

C - Multidimensional Array

Multidimensional arrays in C — arrays with three or more dimensions. Learn the 3D array declaration, how to visualise it as a stack of tables, its memory layout, and when the extra dimensions are worth it.

Beyond Two Dimensions

C puts no practical limit on dimensions — the standard guarantees at least 12. Each pair of brackets adds a level:

DeclarationDimensionsMental pictureElements
int a[5]1A row5
int a[3][4]2A table12
int a[2][3][4]32 stacked tables24
int a[2][2][3][4]42 groups of 2 tables48
In simple words: read the dimensions left to right as "how many of the next thing". int a[2][3][4] is 2 tables, each with 3 rows, each row holding 4 numbers.

Declaring and Initialising a 3D Array

Nest the braces one level deeper than for a 2D array — an outer group per table, an inner group per row:

Example02
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 int a[2][3][4] = {
6 { /* table 0 */
7 { 1, 2, 3, 4},
8 { 5, 6, 7, 8},
9 { 9, 10, 11, 12}
10 },
11 { /* table 1 */
12 {13, 14, 15, 16},
13 {17, 18, 19, 20},
14 {21, 22, 23, 24}
15 }
16 };
17 
18 printf("a[0][1][2] = %d\n", a[0][1][2]);
19 printf("a[1][2][3] = %d\n", a[1][2][3]);
20 printf("Total elements: %zu\n", sizeof(a) / sizeof(int));
21 return 0;
22}
Output
a[0][1][2] = 7
a[1][2][3] = 24
Total elements: 24

Traversing with Three Nested Loops

One loop per dimension. The outermost walks tables, the middle walks rows, the innermost walks columns:

Example03
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 int a[2][3][4] = {
6 {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
7 {{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}
8 };
9 int i, j, k;
10 
11 for (i = 0; i < 2; i++) /* tables */
12 {
13 printf("Table %d:\n", i);
14 for (j = 0; j < 3; j++) /* rows */
15 {
16 for (k = 0; k < 4; k++) /* columns */
17 printf("%4d", a[i][j][k]);
18 printf("\n");
19 }
20 printf("\n");
21 }
22 return 0;
23}
Output
Table 0:
   1   2   3   4
   5   6   7   8
   9  10  11  12

Table 1:
  13  14  15  16
  17  18  19  20
  21  22  23  24

Memory Layout — Rightmost Index Varies Fastest

Memory is still a single flat block. C fills it by incrementing the last index first, then the middle, then the first:

Example04
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 int a[2][2][3] = {
6 {{1, 2, 3}, {4, 5, 6}},
7 {{7, 8, 9}, {10, 11, 12}}
8 };
9 int *flat = (int *) a; /* view it as one long row */
10 int i;
11 
12 printf("Flat order: ");
13 for (i = 0; i < 12; i++) printf("%d ", flat[i]);
14 printf("\n");
15 return 0;
16}
Output
Flat order: 1 2 3 4 5 6 7 8 9 10 11 12 

The Flat Position Formula

For int a[D1][D2][D3], element a[i][j][k] lives at flat offset:

(i × D2 × D3) + (j × D3) + k

Example05
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 int a[2][2][3] = {
6 {{1, 2, 3}, {4, 5, 6}},
7 {{7, 8, 9}, {10, 11, 12}}
8 };
9 int *flat = (int *) a;
10 int i = 1, j = 0, k = 2;
11 int offset = (i * 2 * 3) + (j * 3) + k;
12 
13 printf("a[%d][%d][%d] = %d\n", i, j, k, a[i][j][k]);
14 printf("flat[%d] = %d\n", offset, flat[offset]);
15 return 0;
16}
Output
a[1][0][2]  = 9
flat[8]      = 9

A Practical Example — Marks by Class

Three dimensions map naturally onto real data: class → student → subject:

Example06
CCode Cell
1#include <stdio.h>
2 
3#define CLASSES 2
4#define STUDENTS 3
5#define SUBJECTS 2
6 
7int main()
8{
9 int marks[CLASSES][STUDENTS][SUBJECTS] = {
10 {{85, 90}, {78, 82}, {92, 88}}, /* class A */
11 {{70, 75}, {88, 91}, {65, 72}} /* class B */
12 };
13 int c, s, sub, total;
14 
15 for (c = 0; c < CLASSES; c++)
16 {
17 printf("Class %c\n", 'A' + c);
18 for (s = 0; s < STUDENTS; s++)
19 {
20 total = 0;
21 for (sub = 0; sub < SUBJECTS; sub++)
22 total += marks[c][s][sub];
23 printf(" Student %d total: %d\n", s + 1, total);
24 }
25 }
26 return 0;
27}
Output
Class A
  Student 1 total: 175
  Student 2 total: 160
  Student 3 total: 180
Class B
  Student 1 total: 145
  Student 2 total: 179
  Student 3 total: 137

Passing to a Function

Only the first dimension may be omitted. All the rest are needed so C can compute offsets:

Example07
CCode Cell
1#include <stdio.h>
2 
3/* [3][4] must both be stated; the first pair may be empty */
4void print3D(int a[][3][4], int tables)
5{
6 int i, j, k;
7 for (i = 0; i < tables; i++)
8 for (j = 0; j < 3; j++)
9 {
10 for (k = 0; k < 4; k++) printf("%4d", a[i][j][k]);
11 printf("\n");
12 }
13}
14 
15int main()
16{
17 int a[1][3][4] = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}};
18 print3D(a, 1);
19 return 0;
20}
Output
   1   2   3   4
   5   6   7   8
   9  10  11  12

When Not to Use Them

Multidimensional arrays are simple but rigid. Watch out for these limits:

  • Memory grows multiplicativelyint a[100][100][100] is a million ints, about 4 MB, and will overflow the stack as a local.
  • Hard to read past three dimensionsa[i][j][k][l][m] is a maintenance problem.
  • Every dimension is fixed at compile time — a jagged structure needs an array of pointers instead.
  • All dimensions must be stated in parameters — that couples your functions to exact sizes.
Large multidimensional arrays crash as locals. A typical stack is 1–8 MB, so int a[500][500][10]; (about 10 MB) overflows it immediately. Declare big arrays as static, make them global, or allocate them with malloc.
📝 Key Takeaways
  • Syntax: type name[d1][d2][d3]... — C allows at least 12 dimensions.
  • Read int a[2][3][4] as 2 tables of 3 rows and 4 columns.
  • Total elements = the product of all dimensions.
  • Storage is row-major: the rightmost index varies fastest.
  • All dimensions except the first are required in a function parameter.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4