Multi-dimensional arrays in C C does not have true multi-dimensional arrays. Instead use a one dimensional array, each of whose elements are arrays. /* 1 dim */ int a[/* 2 optional */] = {80,81}; array a[]: a[0] a[1] contents: 80 81 /* 2 dim */ int b[/* 2 optional */] = {{80,81,82},{90,91,92}}; /* or this: */ = { 80,81,82 , 90,91,92 }; results in an array of 2 elements each of whose elements is an int c[3], an array of three elements: array a[]: a[0]--------------------| a[1]--------------------| array a[][]: a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] contents: 80 81 82 90 91 92 The elements are in lexicographical or row major order (the last index, the column index, moves fastest). a[1][0] refers to 90: It is the same as contents of a + 1*3 + 0 pointer + int + int a[1] is a pointer to the second row (starting with 90) a is a pointer to the first element (80). a[r][c] or (a[r])[c] both mean: * (a + r * sizeof(int[][3]) + c * sizeof(int)) where sizeof(int[][3]) is same as 3 * sizeof(int) In function calls and declarations: If the call is g(a[1][0]) then the declaration is g(int x). If the call is f(a) then the declaration is f(int a[2][3]) but the 2 is ignored OR f(int a[][3]) OR f(int (*a)[3]) which is the form the previous are converted to. BUT NOT: f(int *a[3]) which makes "a" an array of 3 pointers to int. Similar considerations apply for high dimensions. An argv array is not a multi-dimensional array; it is an array of pointers to characters, that is, an array of pointers to strings (which are arrays (of varying lengths) of characters).