Node:Function pointers, Previous:Assigning variables to one another, Up:Bits and pieces



Function pointers

You can create pointers to functions as well as to variables. Function pointers can be tricky, however, and caution is advised in using them.

Function pointers allow you to pass functions as a parameters to another function. This enables you to give the latter function a choice of functions to call. That is, you can plug in a new function in place of an old one simply by passing a different parameter. This technique is sometimes called indirection or vectoring.

To pass a pointer for one function to a second function, simply use the name of the first function, as long as there is no variable with the same name. Do not include the first function's parentheses or parameters when you pass its name.

For example, the following code passes a pointer for the function named fred_function to the function barbara_function:

void fred();
barbara (fred);

Notice that fred is declared with a regular function prototype before barbara calls it. You must also declare barbara, of course:

void barbara (void (*function_ptr)() );

Notice the parentheses around function_ptr and the parentheses after it. As far as barbara is concerned, any function passed to it is named (*function_ptr)(), and this is how fred is called in the example below:

#include <stdio.h>

void fred();
void barbara ( void (*function_ptr)() );
int main();

int main()
{
  barbara (fred);
  return 0;
}

void fred()
{
  printf("fred here!\n");
}

void barbara ( void (*function_ptr)() )
{
  /* Call fred */
  (*function_ptr)();
}

The output from this example is simply fred here!.

Again, notice how barbara called fred. Given a pointer to a function, the syntax for calling the function is as follows:

variable = (*function_pointer)(parameter_list);

For example, in the program below, the function do_math calls the functions add and subtract with the following line:

result = (*math_fn_ptr) (num1, num2);

Here is the example program:

#include <stdio.h>

int add (int, int);
int subtract (int, int);
int do_math (int (*math_fn_ptr) (int, int), int, int);
int main();

int main()
{
  int result;

  result = do_math (add, 10, 5);
  printf ("Addition = %d.\n", result);

  result = do_math (subtract, 40, 5);
  printf ("Subtraction = %d.\n\n", result);

  return 0;
}

int add (int num1, int num2)
{
  return (num1 + num2);
}


int subtract (int num1, int num2)
{
  return (num1 - num2);
}


int do_math (int (*math_fn_ptr) (int, int), int num1, int num2)
{
  int result;

  printf ("\ndo_math here.\n");

  /* Call one of the math functions passed to us:
     either add or subtract. */

  result = (*math_fn_ptr) (num1, num2);
  return result;
}

The output from this program reads:

do_math here.
Addition = 15.

do_math here.
Subtraction = 35.

You can also initialize a function pointer by setting it to the name of a function, then treating the function pointer as an ordinary function, as in the next example:

#include <stdio.h>

int main();
void print_it();
void (*fn_ptr)();

int main()
{
  void (*fn_ptr)() = print_it;

  (*fn_ptr)();

  return 0;
}

void print_it()
{
  printf("We are here!  We are here!\n\n");
}

Remember to initialize any function pointers you use this way! If you do not, your program will probably crash, because the uninitialized function pointer will contain garbage.