Menu
Coddy logo textTech

Передача функций в качестве аргументов

Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 36 из 61.

Одним из наиболее мощных способов использования указателей на функции является их передача в качестве аргументов другим функциям. Это позволяет внедрять настраиваемое поведение в функцию без изменения её кода — метод, который иногда называют callback.

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

typedef int (*Operation)(int, int);

int compute(int a, int b, Operation op) {
    return op(a, b);
}

Функция compute не знает, выполняет ли она сложение, вычитание или что-то совсем другое. Она просто вызывает ту функцию, которая ей передана:

int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }

int main() {
    printf("%d\n", compute(5, 3, add));       // Результат: 8
    printf("%d\n", compute(5, 3, multiply));  // Результат: 15
    return 0;
}

Обратите внимание, как одна и та же функция compute выдает разные результаты в зависимости от того, какую функцию мы передаем. Этот паттерн является основополагающим для написания гибкого, переиспользуемого кода — вы пишете структуру один раз, а пользователи вашей функции предоставляют конкретную логику, которая им необходима.

challenge icon

Задание

Легко

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

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

Требуемая структура:

  • Определите typedef с именем Operation для указателя на функцию, которая принимает два параметра типа int и возвращает int
  • Определите две функции операций: add (возвращает a + b) и multiply (возвращает a * b)
  • Определите функцию compute, которая принимает два целых числа и указатель на функцию Operation, а затем возвращает результат вызова этой операции
  • В функции apply_twice выберите соответствующую операцию на основе кода, затем используйте compute дважды: сначала с исходными числами, затем с полученным результатом и вторым числом снова

Логика:

  1. Выберите функцию операции на основе op_code (1 = add, 2 = multiply)
  2. Вызовите compute(a, b, operation), чтобы получить промежуточный результат
  3. Вызовите compute(intermediate, b, operation), чтобы получить конечный результат
  4. Верните конечный результат

Параметры:

  • a (int): Первое число
  • b (int): Второе число
  • op_code (int): Код операции (1 для add, 2 для multiply)

Возвращает: Результат после двукратного последовательного применения операции (int)

Пример: Для a = 5, b = 3, op_code = 1 (add):

  • Первое вычисление: 5 + 3 = 8
  • Второе вычисление: 8 + 3 = 11
  • Результат: 11

Для a = 2, b = 4, op_code = 2 (multiply):

  • Первое вычисление: 2 × 4 = 8
  • Второе вычисление: 8 × 4 = 32
  • Результат: 32

Шпаргалка

Указатели на функции могут передаваться в качестве аргументов другим функциям, обеспечивая работу обратных вызовов (callbacks) — способа внедрения пользовательского поведения без изменения кода самой функции.

Определите тип указателя на функцию с помощью typedef:

typedef int (*Operation)(int, int);

Создайте функцию, которая принимает указатель на функцию в качестве параметра:

int compute(int a, int b, Operation op) {
    return op(a, b);
}

Передавайте различные функции для достижения разного поведения:

int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }

int main() {
    printf("%d\n", compute(5, 3, add));       // Результат: 8
    printf("%d\n", compute(5, 3, multiply));  // Результат: 15
    return 0;
}

Этот паттерн позволяет писать гибкий, переиспользуемый код, в котором структура определяется один раз, а пользователи предоставляют конкретную логику, которая им необходима.

Попробуйте сами

int apply_twice(int a, int b, int op_code) {
    // Напишите код здесь
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming