Function pointers are a powerful feature in C programming that allow you to store the address of a function in a variable, just like you do with normal data pointers. They are especially useful for callbacks, plugin architectures, and dynamic execution of different functions at runtime.
In this article, you’ll learn:
- What function pointers are
- How to declare and use them
- How to pass them to functions
- Real-world examples like callback functions
- Common mistakes and best practices
📦 What is a Function Pointer?
A function pointer stores the memory address of a function, allowing the function to be called indirectly through the pointer. This is useful when the function to be called isn’t known at compile time.
For example:
int (*funcPtr)(int, int);
This declares a pointer named funcPtr
to a function that returns int
and takes two int
parameters.
✅ Example 1: Basic Function Pointer Declaration and Usage
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*operation)(int, int);
operation = add;
printf("Result: %d\n", operation(5, 3));
return 0;
}
Explanation:
int (*operation)(int, int);
declares the function pointer.- operation = add; assigns the function’s address.
operation(5, 3);
calls the function via the pointer.
This method allows flexible function selection at runtime.
📘 Example 2: Passing Function Pointers to Another Function
#include <stdio.h>
int multiply(int x, int y) {
return x * y;
}
void compute(int a, int b, int (*func)(int, int)) {
printf("Computed value: %d\n", func(a, b));
}
int main() {
compute(4, 5, multiply);
return 0;
}
Explanation:
Here, we pass the function multiply
as a parameter to compute()
. This is the basis of callback functions in C and allows the caller to define the logic dynamically.
✏️ Example 3: Array of Function Pointers
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int main() {
int (*operations[3])(int, int) = {add, subtract, multiply};
printf("Add: %d\n", operations[0](10, 5));
printf("Subtract: %d\n", operations[1](10, 5));
printf("Multiply: %d\n", operations[2](10, 5));
return 0;
}
Explanation:
We use an array of function pointers operations[]
to store multiple functions. This is great for implementing menu-driven programs or instruction tables, where the correct function is chosen at runtime based on an index.
🔄 Example 4: Function Pointer as Return Type
#include <stdio.h>
int greet() {
printf("Hello from greet!\n");
return 0;
}
int (*getFunction())() {
return greet;
}
int main() {
int (*funcPtr)() = getFunction();
funcPtr(); // Calls greet()
return 0;
}
Explanation:
In this example, getFunction
returns a pointer to a function that takes no parameters and returns an int
. This is a higher-order function, capable of returning behavior dynamically.
⚠️ Common Mistakes to Avoid
Mistake | Explanation |
---|---|
Incorrect parenthesis placement | int *func() ≠ int (*func)() |
Calling NULL function pointer | Causes segmentation fault; always check before calling |
Forgetting function signature match | Function pointers must match return type and parameter types |
🧠 Best Practices
- Always use clear naming for function pointer types.
- Use
typedef
for long function pointer declarations. - Always validate pointer before calling (e.g.,
if (ptr != NULL)
). - Document function pointer usage clearly in APIs.
🧪 Use Case: Dynamic Operation Selector
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
char op;
int a = 10, b = 5;
int (*operation)(int, int) = NULL;
printf("Enter operation (+ or -): ");
scanf(" %c", &op);
if (op == '+') operation = add;
else if (op == '-') operation = subtract;
if (operation) {
printf("Result: %d\n", operation(a, b));
} else {
printf("Invalid operation\n");
}
return 0;
}
Explanation:
This example mimics a function dispatcher. Based on user input, a function pointer is set to the right function, and then executed. This is foundational in building flexible runtime logic.
Function pointers are among the most powerful features in C programming. They make your code more modular, reusable, and dynamic. Whether building libraries, plugins, or callback systems, function pointers offer the flexibility of behavior injection at runtime.
Once you master their syntax and understand how memory addresses and type signatures work, you’ll unlock new levels of C programming flexibility.
Did function pointers confuse you earlier?
Try one of the examples above, or share a code snippet where you’d like help. Let’s decode C together in the comments!