int q[10]={0};
cout << q << endl;
cout << &q << endl;
cout << &q[0] << endl;
output is
0x7fffd4d2f860
0x7fffd4d2f860
0x7fffd4d2f860
Now when i do this->
int *r=q; // allowed
int *r=&q[0] // allowed
int *r=&q // not allowed
Why is the third assignment not allowed when it is essentially the same thing?
If you have an array declared like
T a[N];
where T
is some type specifier then a pointer to the array will be declared like
T ( *p )[N] = &a;
A general rule is the following. If you have a multidimensional array (including one-dimensional arrays) like for example
T a[N1][N2][N3];
then this declaration you may rewrite like
T ( a[N1] )[N2][N3];
To get a pointer to the first element of the array just substitute the content in the parentheses the following way
T ( *p )[N2][N3] = a;
If you want to get a pointer to the whole array then rewrite the declaration of the array like
T ( a )[N1][N2][N3];
and make the substitution
T ( *p )[N1][N2][N3] = &a;
Compare this with a declaration of a scalar object and a pointer to it.
For example
T obj;
You may rewrite the declaration like
T ( obj );
Now to get a pointer to the object you can write
T ( *p ) = &obj;
Of course in this case the parentheses are redundant and the above declaration is equivalent to
T *p = &obj;
As for this code snippet
int q[10]={0};
cout << q << endl;
cout << &q << endl;
cout << &q[0] << endl;
and its output
0x7fffd4d2f860
0x7fffd4d2f860
0x7fffd4d2f860
then array designators used in expressions with rare exceptions are converted to pointers to their first elements.
So in fact the two expression q
and &q[0]
in these statements
cout << q << endl;
cout << &q[0] << endl;
are equivalent. On the other hand, the address of the array itself is the address of the memory extent that the array occupies. And in the beginning of the extent there is the first element of the array. So the three expressions give the same result: the address of the extent of memory occupied by the array.