Указатели на функции как параметры

Последнее обновление: 24.03.2023

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

Рассмотрим пример:

#include <iostream>
 
int add(int, int);
int subtract(int, int);
int operation(int(*)(int, int), int, int);	// первый параметр - указатель на функцию
 
int main()
{
    int a{10};
    int b{6};
    int result = operation(add, a, b);
    std::cout << "result: " << result << std::endl;
 
    result = operation(subtract, a, b);
    std::cout << "result: " << result << std::endl;
}
 
int add(int x, int y)
{
    return x + y;
}
int subtract(int x, int y)
{
    return x - y;
}
int operation(int(*op)(int, int), int a, int b)
{
    return op(a, b);
}

В данном случае первый параметр функции operation - int (*op)(int, int) - представляет указатель на функцию, которая возвращает значение типа int и принимает два параметра типа int. Результатом функции является вызов той функции, на которую указывает указатель.

Определению указателя соответствуют две функции: add и subtract, поэтому их адрес можно передать в вызов функции operation: operation(add, a, b);.

Результат работы программы:

result: 16
result: 4

Функция, передаваемая другой функции в качестве аргумента, называется функцией обратного вызова или коллбек (callback). А функция, которая принимает другую функцию в качестве аргумента, является функцией высшего порядка. Таким образом, в примере выше функция operation представляет функцию высокого порядка, а функции add и subtract - функции обратного вызова.

Рассмотрим другой пример - определим функцию, которая может принимать в качестве параметра некоторое условие и вычислять все элементы массива, которые соответствуют этому условию:

#include <iostream>
 
// функции, которые представляют условия
bool isEven(int);		// если число четное
bool isPositive(int);	// если число положительное

// Функция для определения элементов массива, которые соответствуют некоторому условию
// функция принимает условие - bool(*)(int)
// массив - int[]
// размер массива - unsigned
void action(bool(*)(int), int[], unsigned);
 
int main()
{
    int numbers[]{ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    const unsigned n { std::size(numbers)};	// находим длину массива
 
    std::cout << "Even numbers: " << std::endl;
    action(isEven, numbers, n);	// находим числа, которые соответствуют условию isEven
 
    std::cout << "\nPositive numbers: " << std::endl;
    action(isPositive, numbers, n);	// находим числа, которые соответствуют условию isPositive
}
bool isEven(int x)
{
    return x % 2 == 0;
}
bool isPositive(int x)
{
    return x > 0;
}
void action(bool(*condition)(int), int numbers[], unsigned n)
{
	// перебираем массив
    for (unsigned i{}; i < n; i++)
    {
		// если число (numbers[i] соответствует условию condition
        if (condition(numbers[i]))
        {
            std::cout << numbers[i] << "\t";
        }
    }
    std::cout << std::endl;
}

Функция action в качестве первого параметра принимает некоторую функцию, которая задает условие, которому должны соответствовать элементы массива. Это условие представляет указатель bool (*condition)(int). То есть это некоторая функцию, которая принимает целое число и в зависимости от того, соответствует оно условию или нет, возвращает значение типа bool (true, если число из массива соответствует условию, и false, если не соответствует). На момент определения функции action точное условие может быть неизвестно.

В текущей программе условия представлены двумя функциями. Функция isEven() возвращает true, если число четное, и false, если число нечетное. А функция isPositive() возвращает true, если число положительное, и false, если отрицательное.

Второй параметр функции action - массив чисел int, для которых вызываем условие. А третий параметр - размер массива. Если число соотвествует условию, то выводим это число на консоль

void action(bool(*condition)(int), int numbers[], unsigned n)
{
	// перебираем массив
    for (unsigned i{}; i < n; i++)
    {
		// если число (numbers[i] соответствует условию condition
        if (condition(numbers[i]))
        {
            std::cout << numbers[i] << "\t";
        }

При вызове функции action() в нее можно передать нужное условие:

action(isEven, nums, n);
action(isPositive, numbers, n);

В итоге программа выведет на экран числа из массива nums, которые соответствуют переданному условию:

Even numbers:
-4      -2      0       2       4

Positive numbers:
1       2       3       4       5
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850