Arrays are not pointers actually, though they tend to act in a bit similar way, but not always.
Say you have this array and a pointer:
int a[] = {1, 2, 3};
int i = 19;
int *ptr = &i;
Now here a is equal to &a
, but the same is not true, for pointers (ptr is not equal to &ptr
).
Now coming to the question:
Consider a single dimensional array:
int arr[] = {11, 19, 5, 9};
Here, this array elements are stored in contiguous memory locations. Say, with starting address 0
:
---------------------
| 11 | 19 | 5 | 9 |
---------------------
0 4 8 12 16
Now when you write name of the array, arr (for this example), you will get the starting address of the 1st element. Though if you write &arr
, then you get the starting address of the whole block(this includes all the elements of the array). Now when you write *arr
, you actually get the value inside the 1st element of this array.
Now consider this 2-dimensional array arr[][4] = {{11, 19, 5, 9}, {5, 9, 11, 19}}:
0 4 8 12 16 -> These are memory addresses
---------------------
| 11 | 19 | 5 | 9 | ----> These values represent the values inside each index
---------------------
| 5 | 9 | 11 | 19 |
---------------------
16 20 24 28 32
Here, when you write the name of the array, as arr
, what you get is the address of the 1st element of this array, which in this case will be address of this 0th index:
0 16 32
----------------------------------------------
| 0<sup>th</sup> index | 1<sup>st</sup> index |
----------------------------------------------
Now when you do &arr
, here what you get is the base address for whole of the block, i.e. base address of this:
0 4 8 12 16
---------------------
| 11 | 19 | 5 | 9 |
---------------------
| 5 | 9 | 11 | 19 |
---------------------
16 20 24 28 32
Now, if you do *arr
, in 1-dimensional array it gives you the value inside the 1st element, though in 2-dimensional array, the value inside each index is actually one 1-dimensional array, hence you will get the address of this array:
0 4 8 12 16
---------------------
| 11 | 19 | 5 | 9 |
---------------------
Now if you do **arr
, that is when you will actually get the value inside the 1st element, which is 11
.
I hope it clears some doubts :-)
EDIT 1:
As brought to my attendtion, by fellow user, it seems there is a bit of a confusion somewhere, though I have explained in detail what is meant by what thingy. But just to justify, for this statement:
Now here __a is equal to &a__, but the same is not true, for pointers (__ptr is not equal to &ptr__).
The types of both a
and &a
will be different, as already stated, in the answer. If one performs pointer arithmetics, one will able to know that. Try performing a + 1
and &a + 1
, how they both react to pointer arithmetics will surely give a good idea.
Considering a 1-dimensional array:
int arr[] = {11, 19, 5, 9};
---------------------
| 11 | 19 | 5 | 9 |
---------------------
0 4 8 12 16
We cannot do a++
, though for a pointer:
int i = 4;
int *ptr = &i;
we can perform ptr++
, this will make ptr
point to the next memory location.