Array of pointers : (let's assume it's data type is int)
int *array_of_pointers[4];
We know that pointer holds a address of int data type variable. So the above mentioned array_of_pointers can store four different or same int data type address i.e. array_of_pointers[0], array_of_pointers[1], array_of_pointers[2] array_of_pointers[3] each can hold a int data type address.
For example:
int variable_one;
int variable_two;
int variable_three;
int variable_four;
So we have four different variable which are of type int so we can assign these to the above declared array_of_pointers
i.e. array_of_pointers[0] = &variable_one
This is similar to declaring four different int pointers but instead we used an array to hold these four pointers.
Pointer to array :
int[4] *pointer_to_array; or
int ( *pointer_to_array)[4];
In simple language the pointer_to_array is a single variable that holds the address of the array.
Example:
int simple_array[4];
Now we can assign
pointer_to_array = simple_array; or
pointer_to_array = &simple_array[0];
Hope you get the difference.
Edit 1 :
In pointer to an integer if pointer is incremented then it goes next address which is differ by integer size.
For example consider pointer ptr holds 22 as address and integer size is 2 then after ptr++ we get 22+2( int size) = 24 as next address.
in array of pointer if pointer is incremented it jumps to next address which is differ by size of array.
For example consider pointer ptr holds 22 as address and integer array size is 4 elements, we already assumed int size is 2 then after ptr++ we get 22+4*2 ( total size of array ) = 30 as next address.
int *array_of_pointers[4];
We know that pointer holds a address of int data type variable. So the above mentioned array_of_pointers can store four different or same int data type address i.e. array_of_pointers[0], array_of_pointers[1], array_of_pointers[2] array_of_pointers[3] each can hold a int data type address.
For example:
int variable_one;
int variable_two;
int variable_three;
int variable_four;
So we have four different variable which are of type int so we can assign these to the above declared array_of_pointers
i.e. array_of_pointers[0] = &variable_one
This is similar to declaring four different int pointers but instead we used an array to hold these four pointers.
Pointer to array :
int[4] *pointer_to_array; or
int ( *pointer_to_array)[4];
In simple language the pointer_to_array is a single variable that holds the address of the array.
Example:
int simple_array[4];
Now we can assign
pointer_to_array = simple_array; or
pointer_to_array = &simple_array[0];
Hope you get the difference.
Edit 1 :
In pointer to an integer if pointer is incremented then it goes next address which is differ by integer size.
For example consider pointer ptr holds 22 as address and integer size is 2 then after ptr++ we get 22+2( int size) = 24 as next address.
in array of pointer if pointer is incremented it jumps to next address which is differ by size of array.
For example consider pointer ptr holds 22 as address and integer array size is 4 elements, we already assumed int size is 2 then after ptr++ we get 22+4*2 ( total size of array ) = 30 as next address.