Pular para o conteúdo principal

Ponteiros de funções em C

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);


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

Postagens mais visitadas deste blog

Comando system("cls"); Limpando a tela

Para utilizar o comando system("cls"); é necessário a declaração da biblioteca stdlib.h no início do programa. Sua função é limpar a tela de saída de programa que é executado no MS-DOS, ou seja, funciona como um "apagador" para tudo que já foi escrito. O programa a seguir imprime na tela o que o programador colocou no printf e depois de pressionar uma tecla tudo é limpo, ou seja, apaga tudo o que já foi escrito e imprime as outras funções que foram programadas. Link para o código-fonte do exemplo (Pastebin ) Agora visualize o que deve acontecer com o seu programa:

Biblioteca Conio.c

A biblioteca conio.c é a modificação da biblioteca conio.h para poder disponibilizar algumas funcionalidades no programa Dev C/C++ . Com ela é possível usar os comandos textcolor(), backgroundcolor(), gotoxy(), clrscr(), etc, e deixar a saída dos dados com um layout mais agradável para o usuário. O link abaixo redireciona para o site 4shared.com, o qual permite fazer o download da biblioteca. Download Conio.c - 4shared Junto com a biblioteca vem um pequeno tutorial de instalação no  Dev .   ATENÇÃO: Para o funcionamento das funções é necessário a adição da biblioteca no início do programa.

Mudar cor da saída em C/C++(printf)

Para alterar a cor do comando de saída - ou impressão na tela - utilizando o Dev C/C++ (em ambiente Windows) é necessário a instalação da biblioteca conio.c .  Após seguir as instruções de instalação, é necessário declará-la no topo do código-fonte utilizando o comando " #include <conio.c> " (sem aspas). Após declarar a biblioteca, o comando textcolor() é o que vai alterar a cor do texto de saída. Sua estrutura é a seguinte:   textcolor( cor ); A palavra 'cor' escrita entre parênteses representa a cor que o desenvolvedor deseja para o seu programa. Abaixo segue a tabela das cores disponíveis.