Кроме одиночных указателей на функции, в языке Си можно определять массивы указателей на функции. Для этого используется следующий формальный синтаксис:
1 |
тип (*имя_массива[размер]) (параметры) |
Например:
1 |
double (*actions[]) (int, int) |
Здесь actions представляет собой массив указателей на функции, каждая из которых обязательно должна принимать два параметра типа int и возвращать значение типа double.
Посмотрим применение массива указателей на функции на примере:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
#include <stdio.h>
void add(int x, int y)
{
printf("x+y=%d \n", x+y);
}
void subtract(int x, int y)
{
printf("x+y=%d \n", x-y);
}
void multiply(int x, int y)
{
printf("x*y=%d \n", x*y);
}
int main(void)
{
int a = 10;
int b = 5;
void (*operations[3])(int, int) = {add, subtract, multiply};
// получаем длину массива
int length = sizeof(operations)/sizeof(operations[0]);
for(int i=0; i<length;i++)
{
operations[i](a, b); // вызов функции по указателю
}
return 0;
} |
Здесь массив operations содержит три функции add, subtract и multiply, которые последовательно вызываются в цикле через перебор массива в функции main.
Еще пример:
Тип данных вида void (*pp[])(аргументы) расшифровывается в соответствии с контекстным определением типа данных как массив указателей на функции с общим прототипом (схемой передачи параметров и результата) – последовательность операций в контексте – массив – указатель – вызов функции. Образно, хотя и не совсем точно, этот тип можно назвать таблицей функций, вызов которых может производиться по номеру (индексу).
Вызов функции, размещенной в массиве функций, происходит следующим образом:
(*pp[i])(аргуметы)
или, более кратко, но тоже правильно:
pp[i](аргуметы)