Function pointers in C: solved exercise with callbacks

Function pointers in C: solved exercise step by step

If you searched for a solved function pointer exercise in C, here are the three most common uses: direct call, function table, and callback in qsort.

A function pointer stores the address of a function with a specific signature. It lets you choose which function to invoke at runtime without needing switch or if-else.

Function pointer syntax

1
return_type (*name)(param_type1, param_type2, ...);

For example, a pointer to a function that takes two int arguments and returns int:

1
int (*operation)(int, int);

Problem statement

  1. Define four basic arithmetic operations as separate functions.
  2. Call one of them through a function pointer.
  3. Create a table (array) of function pointers to iterate over all operations.
  4. Use a function pointer as a callback in qsort to sort an integer array in descending order.

C solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>

/* 1. Arithmetic functions */
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; }

/* 4. Comparator for qsort: descending order */
int compare_desc(const void *p1, const void *p2) {
    int a = *(const int *)p1;
    int b = *(const int *)p2;
    return b - a;   /* b-a = descending; a-b = ascending */
}

int main(void) {
    int x = 12, y = 4;

    /* 2. Call through a pointer */
    int (*op)(int, int) = add;
    printf("Pointer to add: %d + %d = %d\n", x, y, op(x, y));

    op = multiply;
    printf("Pointer to multiply: %d * %d = %d\n", x, y, op(x, y));

    /* 3. Function pointer table */
    int (*table[])(int, int) = { add, subtract, multiply, divide };
    const char *names[] = { "add", "subtract", "multiply", "divide" };

    printf("\nOperation table with x=%d, y=%d:\n", x, y);
    for (int i = 0; i < 4; i++) {
        printf("  %s -> %d\n", names[i], table[i](x, y));
    }

    /* 4. qsort with callback */
    int data[] = { 5, 1, 8, 3, 9, 2 };
    int n = (int)(sizeof(data) / sizeof(data[0]));

    qsort(data, n, sizeof(int), compare_desc);

    printf("\nSorted descending: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");

    return 0;
}

Expected output

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Pointer to add: 12 + 4 = 16
Pointer to multiply: 12 * 4 = 48

Operation table with x=12, y=4:
  add -> 16
  subtract -> 8
  multiply -> 48
  divide -> 3

Sorted descending: 9 8 5 3 2 1

Common mistakes

  • Forgetting parentheses in the declaration: int *f(int) declares a function returning int*, not a function pointer.
  • Mismatching the pointer signature with the assigned function’s signature.
  • In qsort, using a plain subtraction (return a - b) can overflow with large integers; the safe form is return (a > b) - (a < b).
  • Calling a NULL function pointer without checking.

Practical use

Function pointers appear in:

  • sorting callbacks (qsort, bsearch),
  • plugin systems or interchangeable strategies,
  • state machines where each state has its own processing function,
  • C APIs that accept user-supplied functions (signals, threads).

Guided practice and next step

If you want a complete path with progressive difficulty:

FAQ

What is the difference between (*op)(x, y) and op(x, y)?

Both forms are equivalent in C. The first explicitly dereferences the pointer; the second uses the shorthand notation accepted since C89. The second form is more common in modern code.

Can I pass a function pointer as an argument?

Yes. That is the callback mechanism: void apply(int a, int b, int (*f)(int, int)) { printf("%d\n", f(a, b)); }.

Are function pointers safe?

They are safe as long as they point to a valid function. The risks are calling a NULL pointer without checking, or assigning a function with an incompatible signature (undefined behavior).