5.1.13 · D3C Programming

Worked examples — Function pointers — declaration, calling, use in callbacks

3,696 words17 min readBack to topic

This page is the "run every case" workshop for Function pointers. The parent note built the ideas; here we exercise them until no scenario can surprise you. If a symbol shows up you don't recognise, it was defined in the parent — but we'll re-anchor the important ones as we go.

Prerequisites we lean on: Pointers in C, Arrays in C, void pointers, typedef, qsort and the C Standard Library, and the idea of Polymorphism.


The scenario matrix

Before working examples, let's list every kind of situation a function pointer can put in front of you. Think of this like the "all quadrants + zero + limits" checklist for angles — but for code. Each row is a case class; every example below is tagged with the cell it fills.

# Case class What makes it tricky Example that covers it
A Declare + call a plain fn pointer (*p) parentheses; two call syntaxes Ex 1
B Ascending sort via qsort (positive sign) comparator returns positive Ex 2
C Descending sort (flipped sign) comparator returns negative Ex 2
D Equal elements (zero case) comparator returns 0, stability Ex 3
E Degenerate input: array of size 0 or 1 callback may never fire Ex 4
F Dispatch table (array of fn pointers) index selects behaviour Ex 5
G1 Overflow trap (a-b) subtraction returns wrong sign Ex 6
G2 Signature mismatch (wrong type) UB from calling through mismatched type Ex 7
H NULL / uninitialised pointer (degenerate) calling garbage → crash Ex 8
I Real-world word problem callback as "behaviour parameter" Ex 9
J Exam-style twist (pointer to fn returning pointer) reading gnarly declarations Ex 10

Ex 1 — Declare, assign, call (Cell A)


Ex 2 — Ascending and descending sort (Cells B & C)

The figure below shows the single rule that drives every sort: qsort reads only the sign of your comparator. Three coloured buckets — teal for negative (first goes before second), plum for zero (equal), burnt orange for positive (first goes after second) — and an orange arrow tracing the worked case x=3, y=1 → +1. Keep this picture in mind whenever a comparator returns a number.

Figure — Function pointers — declaration, calling, use in callbacks

Ex 3 — Equal elements: the zero case (Cell D)


Ex 4 — Degenerate inputs: size 0 and size 1 (Cell E)


Ex 5 — Dispatch table (Cell F)

The figure below draws the dispatch table as three top slots (ops[0], ops[1], ops[2]), each holding a code address, with a coloured arrow pointing down to the actual function body (add → a+b in teal, sub → a-b in orange, mul → a*b in plum). The caption traces ops[1](10,4) → sub(10,4) → 6. Read it as "index picks a wire, the wire runs code."

Figure — Function pointers — declaration, calling, use in callbacks

Ex 6 — Overflow trap: why a - b is a landmine (Cell G1)


Ex 7 — Signature mismatch: the wrong-type call (Cell G2)


Ex 8 — NULL / uninitialised pointer (Cell H)


Ex 9 — Real-world word problem (Cell I)


Ex 10 — Exam twist: pointer to function returning a pointer (Cell J)


Recall Matrix coverage check

Which cells did we cover, A–J? ::: All of them: A(Ex1), B&C(Ex2), D(Ex3), E(Ex4), F(Ex5), G1(Ex6), G2(Ex7), H(Ex8), I(Ex9), J(Ex10). No cell left unshown.


Connections

  • Parent topic ↩
  • qsort and the C Standard Library — Ex 2, 3, 4 live here.
  • void pointers — why the comparator takes const void *.
  • Arrays in C — the dispatch table of Ex 5.
  • typedef — taming the Ex 10 declaration.
  • Polymorphism — one call site, many behaviours (Ex 2, 5, 9).
  • Pointers in C — the base idea behind all of it.