-edit-
For the answer to OP search for 'Updated' and read from there.
Continue from here if you want to know about how multidimensional arrays are stored in memory in C.
I had separated the answer from this long explanation but consecutive posts are merged.
-edit-
Look at it this way to understand arrays and how they are stored in the memory.
C uses Row-major order for storing multidimensional arrays.
http://en.wikipedia.org/wiki/Row-major_order
1-D Array of int a[4] = {1,2,3,4}
this is stored in a linear manner in the memory starting from a[0] = 1 to a[3] = 4.
Memory location | x | x+4 | x+8 | x+12 |
Array addressing | a[0] | a[1] | a[2] | a[3] |
Value | 1 | 2 | 3 | 4 |
The memory location of a[0] is 'x' which can change but the difference between the two consecutive elements of the
int array will always be 4 (sizeof(int) = 4 ). If it was a
char the difference would have been 1 (sizeof(char) = 1).
2-D Array of int a[2][2] = {{1,2},{3,4}}
Memory location | x | x+4 | x+8 | x+12 |
Array addressing | a[0][0] | a[0][1] | a[1][0] | a[1][1] |
Value | 1 | 2 | 3 | 4 |
This is stored as two 1-D arrays one after the other. a[0][] followed by a[1][].
3-D Array of int a[2][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}}}
Memory location | x | x+4 | x+8 | x+12 | x+16 | x+20 | x+24 | x+28 |
Array addressing | a[0][0][0] | a[0][0][1] | a[0][1][0] | a[0][1][1] | a[1][0][0] | a[1][0][1] | a[1][1][0] | a[1][1][1] |
Value | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
This is stored as two 2-D arrays one after the other. a[0][][] followed by a[1][][].
The 2-D arrays are again stored as two 1-D arrays one after the other.a[0][0][] followed by a[0][1][] followed by a[1][0][] followed by a[1][1][].
Answer in the next post. Keeping this as it is.
- - - Updated - - -
The answer lies in how pointer addition/subtraction takes place using implicit sizeof(datatype).
Consider a 1D array int a[2].
suppose a[0] is at memory location x, then a[1] is actually located at a[0] + 4. 4 being sizeof(int).
Even if it was a 1D array of a structure (struct xyz), the n[SUP]th[/SUP] element is always accessed using the base address of a[0] and adding ((n-1)*sizeof(struct xyz)) to it.
Now consider a 2D array int b[2][3].
Here b[0] is actually of the type int [
3]. To access b[1] the compiler takes the base address of b[0] and adds the 3*sizeof(int) which is actually 12.
luster had the correct idea when he said that we divide the memory address difference by 4 to get the answer, but that holds true for a 2D int array because sizeof(int) = 4. The same can be applied in the above example and b[1] -b[0] comes out to be
3.
For a 3D array c[2][3][2],
c[0] is of the type
int [3][]. The second bracket is blank because it can be anything, in this case it is int [2]. c[1] is calculated using address of c[0] and adding into it 3*sizeof(int [2]) which is 3*
8 = 24.
c[0] has 3 elements each of type int[2]. Hence c[1] - c[0] = (Memory difference in bytes)/(sizeof (int[2]).
Generalizing the above statement, the element which comprises of an array can be anything, like a char,int,float,struct,another array etc...
this also gives the answer for c[1][0]-c[0][0] where we divide the memory difference by 4.
I hope this clears the doubt. Thanks to
manojkrishnaks for this question which increased my knowledge of C a bit more.