Passando Funções como Argumentos
Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 36 de 61.
Um dos usos mais poderosos de ponteiros de função é passá-los como argumentos para outras funções. Isso permite que você injete comportamento personalizado em uma função sem modificar seu código — uma técnica às vezes chamada de callback.
Considere uma função que realiza um cálculo em dois números. Em vez de codificar rigidamente a operação, você pode aceitar um ponteiro de função que define qual operação realizar:
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}A função compute não sabe se está somando, subtraindo ou fazendo algo completamente diferente. Ela simplesmente chama qualquer função que lhe seja passada:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Saída: 8
printf("%d\n", compute(5, 3, multiply)); // Saída: 15
return 0;
}Observe como a mesma função compute produz resultados diferentes com base em qual função passamos. Este padrão é fundamental para escrever código flexível e reutilizável — você escreve a estrutura uma vez, e os usuários da sua função fornecem a lógica específica de que precisam.
Desafio
FácilEscreva uma função apply_twice que recebe dois inteiros e um código de operação, aplica a operação aos números duas vezes em sequência e retorna o resultado final.
Sua função receberá um código de operação que determina qual operação usar. Você deve definir as funções de operação dentro da sua solução e passá-las para uma função auxiliar compute que aceita um ponteiro de função.
Estrutura necessária:
- Defina um
typedefchamadoOperationpara um ponteiro de função que recebe dois parâmetrosinte retorna umint - Defina duas funções de operação:
add(retorna a + b) emultiply(retorna a * b) - Defina uma função
computeque recebe dois inteiros e um ponteiro de funçãoOperation, e então retorna o resultado da chamada da operação - Em
apply_twice, selecione a operação apropriada com base no código, então usecomputeduas vezes: primeiro com os números originais, depois com o resultado e o segundo número novamente
Lógica:
- Selecione a função de operação com base em
op_code(1 = add, 2 = multiply) - Chame
compute(a, b, operation)para obter um resultado intermediário - Chame
compute(intermediate, b, operation)para obter o resultado final - Retorne o resultado final
Parâmetros:
a(int): Primeiro númerob(int): Segundo númeroop_code(int): Código da operação (1 para add, 2 para multiply)
Retorno: O resultado após aplicar a operação duas vezes em sequência (int)
Exemplo: Com a = 5, b = 3, op_code = 1 (add):
- Primeiro compute: 5 + 3 = 8
- Segundo compute: 8 + 3 = 11
- Retorno: 11
Com a = 2, b = 4, op_code = 2 (multiply):
- Primeiro compute: 2 × 4 = 8
- Segundo compute: 8 × 4 = 32
- Retorno: 32
Folha de consulta
Ponteiros de função podem ser passados como argumentos para outras funções, permitindo callbacks — uma maneira de injetar comportamento personalizado sem modificar o código da função.
Defina um tipo de ponteiro de função usando typedef:
typedef int (*Operation)(int, int);Crie uma função que aceite um ponteiro de função como parâmetro:
int compute(int a, int b, Operation op) {
return op(a, b);
}Passe funções diferentes para alcançar comportamentos diferentes:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Saída: 8
printf("%d\n", compute(5, 3, multiply)); // Saída: 15
return 0;
}Esse padrão permite que você escreva código flexível e reutilizável, onde a estrutura é definida uma vez e os usuários fornecem a lógica específica de que precisam.
Experimente você mesmo
int apply_twice(int a, int b, int op_code) {
// Escreva o código aqui
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta7Ponteiros para Funções
Declarando Ponteiros para FunçõesChamando Ponteiros para FunçõesTypedef para Ponteiros para FunçõesPassando Funções como ArgumentosRecapitulação: Dispatch de Calculadora2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do Círculo