Program 1
int ptr[12];
$\rightarrow$ ptr is the name of the array which acts as a constant pointer that points to the first element of the array. i.e. stores the address of 1st element.
$\rightarrow$ (ptr+i) means move i address locations forward.
$\rightarrow$ (ptr+i)∗ means access the value present at that location.i.e. ptr[i] or i[ptr].
$\rightarrow$ For eg if array's 1st element is stored at 100 and int takes 2 bytes then (ptr+5) = 100 + 2*5 = 110 i.e. the address of the 6th element of the array.
$\rightarrow$ (ptr+5)∗ means access the value present at location 110. i.e ptr[5].
*(ptr+5)==*(ptr+3)
$\rightarrow$ Since we have declared ptr as global. So by default each element of the array will store 0 so this returns true.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Program 2
int *ptr[12];
$\rightarrow$ Here ptr is an array of size 12 where each element of the array i.e. ptr[i] is a pointer that can point to an integer value.
$\rightarrow$ So (ptr+i) means we move to the address location which is i steps ahead in the array.
$\rightarrow$ For eg if array's 1st element(i.e. a pointer) is stored at 1000 and int pointer takes 2 bytes then (ptr+5) = 1000 + 2*5 = 1010 i.e. the address of the 6th element(which is also a pointer i.e. stores an address)
$\rightarrow$ (ptr+5)∗ means access the value present at location 1010. i.e ptr[5] which also contains a location(address).
*(ptr+5)==*(ptr+3)
$\rightarrow$ Since we have declared ptr as global. so by default each pointer i.e. each element of the pointer array will point to NULL so this returns true.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Program 3
int **ptr[12];
$\rightarrow$ Here ptr is an array of size 12 where each element of the array i.e. ptr[i] is a pointer that can point to a 1D array.
$\rightarrow$ So (ptr+i) means we move to the address location which is i steps ahead in the array.
$\rightarrow$ For eg if array's 1st element(i.e. a pointer to 1D array) is stored at 1000 and int pointer takes 2 bytes then (ptr+5) = 1000 + 2*5 = 1010 i.e. the address of the 6th element(which is also a pointer to 1D array i.e. stores the address of starting location of a 1D array)
$\rightarrow$ (ptr+5)∗ means access the value present at location 1010. i.e ptr[5] which is also a address of 1D array.
*(ptr+5)==*(ptr+3)
$\rightarrow$ Since we have declared ptr as global. so by default each pointer i.e. each element of the pointer array will point to NULL so this returns true.
$\rightarrow$ Suppose if the ptr[3] stores the address of a 1D that contains 5 elements and we want to obtain the value of 2nd element in that 1D array i.e a[1] then we would write like
*(*(ptr+3) + 1)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
NOTE:
In program 2 each element of ptr array contains the address of an integer value whereas in program 3 each element contains the address of a 1D array of integer type.