Each element of a two-dimensional array has its own memory address. In C, the elements are stored contiguously in row-major order, meaning that the elements of one row are followed by the elements of the next row.
#include <stdio.h>
int main(void)
{
int matrix[2][3] = {
{10, 20, 30},
{40, 50, 60}
};
printf("Address of matrix[0][0]: %p\n",
(void *)&matrix[0][0]);
printf("Address of matrix[0][1]: %p\n",
(void *)&matrix[0][1]);
printf("Address of matrix[0][2]: %p\n",
(void *)&matrix[0][2]);
printf("Address of matrix[1][0]: %p\n",
(void *)&matrix[1][0]);
return 0;
}
Example Output #
On a typical implementation where sizeof(int) is 4 bytes, the addresses might look like this:
Address of matrix[0][0]: 0x7ffe12345000
Address of matrix[0][1]: 0x7ffe12345004
Address of matrix[0][2]: 0x7ffe12345008
Address of matrix[1][0]: 0x7ffe1234500c
The actual addresses vary between executions and implementations.
Explanation #
The expression:
&matrix[0][0]
obtains the address of the first element.
The expression:
&matrix[1][0]
obtains the address of the first element in the second row. Because the array contains three integers per row, this address is three integer elements after the first element’s address.
Address Reference #
| Expression | Meaning |
|---|---|
&matrix[0][0] |
Address of the first element |
&matrix[0][1] |
Address of the second element in row 0 |
&matrix[0][2] |
Address of the third element in row 0 |
&matrix[1][0] |
Address of the first element in row 1 |
matrix[0] |
Converts to a pointer to the first element of row 0 in most expressions |
matrix |
Converts to a pointer to the first row in most expressions |
The distinction between matrix and &matrix[0][0] matters for pointer arithmetic:
matrix + 1advances by one entire row.&matrix[0][0] + 1advances by one integer element.
For a declaration of int matrix[2][3], the row type is int[3]. Consequently, a pointer to a row and a pointer to an individual integer have different types and different arithmetic behavior.