代码之家  ›  专栏  ›  技术社区  ›  Edamame

使用回调的优点(在非事件驱动程序中)

  •  1
  • Edamame  · 技术社区  · 6 年前

    我正在查看中的回调示例: 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 回复  |  直到 6 年前
        1
  •  2
  •   Carcigenicate    6 年前

    Higher Order Function

    在这个特殊的例子中,它不是很有用。你说得对,直接传递数据会更容易。

    不过,这是一种允许函数泛化的技术,在正确使用时对减少代码重复非常有帮助。

    一个典型的例子是 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]
    

    如果没有高阶函数,则必须编写与 地图 每次要转换列表时。如果我想在其他地方给每个元素加2呢?或者每个乘以5?通过传递函数,您可以告诉它您希望它如何转换每个项,而不必担心迭代。


    抱歉,我不能用C回答这个问题。我理解你发布的代码中发生了什么,但我不懂C,所以我不能给出使用HOFs的好示例代码。

        2
  •  0
  •   Matthieu Brucher    6 年前

    通常,C中最常见的回调之一是 qsort

        3
  •  0
  •   mnistic    6 年前

    回调至少在两种情况下有用:

    • 对某些数据重复执行任务的函数。注释中给出的示例很好:作为回调传递给排序函数的比较函数是一个很好的有用回调示例。
    • 枚举函数。这是当您向库请求对象列表并希望对每个对象执行操作时。您将向枚举函数传递回调。例子: EnumWindows .