Declarando Ponteiros para Funções
Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 33 de 61.
Até agora, aprendemos a simular herança usando incorporação de struct. Mas o polimorfismo verdadeiro — onde diferentes objetos respondem de maneira diferente à mesma chamada — exige algo mais: function pointers.
Um ponteiro para função é uma variável que armazena o endereço de uma função. Assim como um ponteiro comum mantém o endereço de dados, um ponteiro para função mantém o endereço de código executável.
A sintaxe pode parecer assustadora no início. Para declarar um pointer de function, você especifica o tipo de return, depois o nome do pointer entre parênteses com um asterisco, seguido pelos tipos de parameters:
int (*operation)(int, int);Isso declara uma variável chamada operation que pode apontar para qualquer função que recebe dois parâmetros int e retorna um int. Os parênteses ao redor de *operation são fundamentais — sem eles, você estaria declarando uma função que retorna um ponteiro.
Para atribuir uma função a este ponteiro, basta usar o nome da função (sem parênteses):
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // Agora operation aponta para addO nome da função atua como seu endereço. Você também pode usar &add explicitamente, mas é opcional — ambas as formas são equivalentes em C.
Desafio
FácilVamos praticar a declaração de ponteiros para funções e a atribuição de funções a eles. Você criará um sistema simples de operações matemáticas onde um ponteiro de função pode conter diferentes funções aritméticas.
Escreva um programa que:
- Define duas funções:
multiply— recebe dois parâmetrosinte retorna o produto delessubtract— recebe dois parâmetrosinte retorna o primeiro menos o segundo
- Em
main, declara uma variável ponteiro de função chamadaoperationque pode apontar para funções que recebem dois parâmetrosinte retornam umint - Lê três entradas: dois inteiros e um código de operação (1 para multiply, 2 para subtract)
- Com base no código da operação, atribui a função adequada ao seu ponteiro
operation - Imprime o nome da operação atribuída e, em seguida, imprime o resultado da chamada da função por meio do ponteiro
Você receberá três entradas: o primeiro número, o segundo número e o código da operação (1 ou 2).
Sua saída deve ser parecida com isto:
Operation: multiply
Result: 35Onde multiply é o nome da operação (ou subtract se o código for 2), e 35 é o resultado de chamar a função através do seu ponteiro (neste caso, 5 × 7).
Lembre-se: para declarar o ponteiro de função, você precisa do tipo de retorno, do nome do ponteiro entre parênteses com um asterisco e dos tipos de parâmetro. Para atribuir uma função, use apenas o nome da função sem parênteses.
Experimente você mesmo
#include <stdio.h>
// TODO: Defina a função multiply aqui
// TODO: Defina a função subtract aqui
int main() {
int num1, num2, code;
// Ler a entrada
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &code);
// TODO: Declare um ponteiro de função chamado 'operation' que possa apontar para
// funções que recebem dois parâmetros int e retornam um int
// TODO: Com base no código da operação (1 para multiply, 2 para subtract),
// atribua a função apropriada ao seu ponteiro operation
// TODO: Imprima o nome da operação e o resultado
// Formato:
// Operation: <name>
// Result: <result>
return 0;
}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írculoImplementação do RetânguloUso PolimórficoContainer de Formas