C/C++ Arena

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