// Un callback que recibe, además del dato, un contexto void *.
#include <stdio.h>

#define COUNT 6

typedef void (*Visitor)(int value, void *context);

void for_each(const int *values, int n, Visitor visit, void *context) {
    for (int i = 0; i < n; i++) {
        visit(values[i], context);
    }
}

typedef struct {
    int limit;
    int sum;
    int taken;
} SumAbove;

void add_if_above(int value, void *context) {
    SumAbove *state = context;
    if (value > state->limit) {
        state->sum += value;
        state->taken++;
    }
}

void print_labeled(int value, void *context) {
    const char *label = context;
    printf("%s %d\n", label, value);
}

int main(void) {
    int grades[COUNT] = {14, 9, 20, 11, 17, 13};

    SumAbove strict = {15, 0, 0};
    for_each(grades, COUNT, add_if_above, &strict);
    printf("mayores que %d: %d, suman %d\n", strict.limit, strict.taken, strict.sum);

    SumAbove easy = {10, 0, 0};
    for_each(grades, COUNT, add_if_above, &easy);
    printf("mayores que %d: %d, suman %d\n", easy.limit, easy.taken, easy.sum);

    for_each(grades, 2, print_labeled, "nota:");
    return 0;
}
