computer fundamentals...

Function Pointers in C

What is Function Pointer?

Function pointers are usual pointer variables and nothing special in anyway except they are special in that unlike pointer to object types, there is no guarantee that they can be represented by void *. Pointer arithmetic is also not defined anywhere in the C standard for pointer to function types. As normal pointer variables point to other variables, likewise function pointer points to the address of a function. 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 this 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.

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.

Advantages of Function Pointers

At times it is advantageous to pass functions as parameters or to create an array of functions. For example, when an interpreter is written, the parser (the part that processes expressions) often calls various support functions, such as those that compute mathematical operations (sine, cosine, tangent, etc.), perform I/O, or access system resources. Instead of having a large switch statement with all of these functions listed in it, an array of function pointers can be created. In this approach, the proper function is selected by its index. Next sections explain you the value of function pointers by studying the 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 talked of function pointers in 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

Comments


Get Free Tutorials To Your Inbox

Tutorials

Interview Questions

Social Links

About the Author

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

Today's Tech News

Sleep sensor smashes Kickstarter goalPosted on Tuesday July 29, 2014

A 22-year-old British entrepreneur's new sleep-tracking device cracks $1m (£590,000) on the Kickstarter crowdfunding platform in five days.

Peers query 'right to be forgotten'Posted on Tuesday July 29, 2014

Demands for web firms to remove personal data to respect people's "right to be forgotten" are unreasonable, peers say.

Twitter shares surge on user growthPosted on Tuesday July 29, 2014

Social networking service Twitter reports a second-quarter loss of $145m but better than expected user growth, sending shares surging over 35%.

OKCupid experiments with 'bad' matchesPosted on Tuesday July 29, 2014

Dating website OKCupid reveals that it experimented on its users, including putting the "wrong" people together to see if they would connect.


Courtesy BBC News