Function Pointers in C

What is Function Pointer?

In C function pointers are usual pointer variables, but they are little different from pointer to objects. For example, function pointers are not allowed to cast void*. Also, pointer arithmetic is also not defined anywhere in the C standard for pointer to function types. Leaving these differences apart function pointer points to the address of a function as normal pointer variable points to the address of a variable.

Being C programmers, we all know that a running C program occupies certain space in memory. Both, the executable compiled program code and the variables used by the program, are put inside the memory. And, every byte of memory is addressable. Thus a function in the program code will have an address just like a character variable or any other variable stored in memory. While, using function pointer; function's physical location or address in memory is assigned to a pointer. Function's address is the entry point of the function and it is the address used when the function is called. Once a pointer points to a function, the function can be called through that pointer.

A function name, without a following set of parentheses, produces a pointer to that function. The address operator can also be applied to a function name to produce a pointer to it. For example, if myFunc is a pointer to a function, the corresponding function can be called either by writing myFunc() or (*myFunc)(). If the function takes arguments, they can be listed inside the parentheses.

Define Function Pointers

Because a function pointer is nothing else than a variable, so it must be defined as normal pointer variables are defined. For illustration, we define a function pointer ptrMaxFunctin. Function pointer ptrMaxFunctin points to a function retMax, which takes two int values as arguments and returns an int value (the maximum one). Let's take a look at the following declaration.

int (*ptrMaxFunctin)(int, int); //declaring function pointer
 
// assigning retMax's address to ptrMaxFunctin
ptrMaxFunctin = retMax; // short form
//or
ptrMaxFunctin = &retMax; // correct assignment using address operator
 
//We can also initialize function pointer in single statement
int (*ptrMaxFunctin)(int, int) = retMax;

We obtain the address of a function by using the function's name without any parentheses or arguments. (This is similar to the way an array's address is obtained when only the array name, without indexes, is used.)

For beginners, a way to remember writing function pointer syntax:
Write a normal function declaration: int retMax (int n1, int n2);
Wrap function name with pointer syntax: int (*retMax) (int n1, int n2);
Change the name to the pointer name: int (*ptrMaxFunctin) (int n1, int n2);

Calling a Function Using Function Pointer

Let's put the function pointer ptrMaxFunctin in a small program to see how to call a function using function pointer. The following program develops a trivial function retMax, which returns the maximum number among passed integers, to demonstrate calling a function by function pointer.

/* return-max.c */
#include <stdio.h>
int retMax (int n1, int n2)
{
  return (n1 > n2) ? n1 : n2;
}
 
int main ()
{
  int (*ptrMaxFunctin)(int, int);
  ptrMaxFunctin = retMax;
  int qty1 = 20, qty2 = 50;
 
  printf ("Max of %d and %d is : %d \n", qty1, qty2, (*ptrMaxFunctin)(qty1, qty2));
  return 0;
}
 
OUTPUT
======
[root@host ~/cprogs]$ gcc return-max.c -o return-max
[root@host ~/cprogs]$ ./return-max
Max of 20 and 50 is : 50
 

Let's look closely at above program. First, examine the declaration for ptrMaxFunctin in main(). It is shown here:

int (*ptrMaxFunctin)(int, int);

This declaration tells the compiler that ptrMaxFunctin is a pointer to a function that has two int parameters, and returns an int result. The parentheses around ptrMaxFunctin are necessary because * is a prefix operator and it has lower precedence than (), so parentheses are necessary to force the proper association.

Now examine the next statement ptrMaxFunctin = retMax; where ptrMaxFunctin is assigned the address of retMax. After this assignment; function retMax can be called with the help of the pointer ptrMaxFunctin to function retMax. In above program it has been called inside the printf.

Pass a Function Pointer as an Argument

Function pointers also allow functions to be passed as arguments to other functions. We pass function name to other function as a parameter and it is received by the formal function pointer parameter. It is in no way different from usual pointer arguments. Following program fp-arguments.c demonstrates passing function pointer as argument.

/* fp-arguments.c */
 
#include <stdio.h>
#include <string.h>
 
char* compareStrings(char*, char*, int (*cmp)(const char*, const char*));
 
int main()
{
  char str1[80], str2[80];
  int (*functPtr)(const char *, const char *); /* function pointer */
  functPtr = strcmp; /* assign address of strcmp to functPtr */
  printf("Enter two strings.\n");
  scanf("%s%s", str1, str2);
 
  /* pass address of strcmp via functPtr */
  printf("Are \"%s\" and \"%s\" equal? : %s\n", str1, str2, compareStrings(str1, str2, functPtr));
 
  return 0;
}
 
char* compareStrings(char *a, char *b, int (*cmp) (const char*, const char*))
{
  if(!(*cmp)(a, b)) // !cmp(a, b) is also correct
    return ("YES");
  else
    return("NO");
}
 
OUTPUT
======
[root@host ~/cprogs]$ gcc fp-arguments.c -o fp-arguments
[root@host ~/cprogs]$  ./fp-arguments
Enter two strings.
string1 string2
Are "string1" and "string2" equal? : NO
 
 

