A function pointer is a variable that can store the address of a function. Unlike normal pointers, they point to functions. They are useful in situations where you need to pass a function as an argument to another function or when you want to create an array of functions.
Syntax
The syntax follows the following general format:
return_type (*pointer_name)(parameter_types);
Example
The following is a simple example that shows a declaration and function call using a function pointer:
#include <stdio.h>
/**
* func - prints value of an integer
* @num: The integer
* Return: nothing.
*/
void func(int num)
{
printf("Value of num is %d\n", num);
}
/**
* main - check the code
*
* Return: Always 0.
*/
int main(void)
{
/* func_ptr is a pointer to function fun() */
void (*func_ptr)(int) = &func;
/* The above line is similar to:
void (*func_ptr)(int);
func_ptr = &func;
*/
/* Invoking func() using func_ptr */
(*func_ptr)(98);
return (0);
}
Output:
Value of num is 98
Note: The syntax confuses a lot of people, even C experts.
If you don't add extra brackets to your function pointer you will be creating a function that returns a pointer.
An array of function pointers
You can create an array of function pointers which is useful in scenarios where you need to switch between multiple functions dynamically.
Example
/**
* add - sum of two nums
* @a: The first operand
* @b: The second operand
*
* Return: sum
*/
int add(int a, int b)
{
return (a + b);
}
/**
* sub- subtracts of two nums
* @a: The first operand
* @b: The second operand
*
* Return: subtraction
*/
int sub(inta, int b)
{
return (a - b);
}
/* Declare an array of function pointers */
int (*op_array[2])(int, int);
/* Initialize the array with functions */
op_array[0] = add;
op_array[1] = sub;
Now, op_array
is an array of function pointers that can point to either the add
or sub
function.
You can use array notation to call functions through function pointers in an array:
int result1 = op_array[0](2, 3); /* Calls add(2, 3) */
int result2 = op_array[1](5, 2); /* Calls subtract(5, 2) */
This allows for more dynamic and flexible code structures.
Function pointers and callbacks
Function pointers are often used as callbacks. A callback is a function that is passed as an argument to another function and is executed after a specific event or task.
Consider a function that applies a callback to a set of data:
/**
* process_data- processes data
* @data: An array
* @size: The second operand
* @callback: The function pointer
*
* Return: nothing
*/
void process_data(int data[], int size, int (*callback)(int)
{
int i;
for (i = 0; i < size; i++)
{
data[i] = callback(data[i]);
}
}
You can use this function with different callbacks, such as:
/**
* mul- multiplies nums
* @num: The number
*
* Return: result of multiplication of numbers
*/
int mul(int num) {
return (num * num);
}
/**
* double_value- doubles nums
* @num: The number
*
* Return: result of doubling numbers
*/
int double_value(int num) {
return (num * 2);
}
/* Using callbacks */
process_data(data_array, size, square);
/* or */
process_data(data_array, size, double_value);
This demonstrates how function pointers enable the implementation of flexible and reusable callback.
Function pointers and structs
Structs in C can contain function pointers, allowing you to create more flexible and extensible data structures.
Example
/**
* Calculator - Struct calculator
*
* @opration: The function pointer
*/
struct Calculator {
int (*operation)(int, int);
};
/**
* add - sum of two nums
* @a: The first operand
* @b: The second operand
*
* Return: sum
*/
int add(int a, int b) {
return (a + b);
}
/**
* sub - subtracts of two nums
* @a: The first operand
* @b: The second operand
*
* Return: subtraction
*/
int subtract(int a, int b) {
return (a - b);
}
/* Example usage of the struct */
struct Calculator calc;
calc.operation = add;
int result = calc.operation(5, 3); /* Calls add(5, 3) */
By incorporating function pointers within structs, you can create data structures that support various operations.
Function pointers in C are a powerful feature that allows you to create more flexible, modular, and dynamic code.
Happy coding!