Преимущества использования обратного вызова (в не управляемой событиями программе) - PullRequest
0 голосов
/ 23 ноября 2018

Я ищу пример обратного вызова в: https://en.wikipedia.org/wiki/Callback_(computer_programming)

#include <stdio.h>
#include <stdlib.h>

/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
    int val1 = numberSource();
    int val2 = numberSource();
    printf("%d and %d\n", val1, val2);
}

/* A possible callback */
int overNineThousand(void) {
    return (rand()%1000) + 9001;
}

/* Another possible callback. */
int meaningOfLife(void) {
    return 42;
}

/* Here we call PrintTwoNumbers() with three different callbacks. */
int main(void) {
    PrintTwoNumbers(&rand);
    PrintTwoNumbers(&overNineThousand);
    PrintTwoNumbers(&meaningOfLife);
    return 0;
}

Я понимаю все функции.Однако мне интересно, кроме сокращения строки, в чем преимущество:

PrintTwoNumbers(&overNineThousand);

, а не просто использовать их как обычные функции:

int a = overNineThousand();
PrintTwoNumbers(a);

Спасибо!

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

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

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

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

0 голосов
/ 23 ноября 2018

Существует как минимум две ситуации, в которых полезны обратные вызовы:

  • Функции, в которых задача выполняется несколько раз над некоторыми данными.Пример, приведенный в комментариях, хорош: функция сравнения, переданная в функцию сортировки в качестве обратного вызова, является хорошим примером полезного обратного вызова.
  • Функции перечисления.Это когда вы запрашиваете у библиотеки список объектов, и вы хотите воздействовать на каждый из них.Вы должны передать обратный вызов в функцию перечисления.Пример: EnumWindows.
0 голосов
/ 23 ноября 2018

Это тривиальный пример того, что известно как Функция высшего порядка .

В этом конкретном примере это не очень полезно.Вы правы в том, что было бы проще просто передать данные напрямую.

Это метод, который позволяет обобщать функции и очень полезен для уменьшения дублирования кода при правильном использовании.

Типичным примером является функция map, которая преобразует список:

var arr = [1, 2, 3];
var newArr = arr.map(x => x + 1); // Pass a function that adds one to each element

print(newArr); // Prints [2, 3, 4]

Без функций более высокого порядка вам придется писать один и тот же код цикла, который содержит map каждый раз, когда вы хотите преобразоватьсписок.Что если я хочу добавить 2 к каждому элементу где-нибудь еще?Или умножить каждый на 5?Передав функцию, вы можете сказать ей, как вы хотите, чтобы она преобразовывала каждый элемент, не беспокоясь об итерации.

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


Извините, я не мог ответить на это в C. Я понимаю, что происходит в коде, который выопубликовал, но я не знаю C, поэтому я не мог привести хороший пример кода, который использует HOF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...