Function pointers in C can be tricky for beginners, but they are one of the most powerful features of the language. They allow you to treat functions as first-class entities—passing them as arguments, storing them in variables, and invoking them dynamically.
What is a Function Pointer? #
When you define a function in C, the compiler allocates a block of memory for the function code. The starting address of that block is the function’s pointer (entry address).
Just like an array name represents its base address, a function name represents its memory address. This means you can assign a function’s address to a pointer and call the function indirectly.
Declaring a Function Pointer #
Declaring a function pointer is similar to declaring a variable pointer.
For example:
int getData(int a, int b); // Function declaration
int (*p)(int a, int b); // Function pointer declaration
⚠️ Note: Parentheses around
*p
are required due to operator precedence. Without them,int *p(int a, int b);
would declare a function returning int* instead of a pointer to a function.
Example: Calling Functions via Pointers #
Let’s start with a simple example to see how function pointers work.
#include "stdio.h"
void PrintWelcome() {
printf("Hello, welcome\n");
}
int main() {
// Direct function call
PrintWelcome();
// Indirect call using a function pointer
void (*p)() = PrintWelcome;
(*p)();
return 0;
}
Output #
Hello, welcome
Hello, welcome
Both calls produce the same result. The key rule: 👉 The function pointer’s type must match the target function’s type.
Why Use Function Pointers? #
Function pointers provide flexibility. They enable techniques such as:
- Dynamic function selection at runtime
- Callback mechanisms
- Table-driven programming (jump tables)
Let’s see a practical case.
Example: Function Pointers with switch
#
Suppose the user inputs 1
, 2
, or 3
:
1
: return the maximum of two integers2
: return the minimum3
: return their sum
We can solve this elegantly using function pointers.
#include "stdio.h"
#include "stdlib.h"
// Three operations
int GetMax(int a, int b) { return a > b ? a : b; }
int GetMin(int a, int b) { return a < b ? a : b; }
int GetSum(int a, int b) { return a + b; }
// Function handler using a function pointer
int dataHandler(int a, int b, int (*pfunk)(int, int)) {
return pfunk(a, b);
}
int main() {
int a = 10, b = 20;
int cmd, ret;
int (*pfunk)(int, int);
printf("Enter 1 for max, 2 for min, 3 for sum: ");
scanf("%d", &cmd);
switch (cmd) {
case 1:
printf("Maximum: ");
pfunk = GetMax;
break;
case 2:
printf("Minimum: ");
pfunk = GetMin;
break;
case 3:
printf("Sum: ");
pfunk = GetSum;
break;
default:
printf("Invalid input\n");
exit(-1);
}
ret = dataHandler(a, b, pfunk);
printf("ret = %d\n", ret);
return 0;
}
Example Run #
$ ./test
Enter 1 for max, 2 for min, 3 for sum: 1
Maximum: ret = 20
$ ./test
Enter 1 for max, 2 for min, 3 for sum: 2
Minimum: ret = 10
$ ./test
Enter 1 for max, 2 for min, 3 for sum: 3
Sum: ret = 30
Key Notes on Function Pointers #
- Always use parentheses when declaring (
int (*pfunk)(int, int)
). - The pointer’s signature must match the target function’s return type and parameters.
- Argument names in declarations are optional:
int (*pfunk)(int, int); // valid
is equivalent to:
int (*pfunk)(int data1, int data2);
Conclusion #
Function pointers in C are powerful tools that allow dynamic behavior in programs. They are essential in areas such as:
- Event-driven systems
- Callback implementations
- Low-level OS or driver code
- Table-driven command execution
By mastering function pointers, you gain a deeper understanding of C’s flexibility and runtime capabilities.