In C, pointers typically hold the memory address of variables. However, pointers can also hold the memory address of functions. These are known as Function Pointers.
Function pointers are one of the most powerful—and often most intimidating—features of C. They allow you to pass functions as arguments to other functions, store functions in arrays, and implement callback mechanisms, paving the way for highly dynamic and flexible code architectures.
When you compile a C program, every function is assigned a unique memory address where its machine instructions are stored. A function pointer simply stores this starting memory address.
By dereferencing the function pointer, you can invoke the function it points to, just as you would call it by its normal name.
The syntax for declaring a function pointer can look a bit strange at first glance. You must specify the return type, the pointer name (enclosed in parentheses), and the parameter types.
Syntax:
return_type (*pointer_name)(parameter_type1, parameter_type2, ...);
Example:
// A pointer named 'operation' that points to a function // taking two ints and returning an int. int (*operation)(int, int);
Note: The parentheses around `(*pointer_name)` are crucial. Without them, `int *operation(int, int);` declares a normal function named `operation` that returns a pointer to an integer.
To use a function pointer, you assign it the name of the target function (without parentheses). Then, you use the pointer to call the function.
#include <stdio.h>// A simple function int add(int a, int b) { return a + b; }
// Another simple function int subtract(int a, int b) { return a - b; }
int main() { // 1. Declare a function pointer int (*math_ptr)(int, int); // 2. Assign the address of the 'add' function // (The name of a function acts as its memory address) math_ptr = add; // 3. Call the function using the pointer int result1 = math_ptr(10, 5); printf("Result of addition: %d\n", result1); // 4. Reassign the pointer to the 'subtract' function math_ptr = subtract; // 5. Call the new function int result2 = math_ptr(10, 5); printf("Result of subtraction: %d\n", result2); return 0; }
One of the most practical uses of function pointers is creating an array of them. This is extremely useful for replacing complex, deeply nested switch-case statements, creating state machines, or implementing jump tables/dispatch tables.
#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 divide(int a, int b) { return (b != 0) ? a / b : 0; }
int main() { // Array of function pointers int (*operations[4])(int, int) = {add, subtract, multiply, divide}; int choice, a = 20, b = 5; printf("Select operation:\n0: Add\n1: Subtract\n2: Multiply\n3: Divide\nChoice: "); scanf("%d", &choice); if (choice >= 0 && choice <= 3) { // Calling the selected function from the array int result = operations[choice](a, b); printf("Result: %d\n", result); } else { printf("Invalid choice!\n"); } return 0; }
Function pointers allow you to pass a function as an argument to another function. The receiving function can then "call back" the passed function. This is the foundation of event-driven programming and generic algorithms in C.
A classic example is the qsort function from the C Standard Library (<stdlib.h>), which requires a function pointer to know exactly how to compare the custom elements.
#include <stdio.h>// A function that takes an array, its size, and a callback function pointer void processArray(int arr[], int size, void (*action)(int)) { for (int i = 0; i < size; i++) { // Execute the callback function for each element action(arr[i]); } }
// Callback implementation 1 void printElement(int value) { printf("%d ", value); }
// Callback implementation 2 void printSquare(int value) { printf("%d ", value * value); }
int main() { int numbers[] = {1, 2, 3, 4, 5}; int size = sizeof(numbers) / sizeof(numbers[0]); printf("Original Elements: "); // Pass 'printElement' as a callback processArray(numbers, size, printElement); printf("\n"); printf("Squared Elements: "); // Pass 'printSquare' as a callback processArray(numbers, size, printSquare); printf("\n"); return 0; }
typedefFunction pointer declarations can get messy and hard to read very quickly. You can use the typedef keyword to create an alias for a function pointer type, making your code much cleaner.
// Create an alias 'MathFunc' for a function pointer typedef int (*MathFunc)(int, int);// Now you can declare variables much more easily! MathFunc myFunc = add; int result = myFunc(10, 5);
Which of the following correctly declares a pointer `ptr` to a function that takes a `float` and returns a `char`?