Таблицы диспетчеризации могут быть реализованы несколькими способами. Один - с таблицей указателей на функции:
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 a / b; }
int DoFunction(int Select, int a, int b)
{
/* Declare a type to point to a function with parameters (int a, int b)
and returning an int.
*/
typedef int (*MyFunctionPointer)(int a, int b);
// Build a dispatch table with pointers to functions.
MyFunctionPointer Table[] =
{
Add,
Subtract,
Multiply,
Divide,
};
// Dispatch to the requested function.
return Table[Select](a, b);
}
#include <stdio.h>
int main(void)
{
// Demonstrate calls using dispatch table.
printf("7 + 3 = %d.\n", DoFunction(0, 7, 3));
printf("7 - 3 = %d.\n", DoFunction(1, 7, 3));
printf("7 * 3 = %d.\n", DoFunction(2, 7, 3));
printf("7 / 3 = %d.\n", DoFunction(3, 7, 3));
}
Можно также перейти в таблицу инструкций перехода. Это чаще встречается в ассемблере, чем в языках более высокого уровня.
По сути, таблица диспетчеризации - это некоторый метод передачи управления программой в место, выбранное с помощью индекса, а не путем индивидуального выбора, такого как if
или switch
заявления. В некоторых ситуациях проще или проще вычислить индекс для выбора функции, чем написать несколько запутанных операторов выбора.
(В этом примере показаны однородные функции - все они имеют один и тот же список типов параметров и возвращаемый тип. Если функции неоднородны, может быть сложнее использовать таблицу диспетчеризации в C.)
Хотя таблицы диспетчеризации не часто встречаются во многих исходных кодах (и не являются редкостью), их можно использовать для множество вещей, например:
На некоторых процессорах подпрограммы обслуживания прерываний обрабатываются с помощью таблицы диспетчеризации: в памяти есть фиксированные ячейки, в которых хранятся адреса подпрограмм, образуя таблицу адресов. Когда происходит прерывание, оборудование ищет адрес и передает ему управление.
В коде, который должен быть высокопроизводительным на разнообразном оборудовании, мы можем подготовить несколько функций, каждая из которых использовать другой алгоритм, разработанный для конкретного оборудования. Когда программа запускается, она может проверить, на каком оборудовании она работает (например, определенная модель процессора c), и записать индекс в таблицу. Этот индекс указывал бы, какую процедуру выполнять. Затем вызовы функции могут использовать индексную таблицу для быстрой диспетчеризации без необходимости тестирования и перехода для каждого вызова.