Многие языки программирования поддерживают функции высшего порядка. Согласно Википедии, функции высшего порядка — это функции, которые могут либо иметь другую функцию в качестве параметра, либо возвращать другую функцию.

В контексте языка программирования C стиль функций высшего порядка может быть реализован с помощью указателей на функции. Когда мы используем указатели на функции, мы можем присваивать их, помещать в массивы, передавать их функциям, возвращать их функциями и так далее. Далее я покажу вам простой пример, написанный на C, чтобы продемонстрировать, как мы можем использовать указатели на функции и применять стиль функций высшего порядка.

Программа представляет собой простой калькулятор, который принимает два целых числа и одну операцию и возвращает целое число в результате операции. Я буду использовать сумму, вычитание, умножение и деление как операции, хранить их в массиве, а затем передавать каждую операцию функции для получения результата.

Ниже у нас есть прототипы функций:

int sum(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);
int calc(int, int, int (*)(int, int));

Третий параметр функции calc — это указатель на функцию с двумя целыми числами в качестве параметров, которая возвращает целое число, точно такое же, как в sum, прототипы функций sub, mul и div. Здесь мы передаем функцию в качестве параметра другой функции, то есть применяемой функции более высокого порядка! Далее у нас есть определения функции:

/* sum: sum two integral numbers. */
int sum(int x, int y)
{ 
    return x + y;
}
/* sub: subtracts two integral numbers. */
int sub(int x, int y)
{
    return x — y;
}
/* mul: multiplies two integral numbers. */
int mul(int x, int y)
{
    return x * y;
}
/* div: divides two integral numbers. */
int div(int x, int y)
{
    return x / y;
}
/* calc: receives two integral numbers and returns an integral number that is the result of the supplied operation. */
int calc(int x, int y, int (*operation)(int, int))
{
    return (*operation)(x, y);
}

Обратите внимание, как третий параметр использовался внутри функции calc. Мы берем функцию указателя и выполняем ее внутри функции calc, поэтому поведение функции calc является динамическим в соответствии с предоставленная операция.

Наконец, приведенный ниже код показывает реализацию основной функции, где у нас есть массив указателей на функции, называемые операциями, которые будут повторяться, и каждая операция будет передана функции calc в качестве аргумента.

int main(int argc, char const *argv[])
{ 
    /* operations is an array of pointers to functions that receive two integers and return an integer */ 
    int (*operations[4])(int, int) = { sum, sub, mul, div };
    for (int i = 0; i < 4; i++) {
        /* the result will change according to the operation used by calc function */ 
        printf(“Result: %d.\n”, calc(10, 5, operations[i]));
    }

    return 0;
}

И результат, полученный при выполнении этого кода, указан ниже:

Result: 15.
Result: 5.
Result: 50.
Result: 2.

Полный код можно найти на моем GitHub.

В этом посте я упомянул, что такое функции высшего порядка и как мы можем применять их в коде C, используя указатели на функции, на примере функции, которая принимает другую функцию в качестве параметра.

До следующего чтения!