Passe funções como dados. Essencial para qsort, callbacks e tabelas de despacho.
typedef para dar ao tipo um nome legívelqsort já cobre a maioria das necessidades do mundo realint (*fp)(int) significa "fp é um ponteiro para uma função que recebe um int e retorna um int".
#include <stdio.h> int square(int x) { return x * x; } int main(void) { // fp points to "a function taking int, returning int" int (*fp)(int) = square; // function name decays to its address printf("%d\n", fp(5)); // 25 printf("%d\n", (*fp)(5)); // 25, older style return 0; }
fp = square e fp = &square são equivalentes, assim como fp(5) e (*fp)(5).fp(*fp) — fp é um ponteiro(int, int) — para uma função que recebe dois intsint externo — e retorna um intints e retorna um int"
int *fp(int); // ❌ NOT a function pointer // it's the prototype of a function returning int* int (*fp)(int); // ✅ function pointer
typedef int (*CmpFn)(const void *, const void *); void sort(int *a, int n, CmpFn cmp) { /* ... */ }
typedef transforma todo aquele tipo bagunçado em um único nome. Uma vez definido CmpFn, CmpFn x; declara um ponteiro de função.#include <stdio.h> void for_each(int *a, int n, void (*fn)(int)) { for (int i = 0; i < n; i++) fn(a[i]); } void print_int(int v) { printf("%d ", v); } void print_square(int v) { printf("%d ", v * v); } int main(void) { int a[] = {1, 2, 3, 4, 5}; for_each(a, 5, print_int); printf("\n"); for_each(a, 5, print_square); printf("\n"); return 0; }
qsort padrão recebe uma função de comparação como ponteiro de função, o que significa que pode ordenar qualquer tipo — ints, strings, structs, o que você quiser.void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
#include <stdio.h> #include <stdlib.h> int cmp_int_asc(const void *p1, const void *p2) { int a = *(const int *)p1; int b = *(const int *)p2; if (a < b) return -1; if (a > b) return 1; return 0; } int main(void) { int a[] = {5, 2, 8, 1, 9, 3}; qsort(a, 6, sizeof(int), cmp_int_asc); for (int i = 0; i < 6; i++) printf("%d ", a[i]); // 1 2 3 5 8 9 }
return a - b; parece funcionar, mas pode causar overflow para valores grandes ou negativos. Sempre compare e retorne -1, 0 ou 1.struct Student { char name[32]; int score; }; // higher score first, ties broken by name int cmp_student(const void *p1, const void *p2) { const struct Student *a = p1; const struct Student *b = p2; if (a->score != b->score) return (b->score > a->score) ? 1 : -1; return strcmp(a->name, b->name); } qsort(students, n, sizeof(struct Student), cmp_student);
switch gigante, use um array de ponteiros de função para um código limpo e orientado a dados:#include <stdio.h> double op_add(double a, double b) { return a + b; } double op_sub(double a, double b) { return a - b; } double op_mul(double a, double b) { return a * b; } double op_div(double a, double b) { return b != 0 ? a / b : 0; } struct OpEntry { char sym; double (*fn)(double, double); }; static const struct OpEntry ops[] = { {'+', op_add}, {'-', op_sub}, {'*', op_mul}, {'/', op_div}, }; double calc(char op, double a, double b) { for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) { if (ops[i].sym == op) return ops[i].fn(a, b); } return 0; } int main(void) { printf("%.2f\n", calc('+', 3, 4)); printf("%.2f\n", calc('*', 6, 7)); }
int em ordem decrescente.char *words[] = {"banana","apple","cherry"}; em ordem alfabética. Note que o comparador recebe const char **.int filter(int *a, int n, int *out, int (*pred)(int)). Ela deve copiar cada elemento para o qual pred retorna diferente de zero. Teste com um predicado de número par.Confira sua compreensão desta aula!
int (*fp)(int) declara?Os parênteses agrupam *fp, então se lê "fp é um ponteiro para uma função". Sem eles, int *fp(int) significa algo totalmente diferente.
qsort?qsort precisa lidar com tipos arbitrários, então os argumentos chegam como const void *. Faça o cast para o tipo real dentro da função de comparação.
fp?Em C, você pode chamar um ponteiro de função como se fosse um nome de função comum, usando (). O estilo antigo com desreferência explícita (*fp)(...) é equivalente.