thecodex.expert · The Codex Family of Knowledge
C

Function Pointers

qsort doesn’t know how to compare YOUR data — you pass it a function pointer, and it calls your comparison function through that pointer whenever it needs to.

C17 / C23 Runtime-selectable behavior Last verified:
Canonical Definition

Compiled code lives in memory just like data does, so a function has an address too, and C lets that address be stored in a variable whose type matches the function's exact signature. Calling through a function pointer looks almost identical to calling the function directly, but which actual function runs can be decided at runtime — assigned conditionally, passed as a parameter, or stored in a data structure. This is the core mechanism behind callbacks (like qsort's comparison function) and is C's closest equivalent to first-class functions.

Declaring and calling through a function pointer

The declaration syntax is famously awkward — int (*fp)(int, int) reads as "fp is a pointer to a function taking two ints and returning int," and the parentheses around *fp are required, since int *fp(int, int) would instead declare a function returning int*.

Cbasic_fp.c
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

int (*operation)(int, int);   // a pointer to a function taking (int, int), returning int

operation = add;
printf("%d\n", operation(3, 4));   // 7 — called through the pointer

operation = subtract;                // reassign to a DIFFERENT function
printf("%d\n", operation(3, 4));   // -1

Passing a function pointer as a callback

qsort has no idea how to compare your specific data — it calls YOUR comparison function, through the pointer you pass it, whenever it needs to compare two elements during the sort.

Cqsort_callback.c
int compareInts(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int numbers[] = { 5, 2, 8, 1, 9 };
qsort(numbers, 5, sizeof(int), compareInts);   // compareInts is passed AS a function pointer

typedef: making the syntax bearable

A typedef for a function pointer type turns the awkward declaration syntax into a readable, reusable name — genuinely common practice whenever function pointers appear more than once in real code.

Ctypedef_fp.c
typedef int (*BinaryOp)(int, int);   // BinaryOp is now a readable name for this pointer type

BinaryOp op = add;
printf("%d\n", op(3, 4));   // 7

Sources

1
ISO/IEC 9899 (C Standard), "Function pointers," cppreference.com/w/c/language/pointer.