The type of the object pointed to by the pointer declared like
int (*pointer_name)[5] = &array_name;
is int[5] . This means for example that this operator
sizeof( *pointer_name )
yields the value equal to 5 * sizeof( int ). And that if to use the pointer arithmetic as for example pointer_name + 1 then the address obtained by this expression will be equal to the address stored in the pointer plus value of 5 * sizeof( int ).
The type of the object pointed to by the pointer declared like
int *pointer_name = array_name;
is int . This means for example that this operator
sizeof( *pointer_name )
yields the value equal to sizeof( int ). And that if to use the pointer arithmetic as for example pointer_name + 1 then the address obtained by this expression will be equal to the address stored in the pointer plus value of sizeof( int ).
A pointer declared like this
int (*pointer_name)[5];
usually used for two-dimensional arrays that points to "rows" of array.
For example
int array_name[2][5];
int (*pointer_name)[5] = array_name;
// outputs 20 provided that sizeof( int ) is equal to 4
printf( "%zu\n", sizeof( *pointer_name ) );
// outputs 4 provided that sizeof( int ) is equal to 4
printf( "%zu\n", sizeof( **pointer_name ) );
pointer_name points to the first row of the array array_name. pointer_name + 1 points to the second row of the array.
array_name[0]in certain contexts, but not in all contexts. And you definitely cannot say that the name of the array is the address ofarray_name[0].