// Una función tiene dirección, y esa dirección se guarda en una variable.
#include <stdio.h>

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

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

// Otro nombre para el tipo "puntero a función que recibe dos int y devuelve un int".
typedef int (*BinaryOp)(int, int);

int apply(BinaryOp op, int a, int b) {
    return op(a, b);
}

int main(void) {
    int (*op)(int, int) = add;
    printf("op(2, 3) = %d\n", op(2, 3));

    op = multiply;
    printf("op(2, 3) = %d\n", op(2, 3));
    printf("(*op)(2, 3) = %d\n", (*op)(2, 3));
    printf("op == multiply: %d\n", op == multiply);

    BinaryOp chosen = add;
    printf("apply(chosen, 2, 3) = %d\n", apply(chosen, 2, 3));
    printf("apply(multiply, 2, 3) = %d\n", apply(multiply, 2, 3));
    return 0;
}
