Um ponteiro de função nada mais é do que uma variável que armazena o endereço de uma função e possibilita sua chamada. Isso é útil em casos em que você precisa encapsular um comportamento ou principalmente precisa implementar um padrão de projetos em C! (Veja aqui um exemplo do padrão STRATEGY usando Ponteiros para Funções). Utilizar funções em ponteiros também fornece mais flexibilidade para seu código.
O uso dessa técnica é bem simples. Nesse exemplo vamos criar funções que fazem potenciação e raiz quadrada de um número e que são alteradas em apenas um lugar do código, dispensando a modificação de toda a estrutura. Veja o passo a passo abaixo:
1) Declare um ponteiro para função como se estivesse declarando uma função, porém com um * (asterisco) antes do seu nome e utilizando typedef. Na linha abaixo, foo é o nome do ponteiro para função e int é o parâmetro que esta recebe.
typedef void (*foo)(int);
O uso dessa técnica é bem simples. Nesse exemplo vamos criar funções que fazem potenciação e raiz quadrada de um número e que são alteradas em apenas um lugar do código, dispensando a modificação de toda a estrutura. Veja o passo a passo abaixo:
1) Declare um ponteiro para função como se estivesse declarando uma função, porém com um * (asterisco) antes do seu nome e utilizando typedef. Na linha abaixo, foo é o nome do ponteiro para função e int é o parâmetro que esta recebe.
typedef void (*foo)(int);
2) Depois é necessário declarar esse ponteiro dentro do código - igual como se declara uma variável - e também criar as funções que vamos apontar.
Criando as funções...
void func_pow(int n) {
printf("Potenciacao: %f\n", pow(n,2));
}
void func_sqrt(int n) {
printf("Raiz quadrada: %f\n", sqrt(n));
}
Declarando o ponteiro de função dentro do bloco principal ... Note que usamos o foo como tipo de variável e func_pointer é o nome que atribuímos.
int main(int argc, char const *argv[]) {
foo func_pointer;
return 0;
}
3) Agora é hora do ponteiro apontar para a função desejada e executá-la. A referência é feita usando o & que passa o endereço de memória para o ponteiro, aqui passando o endereço da função func_sqrt, e a chamada é feita pelo nome da função do ponteiro. Veja como fica o nosso bloco principal:
int main(int argc, char const *argv[]) {
foo func_pointer;
func_pointer = &func_sqrt; // passando endereço da função
func_pointer(16); // chamada
return 0;
}
Isso deve retornar a raiz quadrada do número 16, visto que passamos ele como parâmetro para a função ponteiro, a qual referencia a func_sqrt.
Muito bem. O programa já está funcionando. Mas e se o seguinte trecho de código for executado, o que acontecerá? Note que chamamos duas vezes func_pointer, porém atribuímos um segundo endereço de função para o ponteiro.
int main(int argc, char const *argv[]) {
foo func_pointer;
func_pointer = &func_sqrt; // passando endereço da função
func_pointer(16); // chamada
func_pointer = &func_pow;
func_pointer(16);
return 0;
}
O programa vai imprimir no console o seguinte:
Raiz quadrada: 4.000000
Potenciacao: 256.000000
Esses recursos permitem com que o programa seja flexibilizado e usufrua de algumas características da programação orientada à objetos. Talvez você não tenha encontrado um benefício para aplicar essa técnica, então te aconselho a aprender orientação à objetos e padrões de projetos! (hehe)
O código fonte do exemplo está disponível abaixo:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
// Declaração do ponteiro para função
typedef void (*foo)(int);
// Definição das funções que serão apontadas
void func_pow(int n) {
printf("Potenciacao: %f\n", pow(n,2));
}
void func_sqrt(int n) {
printf("Raiz quadrada: %f\n", sqrt(n));
}
// Bloco principal - main
int main(int argc, char const *argv[]) {
foo func_pointer;
func_pointer = &func_sqrt; // passando endereço da função
func_pointer(16); // chamada
func_pointer = &func_pow;
func_pointer(16);
return 0;
}
Comentários
Postar um comentário