DMarlon Studio

Lesson 6 · 6 of 20

Function pointers and callbacks · C

Store functions in variables and arrays with C function pointers and pass them as callbacks: pricing rules applied step by step.

C · Function pointers and callbacks in DMarlon Studio: the example's code and its output in the terminal

A function has an address too, and a function pointer stores it. The syntax is awkward, so give it a name with typedef: typedef double (*PriceRule)(double); defines PriceRule as "pointer to a function that takes a double and returns a double". add_vat, discount and round_up all fit that type.

apply_all receives one of those functions in its rule parameter and calls it with rule(prices[i]) for each price. That is a callback: apply_all knows how to walk the array, but what happens to each price is up to the caller.

To pass a function, use its name without parentheses: discount is the function's address; discount(5) would call it.

steps is an array of structs holding a name and a rule. The loop applies the rules in order (a 10% discount, 21% VAT and rounding up) and prints the prices after each step. Reordering or adding a rule means touching only the table, not the loop.

Function pointers are everywhere in C: qsort takes the comparison function, atexit the one to run on exit, and GUI libraries the one that handles each button.

Code · main.c

#include <stdio.h>// A type for "a function that takes a double and returns a double".typedef double (*PriceRule)(double);double add_vat(double p)  { return p * 1.21; }double discount(double p) { return p * 0.90; }double round_up(double p) { return (int)(p + 0.99); }// apply_all receives a callback: what to do with each price is up to the caller.void apply_all(double *prices, int n, PriceRule rule) {    for (int i = 0; i < n; i++) prices[i] = rule(prices[i]);}void print_prices(const char *label, const double *prices, int n) {    printf("%-12s", label);    for (int i = 0; i < n; i++) printf(" %7.2f", prices[i]);    printf("\n");}int main(void) {    double prices[] = {10.00, 24.50, 7.95, 99.00};    int n = sizeof prices / sizeof prices[0];    print_prices("Start", prices, n);    // A table of named rules: an array of function pointers.    struct { const char *name; PriceRule rule; } steps[] = {        {"Discount", discount}, {"With VAT", add_vat}, {"Rounded", round_up},    };    for (int s = 0; s < 3; s++) {        apply_all(prices, n, steps[s].rule);        print_prices(steps[s].name, prices, n);    }    return 0;}

Output · cc main.c -o main && ./main

Start          10.00   24.50    7.95   99.00
Discount        9.00   22.05    7.16   89.10
With VAT       10.89   26.68    8.66  107.81
Rounded        11.00   27.00    9.00  108.00

Key points

  • typedef R (*Name)(params); names a function pointer type.
  • A function's name without () is its address.
  • A callback is a function handed to another one to call.
  • A table of structs with function pointers replaces a long switch.

Exercise

Add a psychological rule that turns each price into x.99 (for example 27.00 becomes 26.99) and put it at the end of the steps table.