SyntaxStudy
Sign Up
C Function Pointers and Callbacks
C Beginner 1 min read

Function Pointers and Callbacks

In C, functions have addresses just like variables. A function pointer stores the address of a function and allows that function to be called indirectly. The syntax for declaring a function pointer can be cryptic at first: `int (*compare)(const void *, const void *)` declares a pointer named `compare` to a function that takes two `const void *` parameters and returns `int`. Using `typedef` to alias the function pointer type greatly improves readability. Function pointers enable callbacks — passing a function as an argument to another function. The standard library's `qsort()` function uses exactly this pattern: you provide a comparison function and `qsort` calls it to determine element ordering. Callbacks are also central to event-driven and plugin architectures, where behaviour is injected at runtime without hard-coding which function to call. Arrays of function pointers can act as dispatch tables, replacing long `switch` or `if/else` chains with an indexed lookup. This is how C virtual dispatch is implemented in many embedded and OS environments. The technique trades some readability for extensibility — adding a new case requires only adding an entry to the table rather than modifying a conditional.
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* typedef makes function pointer syntax readable */
typedef int (*CompareFunc)(const void *, const void *);

int compare_int_asc(const void *a, const void *b)
{
    return (*(const int *)a) - (*(const int *)b);
}

int compare_int_desc(const void *a, const void *b)
{
    return (*(const int *)b) - (*(const int *)a);
}

void print_array(const int *arr, int n)
{
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
}

/* Accepts a callback */
void sort_and_print(int *arr, int n, CompareFunc cmp)
{
    qsort(arr, (size_t)n, sizeof(int), cmp);
    print_array(arr, n);
}

int main(void)
{
    int data[] = {42, 7, 19, 3, 55, 11};
    int n = 6;

    printf("Ascending:  ");
    sort_and_print(data, n, compare_int_asc);

    printf("Descending: ");
    sort_and_print(data, n, compare_int_desc);

    /* Array of function pointers — dispatch table */
    CompareFunc table[] = { compare_int_asc, compare_int_desc };
    int choice = 0;   /* 0 = asc, 1 = desc */
    int copy[] = {9, 1, 5, 3, 7};
    printf("Table[%d]:  ", choice);
    sort_and_print(copy, 5, table[choice]);

    return 0;
}