We have defined a pointer as a variable which keeps the address of another variable. Since pointer is also a variable and is allocated memory space in which its value is stored, so we can have another variable which keeps the address of the pointer. That would be a pointer to a pointer. Such a pointer to a pointer is depicted in Fig, in which pointer ppa points to pointer pa, which in turn points to variable a. These pointers can be initialized as shown below.
int a, *pa, **ppa;
pa = &a; /* pointer pa points to variable a */
ppa = &pa; /* pointer ppa points to pointer pa */
These declarations can be alternatively written in a more readable form as
int a;
int *pa = &a;
int **ppa = &pa;
Now we can use pointer ppa to access the value of variable a. As we know, the expression *ppa gives the value pointed by pointer to ppa which is the value of pointer pa (i. e., the address of variable a). Thus, to access the value of variable a, we have to dereference pointer ppa once more, as in **ppa. Thus, the expression **ppa = 10 assigns value 10 to variable a and ++ **ppa increments its value. Note that the variable a can be accessed using pointer pa as well. Thus, we can also set variable a to 10 using expression *pa= 10.
Note that we can extend this concept further. The declaration
int ***pppa = &ppa;
declares pppa as a pointer to a pointer to a pointer to variable a and initializes it to point to variable ppa declared earlier. This pointer is illustrated in Fig. To access variable a using pointer pppa, we must dereference it three times. Thus, ***pppa = 1o assigns value 10 to variable a.
You might be wondering what is the use of such pointers to other pointers. However, as we will see, they are used to create dynamic multidimensional arrays. For example, a pointer to pointer is used to create a dynamic matrix, and a pointer to a pointer to a pointer is used to create a dynamic three-dimensional array.
illustrates pointer to a pointer and also pointer to pointer to a pointer
int main ()
{
int m = 80 ; // int variable
int* pm= &m ; // pointer to int variable
int** ppm= ± // pointer to pointer to variable
int*** pppm = &ppm; // pointer to pointer to pointer
clrscr();
printf("Variable m = %d\tAddress of m %u\n", m, &m);
printf("Pointer pm= %u\n", pm);
printf("Address of pm= %u\n", &pm);
printf("Pointer to pointer ppm= %u\n",ppm);
printf("Address of ppm= %u\n",&ppm);
printf("Pointer to pointer to pointer pppm = %u\n", pppm);
printf("Address of pppm = %u\n", &pppm);
printf("Now by dereference, ppm= *pppm = %u\n" ,*pppm);
printf("Now by dereference, pm =*ppm= %u\n" ,*ppm);
printf("Value of m = *pm= %d\n" ,*pm);
printf("Value of m = **ppm= %d\n", **ppm);
printf("Value of m = ***pppm = %d\n", ***pppm);
return 0;
}
The expected output is as given below.