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.
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);
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
.
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.
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.
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 ...
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.
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!
Share this page on WhatsApp