A[0], &A, *A all are pointers of distinct types that all point to the same memory location. Same value (sort of), different types.
Expression Symmetric Type
----------------------------------------------------------------------------
A address of first row. int[5][5]
&A[0][0] address of first element int*
&A address of 2d array int(*)[5][5]
*A = *( A + 0) = A[0] = address of first element int[5] = decays to int*
in a expression
My example of 5*4 dimension char arrays:
A
+---201---202---203---204---206--+
201 | +-----+-----+-----+-----+-----+|
A[0] = *(A + 0)--►| 'f' | 'o' | 'r' | 'g' | 's' ||
207 | +-----+-----+-----+-----+-----+|
A[1] = *(A + 1)--►| 'd' | 'o' | '\0'| '\0'| '\0'||
213 | +-----+-----+-----+-----+-----+|
A[2] = *(A + 2)--►| 'n' | 'o' | 't' | '\0'| '\0'||
219 | +-----+-----+-----+-----+-----+|
A[3] = *(A + 3)--►| 'd' | 'i' | 'e' | '\0'| '\0'||
| +-----+-----+-----+-----+-----+|
+--------------------------------+
A brief explanation about figure example.
- In figure
A represents complete 2-D array starts with address 201, and
&A gives address of complete 2-D array = 201
*A = *(A + 0) = A[0] points to first row = 201
- Note value
A[0][0] is 'f' in my example, and &A[0][0] gives address of [0][0] element = 201
- Note
&A[0][0] is same as *A, because &A[0][0] => &(*(*A)) => &**A => *A
So all A[0], &A, *A, A are same but symmetrically different.
To observe difference among the A[0], &A, *A, A. Type to print sizeof() information. e.g.
cout<<sizeof(A[0]) <<" "<<sizeof(&A) <<" "<<sizeof(*A) <<" "<< sizeof(A);
Second try to print next location address using:
cout<<(A[0] + 1)<<" "<<(&A + 1) <<" "<<(*A + 1)<<" "<<(A + 1);
For more detailed explanation, must read this answer.