Array of pointers and Pointer to array

An array is known as the contiguous run of elements while a pointer is an address pointing variable.
A pointer could represent the same array.

   int arr[5];
   int *a;
   a = arr;

The compiler reads arr[2] as, get the base address that is 100, next add 2 as the pointer arithmetic got 108 and then dereference it. Hence we got 30.

It’s like *(arr + 2). In the same we can also write *(a + 2) or a[2], as a = arr means a = &arr[0].
Thus an array acts like a pointer but it’s not a pointer. The difference could be seen when both passed to sizeof method. sizeof(arr) gives 20 while sizeof(a) gives 4 (for 32 bit architecture). Therefore, array names in a C program are converted mostly to pointers, leaving cases like involving sizeof operator.

Array of Pointer and Pointer to array:

  1. int *x[5]
  2. int (*x)[5]

The first one is an array of pointer while the second one is a pointer to an array of 5 blocks. Let’s understand step by step.
So in this post, the table of Precedence and Associativity of operators will be used, so it is better to go through this post to have a better understanding.
Operator [] has higher priority than *.
So in int *x[5], first x[5] is read that says an array of 5 blocks. Next an asterisk * is read, means every block of the array is a pointer. See below,

Array of Pointer
Array of Pointer

This could be seen as there are 5 different pointer variables.

In int (*x)[5], as per the table both () and [] has the same precedence, associativity comes into the picture that says left to right reading. (*x)read first means a pointer. Next [5] that says an array of 5 blocks. Therefore, it’s a pointer that points to an array of 5 blocks.

In a 2-d or multidimensional Array

int z[3][5], this is a 2-d array i.e. three 1-d arrays of 5 blocks each. To create a pointer variable pointing to this first set of 5 blocks of this 2-d array, we’ll write x = &z[0] or in other ways x = z (because starting index of 2d array and first 1d array is same).

Pointer to an array
Pointer to an array

Doing x++ here, will give z[1] i.e. the starting index of 2nd 1-d array, and for accessing any particular block using x will be like a pointer to pointer accessing. Say z[1][4], it would be *(*(x+1)+4) or simply x[1][4].

Interesting Problems:

Try to find the answer by yourself, then run these problems and use solution hint/output.


int main(void) {
  int a[5];
  printf("%u %u %u %u\n", (void*)a, (void*)(a+1), (void*)(&a), (void*) (&a+1));

Solution Hint-

Here, a+1 and (&a+1), both are very different, a is like a pointer while &a is like pointer to an array of 5 blocks i.e. (*)[5]. Thus &a+1 result a jump of 5*4(for 32 bit).

Problem 2:

int main()
	int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {0, 0, 0}};
	int (*p)[3] = arr;
	printf("%d  %d  %d\n", (*p)[0], *(p[1]+1), (*p)[2]);
	printf("%d  %d  %d\n", (*p)[-1], (*p)[1], (*p)[2]);  
	/* (*p)[-1] write it as *(*(p + 0)-1) */	
	return 0;
1  5  3
3  5  6

Problem 3:

int main(void)
	int a[5] = { 0, 1, 2, 3, 4 };
	int *p[5] = { a, a+2, a+1, a+4, a+3};

	printf("%u %u %u %u %u\n",&a[0], &a[2], &a[1], &a[4], &a[3]);
	printf("%u %u %u %u %u", p[0], p[1], p[2], p[3], p[4]);
	return 0;

Solution Hint-

Both the printf statement will give the same output, as p is array of pointer.

Knowledge is most useful when liberated and shared. Share this to motivate us to keep writing such online tutorials for free and do comment if anything is missing or wrong or you need any kind of help.
Keep Learning… Happy Learning.. :)