I have the following code snippet:
char board[3][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
printf("address of board : %p\n", &board);
printf("address of board[0] : %p\n", &board[0]);
Both printf()
statements all print the same value: 0x0013ff67
As per my knowledge, board (i.e) array name represents the address of the first subarray (i.e) board[0]
and
board[0]
represents the address of first element in the first array (i.e) board[0][0]
Why am I getting the same address in all my printf()
statements? I expect different addresses for both statements.
I am pretty new to this stuff and don't understand this behavior. Kindly enlighten me.
Though it's a 2D array, inside the memory it will be represented as linear array. so when you say, board[0][0] it still points to the first element in that linear array and hence the same memory address.
As per my knowledge, board (i.e) array name represents the address of the first subarray (i.e) board[0]
This is only true if board
is used outside of these contexts
- As operand of the
&
operator
- As operand of
sizeof
When any of that applies, expression board
represents the array and keeps having the type of the array (char[3][3]
). Applying the &
operator to it results in getting the address of the array, which of course equals the address of its first element, merely having a different type (char(*)[3][3]
instead of char(*)[3]
). The same that is true about the array board
is true about its first sub array board[0]
.
When you use it outside of those contexts, you get the address of the first element (subarray in your case). That address is not an object but just a value. Value have no address, but objects have. Trying to apply &
on it would fail. For example
// error: trying to apply '&' on something that has no address
&(1 ? board : board)
Note that anything said above applies to C; not necessarily to C++.
Of course this will print the same address.
Think about 2D arrays like this for a minute,
int **ptr;
The address *ptr
does equal &(**ptr)
.
Because basically, that's what your code is doing.
and remember that in memory, 2D arrays will be mapped linearly.
It may be the case that you know an object-oriented language such as Java or Python, and now you are learning the C language. The difference between Java and C when thinking about char board[3][3]
is that in C the board
variable is represented in memory as 9 characters at adjacent memory addresses. Like so:
board: 1 2 3 4 5 6 7 8 9
In C, &board
yields the same memory address as &board[0]
and &board[0][0]
.
In contrast to this, in Java the variable would be declared as char[][] board
and its memory representation would conceptually look like this:
board: ptr(A) ptr(B) ptr(C)
A: 1 2 3
B: 4 5 6
C: 7 8 9
where ptr(x)
points to memory address of x
. So, in Java, board
points to a different memory address than board[0]
.
You say In C, &board yields the same memory address as &board[0] and &board[0][0]. But i am able to access the first element only via board[0][0] (or) *board[0] (or) **board. Why is it so??
Although the expressions &board
and &board[0]
and &board[0][0]
yield the same address, the type system of the C language is preventing you from accessing the char
value. In a C compiler, the types are (conceptually):
board: type char[3][3]
board[0]: type char[3]
board[0][0]: type char
Assuming a variable of type char
, we can write:
char c;
c = board[0][0];
but cannot write:
char c;
c = board; // Error
c = board[0]; // Error
because the type on the left side is incompatible with the type on the right side of the assignment.
If you are sure that an address points to a char
, you can use a type cast:
char c;
c = *(char*)board; // Works OK
c = *(char*)board[0]; // Works OK
The downside is that such type casts may lead to coding bugs.