Read above program carefully, and examine compareStrings() function. It declares three parameters: two character pointers, and one function pointer, cmp. Also notice that the function pointer is declared using the same format as was functPtr inside main(). Thus, cmp is able to receive a pointer to a function that takes two const char* arguments and returns an int result. Like the declaration for functPtr, the parentheses around the *cmp are necessary for the compiler to interpret this statement correctly. Moreover, C provides more flexible syntax for function pointers just like ordinary functions. For example, (*cmp)(a, b) and cmp(a, b) are the same. However, latter may cause confusion if this is a function pointer or ordinary function call.

When the program begins, it assigns functPtr the address of strcmp(), the standard string comparison function. Next, it prompts the user for two strings, and then it passes pointers to those strings along with functPtr to compareStrings(), which compares the strings for equality. Inside compareStrings(), the expression calls strcmp(), which is pointed to by cmp, with the arguments a and b. The parentheses around *cmp are necessary. This is one way to call a function through a pointer.

Note that you can call compareStrings() by using strcmp() directly, as shown here:

compareStrings(str1, str2, strcmp);

That's the way you can pass a function pointer to a function as an argument. But, you may be wondering that why anyone would write a program like the one just shown. Obviously, nothing is gained, and significant confusion is introduced. So, it seems nice time to prove the worth of function pointers.

Application Uses of Function Pointers

One common application for pointers to functions is in passing them as arguments to other functions.The standard C library uses this, for example, in the function qsort, which performs a quick sort on an array of data elements. This function takes as one of its arguments a pointer to a function that is called whenever qsort needs to compare two elements in the array being sorted. In this manner, qsort can be used to sort arrays of any type, as the actual comparison of any two elements in the array is made by a user supplied function, and not by the qsort function itself.

Another common application for function pointers is to create what is known as dispatch tables. You can't store functions themselves inside the elements of an array. However, it is valid to store function pointers inside an array. Given this, you can create tables that contain pointers to functions to be called. For example, you might create a table for processing different commands that will be entered by a user. Each entry in the table could contain both the command name and a pointer to a function to call to process that particular command. Now, whenever the user enters a command, you can look up the command inside the table and invoke the corresponding function to handle it.

Subsequent sections explain you typedef and array of function pointers.

How to typedef Function Pointer?

C language provides a language construct typedef that associates a keyword to a type. It gives a new name to a type that may make program more readable. Type definition is proved very useful especially for pointers to functions. However, typedef construct only makes the writing/reading of a program easy; the compiler just expands the typedef definition before compiling the actual code. If you want to create an array of a certain pointer to function then typedef makes it readable because the original syntax of pointer to function looks odd and confusing too. Below declaration tells how to define a custom name for a function pointer. While creating an array of pointers to functions typedef really helps. Next section demonstrates that.

typedef int (*ptrToFunct)(int, int);
//now on ptrToFunct can be used as a type 
int retSum(int n1, int n2) 
{
  return n1 + n2;
}
 
ptrToFunct pFunct = retSum;
...
int x2 = (*pFunct)(10, 20); // call retSum() to calculate 10+20
...

Using Arrays of Function Pointers?

An array of function pointers can be created for the functions of same return type and taking same type and same number of arguments. For example, if you have four function definitions for performing basic arithmetic operations (addition, subtraction, multiplication, and division) on two integer quantities, all these functions will take two integer arguments and will return an integer as a result. For such similar~return~type~and~argument operations you can create an array of function pointers and select a proper function by its index rather than its name. The following example demonstrates it.

/* array-fp.c */
/* How to Use Arrays of Function Pointers */
 
#include <stdio.h>
 
int getSum(int, int);
int getDifference(int, int);
int getProduct(int, int);
int getDivision(int, int);
 
int main()
{
  // type-definition: 'functionPtr' now can be used as type
  typedef int (*functionPtr)(int, int);
 
  // assign the function's address
  functionPtr arrayFp[4] = {getSum, getDifference, getProduct, getDivision};
 
  int a = 50, b = 20;
  printf("Sum of %d and %d : %d\n", a, b, arrayFp[0](a, b));
  printf("Difference of %d and %d : %d\n", a, b, arrayFp[1](a, b));
  printf("Product of %d and %d : %d\n", a, b, arrayFp[2](a, b));
  printf("Division of %d and %d : %d\n", a, b, arrayFp[3](a, b));
 
  printf("\nProduct of sum and difference of %d and %d is : %d\n", a, b, arrayFp[2](arrayFp[0](a, b), arrayFp[1](a, b)));
}
 
int getSum(int x, int y)
{
  return x + y;
}
 
int getDifference(int x, int y)
{
  return x - y;
}
 
int getProduct(int x, int y)
{
  return x * y;
}
 
int getDivision(int x, int y)
{
  return x / y;
}

Read above program carefully and you will observe that first functionPtr type is defined and then an array of four function pointers has been created. Array arrayFp of function pointers holds addresses of four functions getSum, getDifference, getProduct, getDivision respectively. All four functions are later called with the help of arrayFp using their index in the array.

Last Word

In this tutorial we discussed how to define and use function pointers in C/C++ programs? We also discussed calling a function using function pointer, passing a function to another function as an argument using function pointer, typedef of function pointers and array of function pointers. A function pointer or pointer to function in C is a usual pointer variable that points to the address of a function in memory. Through a pointer a function can be passed to other function as an argument and returned from a function. Hope you have enjoyed reading this article. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!

References



Share this page on WhatsApp

Get Free Tutorials by Email

About the Author

is the founder and main contributor for cs-fundamentals.com. He is a software professional (post graduated from BITS-Pilani) and loves writing technical articles on programming and data structures.