Function pointers are variables that store the address of a function. They enable powerful programming techniques like callbacks, function dispatch tables, and plugin architectures.
Just like you can have a pointer to an integer or a string, you can have a pointer to a function. This lets you pass functions as arguments and build flexible, dynamic code.
#include "function_pointers.h"/** * print_name - prints a name * @name: name * @f: pointer to function * Return: void */void print_name(char *name, void(*f)(char *)){ if (name && f) f(name);}
Usage example:
void print_uppercase(char *name){ for (int i = 0; name[i]; i++) _putchar(toupper(name[i])); _putchar('\n');}void print_lowercase(char *name){ for (int i = 0; name[i]; i++) _putchar(tolower(name[i])); _putchar('\n');}int main(void){ print_name("Bob", print_uppercase); // Output: BOB print_name("Bob", print_lowercase); // Output: bob return (0);}
Key points:
Pass function name without parentheses: print_uppercase not print_uppercase()
The function pointer f is called like a regular function: f(name)
Always validate the function pointer before calling
#include "function_pointers.h"/** * array_iterator - function that executes a function given * as a parameter on each element of an array * @array: array to iterate over * @size: size of array * @action: pointer to function * Return: void */void array_iterator(int *array, size_t size, void(*action)(int)){ size_t i; if (action && array) for (i = 0; i < size; i++) action(array[i]);}
#include "function_pointers.h"/** * int_index - function that searches for an integer * @array: array of integeres * @size: size of array * @cmp: pointer to function * Return: the index of the first element for which the cmp * function does not return 0 * If no element matches, return -1 * If size <= 0, return -1 */int int_index(int *array, int size, int (*cmp)(int)){ int i; if (size < 1 || array == NULL || cmp == NULL) return (-1); for (i = 0; i < size; i++) { if (cmp(array[i])) return (i); } return (-1);}
Usage example:
int is_positive(int n){ return (n > 0);}int is_even(int n){ return (n % 2 == 0);}int main(void){ int array[] = {-1, -2, 3, 4, 5}; int index; index = int_index(array, 5, is_positive); printf("First positive at index: %d\n", index); // Output: 2 index = int_index(array, 5, is_even); printf("First even at index: %d\n", index); // Output: 1 return (0);}
Always validate function pointers before calling them!
if (f) // Good: check before calling f(param);f(param); // Bad: could segfault if f is NULL
#ifndef CALC#define CALC#include <stdlib.h>#include <stdio.h>/** * struct op - Struct op * * @op: The operator * @f: The function associated */typedef struct op{ char *op; int (*f)(int a, int b);} op_t;int op_add(int a, int b);int op_sub(int a, int b);int op_mul(int a, int b);int op_div(int a, int b);int op_mod(int a, int b);int (*get_op_func(char *s))(int, int);#endif /*CALC*/
#include "3-calc.h"/** * op_add - adds two numbers. * @a: first number. * @b: second number. * * Return: add. */int op_add(int a, int b){ return (a + b);}/** * op_sub - subctracts two numbers. * @a: first number. * @b: second number. * * Return: difference. */int op_sub(int a, int b){ return (a - b);}/** * op_mul - multiplies two numbers. * @a: first number. * @b: second number. * * Return: multiplication. */int op_mul(int a, int b){ return (a * b);}/** * op_div - divides two numbers. * @a: first number. * @b: second number. * * Return: division. */int op_div(int a, int b){ if (b == 0) { printf("Error\n"); exit(100); } return (a / b);}/** * op_mod - calculates the module of two numbers. * @a: first number. * @b: second number. * * Return: remainder */int op_mod(int a, int b){ if (b == 0) { printf("Error\n"); exit(100); } return (a % b);}
#include "3-calc.h"/** * get_op_func - selects the correct function to perform * the operation asked by the user. * @s: char operator. * * Return: pointer to the function that corresponds to the operator. */int (*get_op_func(char *s))(int, int){ op_t ops[] = { {"+", op_add}, {"-", op_sub}, {"*", op_mul}, {"/", op_div}, {"%", op_mod}, {NULL, NULL} }; int i = 0; while (i < 10) { if (s[0] == ops->op[i]) break; i++; } return (ops[i / 2].f);}
Usage:
int main(int argc, char *argv[]){ int num1, num2, result; int (*operation)(int, int); if (argc != 4) { printf("Error\n"); exit(98); } num1 = atoi(argv[1]); num2 = atoi(argv[3]); operation = get_op_func(argv[2]); if (operation == NULL) { printf("Error\n"); exit(99); } result = operation(num1, num2); printf("%d\n", result); return (0);}
// Without typedef (complex)int (*get_op_func(char *s))(int, int);// With typedef (cleaner)typedef int (*operation_t)(int, int);operation_t get_op_func(char *s);
void my_function(int x){ printf("%d\n", x);}// Wrong: calls the function immediatelyarray_iterator(arr, 5, my_function(42));// Correct: passes the function pointerarray_iterator(arr, 5, my_function);