6.10. Pointers to Functions

  • The name (identifier) of a function is a constant pointer to the beginning of some machine instructions in the text area of memory.

  • Pointers to functions can be used like any other pointer. We can have a separate pointer variable pointing to a function. We can pass a function pointer to a function. We can also store pointers to functions in an array of functions.

  • We write the data type of such pointers as:

    function_return_type (*)(types of function arguments)
    
    double (*fptr)(int); -- Declare a variable to hold a pointer to a
                            function that takes an int and returns a double.
    
    double *(*f2ptr)(int); -- Same as above, except the function now
                              returns a pointer to a double.
    
  • When functions are passed as arguments to another function, the pointer notation is implicit and may be left off. (see example below)

  • Passing a function as an argument to another function provides a powerful mechanism for writing a general purpose function (algorithm) that can produce very different result based on the function passed as an argument.

6.10.1. Example - Arbitrary string sorting

Here we use the basic bubble sorting algorithm and show an example that sorts an array of strings. The comparison used to decide when to swap values is supplied by a programmer specified external function. In this example, the main() function calls the sorting function twice, each time with a different comparison function. To sort the strings alphabetically, we can use the strcmp function which comes from the string library. Then to sort the strings based on string length, the sort function is given a comparison function of our own which just compares the length of the strings.

#include <stdio.h>
#include <string.h>

void strsort( int (const char *, const char *), char ** );
int lengthcmp( const char *, const char * );

int main( int argc, char **argv)
{
   char **tmp;

   tmp = argv;
   strsort( strcmp, argv );
   while ( *tmp != NULL )
      printf("\t%s\n", *tmp++ );
   printf("\n");
   tmp = argv;
   strsort( lengthcmp, argv );
   while ( *tmp != NULL )
      printf("\t%s\n", *tmp++ );
   return 0;
}

void strsort( int cmp(const char *, const char *), char **strings )
{
   char *temp, **ptr;
   int i, j, length = 0;

   for( ptr = strings; *ptr != NULL; ptr++ ) length++;
   for( i = 0; i < length - 1; ++i )
      for( j = length - 1; j > i; --j )
         if( cmp( *(strings + i), *(strings + j) ) > 0 ) {
            temp = *(strings + i);
            *(strings + i) = *(strings + j);
            *(strings + j) = temp;
         }
}

int lengthcmp( const char *s1, const char *s2 )
{
   int l1, l2;
   l1 = strlen( s1 );
   l2 = strlen( s2 );
   if( l1 < l2 ) return -1;
   if( l1 == l2 ) return 0;
   return 1;
}

Output from the program looks like this:

% stringSort This is a quick simple test.
        This
        a
        is
        quick
        simple
        stringSort
        test.

        a
        is
        This
        quick
        test.
        simple
        stringSort