Advanced pointers

Pointers to pointers (multiple indirection)

A normal pointer contains the address of a variable. When defining a pointer to a pointer, the first pointer contains the address of the second pointer, which points to the location of the variable. A pointer to a pointer is declared by placing an additional asterisk in front of its name. For example, the following declaration declares a pointer to a pointer of type int

int **v;

Accessing the value pointed to in the above integer value is by applying the asterisk operator twice. In the code sample below both the pointer and pointer to that pointer reference the same integer value.

#include <stdio.h>
int main(void) {
// declare and populate 2d array
int value[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int *ptr = &value[0][0]; // set pointer ptr to array value
int total_cells = 12, i;
// output elements of the array value by using pointer ptr
for (i = 0; i < total_cells; i++) {
printf("%d ", *(ptr + i));
}
return 0;
}


Pointers and Multidimensional Arrays

To create a pointer to a multidimensional assign the address of the first element of the array and use the address of the operator as below

int *ptr = &num[0][0];

The multidimensional array num will be saved as a contiguous block in memory. To move between each element the value of ptr will need to be incremented by one

In the following code we are printing the content of the num array using for loop and by incrementing the value of ptr.

#include <stdio.h>
int main(void) {
// declare and populate 2d array
int value[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int *ptr = &value[0][0]; // set pointer ptr to array value
int total_cells = 12, i;
// output elements of the array value by using pointer ptr
for (i = 0; i < total_cells; i++) {
printf("%d ", *(ptr + i));
}
return 0;
}


Array of pointers

An array of pointers is an array that holds memory locations. The following statement declares an array of 5 pointers to type char -

char *str[5];

Each element of the str array acts as an individual pointer to type char. These declarations can be combined initialization statements as below

char *str[5] = { “one”, “two”, “three”,"four","five" };

This code declares an array of 5 pointers to type char and initializes them to point to 5 strings. It then uses a for loop to display each element.

# include <stdio.h>
int main( void )
{
char *str[5] = { "one", "two", "three", "four","five"};
int count;
for (count = 0; count < 5; count++)
printf("%s ", str[count]);
printf("\n");
return 0;
}


Pointers to Functions

A pointer to a function points to the address of the executable code of the function. As with all C variables, it is necessary to declare a pointer to a function before using it. The general form of the declaration is as follows:

type (*function_ptr)(parameter_list);

coded examples of how to declare some functions pointer are listed below

int (*function)(int x);
char (*function)(char *p[]);
void (*functions)();

Parentheses are used around the pointer name because the asterisk operator * has relatively low operator precedence. Without the parenthesis, the function declaration will not be evaluated in the correct order.

Function pointers are useful for implementing callback mechanisms and passing the address of a function to another function. They are also useful for storing an array of functions dynamically.

The following short program demonstrates how to declare and call a function pointer

#include <stdio.h>
void function(char arrayvalue[30]);/*function declaration*/
void (*ptrfunc)(char arrayvalue[30]);/* The pointer declaration. */
int main( void )
{
ptrfunc = function;/* Initialize ptrfuch to address of function. */
char arrayvalue[30]="outside array";
printf(" %s\n", arrayvalue);
ptrfunc(arrayvalue);//call function use *ptrfunc
printf(" %s\n", arrayvalue);
return 0;
}
void function(char arrayvalue[30])
{
strcpy(arrayvalue, "function return");/*change value of arrayvalue*/
}