Pointer to array and pointer to first element of array both are different. In case of int (*arr)[5]
, arr
is pointer to chunk of memory of 5
int
. Dereferencing arr
will give the entire row. In case of int arr[5]
, arr
decays to pointer to first element. Dereferencing arr
will give the first element.
In both cases starting address is same but both the pointers are of different type.
Is it the same if i declare int arr[5]
where arr
is the pointer to the first element? is arr
from both example are same? if not, then what exactly is a pointer to an array?
No. To understand this see the diagram for the function1:
void f(void) {
int matrix[4][2] = { {0,1}, {2,3}, {4,5}, {6,7} };
char s[] = "abc";
int i = 123;
int *p1 = &matrix[0][0];
int (*p2)[2] = &matrix[0];
int (*p3)[4][2] = &matrix;
/* code goes here */
}

All three pointers certainly allow you to locate the 0
in matrix[0][0]
, and if you convert these pointers to ‘byte addresses’ and print them out with a %p
directive in printf()
, all three are quite likely to produce the same output (on a typical modern computer). But the int *
pointer, p1
, points only to a single int
, as circled in black. The red pointer, p2
, whose type is int (*)[2]
, points to two int
s, and the blue pointer -- the one that points to the entire matrix -- really does point to the entire matrix.
These differences affect the results of both pointer arithmetic and the unary *
(indirection) operator. Since p1
points to a single int
, p1 + 1
moves forward by a single int
. The black circle1 is only as big as one int
, and *(p1 + 1)
is just the next int, whose value is 1. Likewise, sizeof *p1
is just sizeof(int)
(probably 4).
Since p2
points to an entire ‘array 2 of int’, however, p2 + 1
will move forward by one such array. The result would be a pointer pointing to a red circle going around the {2,3}
pair. Since the result of an indirection operator is an object, *(p2 + 1)
is that entire array object, which may fall under The Rule. If it does fall under The Rule, the object will become instead a pointer to its first element, i.e., the int
currently holding 2
. If it does not fall under The Rule -- for instance, in sizeof *(p2 + 1)
, which puts the object in object context -- it will remain the entire array object. This means that sizeof *(p2 + 1)
(and sizeof *p2
as well, of course) is sizeof(int[2])
(probably 8).
1 Above content has been taken from More Words about Arrays and Pointers.