Step 3 of 6
A dispatch table
When a program must choose between many actions based on a name or number, a long if/else if chain grows with every new case, and the "what" and the "how" get mixed together. A dispatch table separates them: an array of structs, each pairing a key with a function pointer. Finding the right entry is a simple search, and adding a new action is one line in the table.
#include <stdio.h>
#include <string.h>
static void say_hi(void) { printf("hello!\n"); }
static void say_time(void) { printf("it is 12:00\n"); }
static void say_help(void) { printf("commands: hi, time, help\n"); }
typedef struct {
const char *name;
void (*run)(void);
} Command;
static const Command table[] = {
{"hi", say_hi},
{"time", say_time},
{"help", say_help},
};
int main(void) {
const char *inputs[] = {"time", "dance", "hi"};
size_t ncmds = sizeof table / sizeof table[0];
for (int k = 0; k < 3; k++) {
size_t i = 0;
while (i < ncmds && strcmp(table[i].name, inputs[k]) != 0) i++;
if (i < ncmds) table[i].run();
else printf("unknown: %s\n", inputs[k]);
}
return 0;
}
it is 12:00
unknown: dance
hello!
The lookup
Search the table for a matching name. If the loop stops early, i is the matching index and you call table[i].run(); if i reaches the table size, the name wasn't found. The same code handles 3 commands or 300.
Where it's used
Command-line tools with subcommands (git commit, git push), interpreters mapping instructions to handlers, network servers mapping message types to handlers, and state machines all use tables like this. sizeof table / sizeof table[0] keeps the count right automatically when you add rows.
Your turn: the program reads lines like add 2 3 until end of input. Look up the command in the table and print the result, or unknown CMD if it isn't there. Add a mul command to the table as well.
Previous: typedef and passing callbacks Next: Sorting with qsort