Ken - 2 months ago 13

C++ Question

`#include <iostream>`

using namespace std;

int main()

{

int x[][3]={1,2,3,4,5};

cout<<&x <<" "<<*x <<" "<<x <<endl;

cout<<&x[0]<<" "<<*x[0]<<" "<<x[0]<<endl;

cout<<&x[0][0]<<endl;

return 0;

}

The result is:

`0x28fef8 0x28fef8 0x28fef8`

0x28fef8 1 0x28fef8

0x28fef8

Why

`x[0][0]`

Answer

An array of arrays like yours look like this in memory

+---------+---------+---------+---------+---------+---------+ | x[0][0] | x[0][1] | x[0][2] | x[1][0] | x[1][1] | x[1][2] | +---------+---------+---------+---------+---------+---------+

The location of `x`

, `x[0]`

and `x[0][0]`

is all the same.

Also, arrays naturally decays to pointers to their first element. If you use plain `x`

you will get `&x[0]`

. If you use `x[0]`

you will get `&x[0][0]`

. So when you do `*x[0]`

it is the same as doing `*&x[0][0]`

, and the dereference and address-of operators cancel each other out so you are left with `x[0][0]`

, which is the value you print.

Furthermore, to help you understand why `x`

is the same as `&x[0]`

, you need to know that for any array *or pointer* `x`

and index `i`

the expressions `x[i]`

is the same as `*(x + i)`

. That means the expression `&x[i]`

is the same as `&*(x + i)`

, and since the address-of and dereference operators again cancel each other out `&x[i]`

is the same as `(x + i)`

(or without the parentheses `x + i`

). Now think of the case when `i`

is zero, then we have `&x[0]`

which is the same as `x + 0`

which is the same as `x`

. So `&x[0]`

is the same as `x`

, and vice-versa.

For others that wonders what `&x`

and `&x[0]`

and `&x[0][0]`

are representing, please see this:

+---------+---------+---------+---------+---------+---------+ | x[0][0] | x[0][1] | x[0][2] | x[1][0] | x[1][1] | x[1][2] | +---------+---------+---------+---------+---------+---------+ ^ ^ ^ ^ | | | | +- &x +- &x[0][1] +- &x+1 +- &x[1][1] | | +- &x[0] +- &x[1] | | +- &x[0][0] +- &x[1][0]

While all of `x`

, `x[0]`

, `&x`

, `&x[0]`

and `&x[0][0]`

may represent the same memory address, they are semantically different, i.e they represent different types:

`x`

is a pointer to an array of three`char`

(or`char (*)[3]`

)`x[0]`

is a pointer to`char`

(or`char *`

)`&x`

is a pointer to an array of arrays of three`char`

(or`char (*)[3][3]`

)`&x[0]`

is a pointer to an array of three`char`

(or`char (*)[3]`

)`&x[0][0]`

is a pointer to`char`

(or`char *`

)