Ponteiros para Funções

 

Em C, podemos declarar um ponteiro para função com a sintaxe

     void (*f)();

neste caso, f é um ponteiro para uma função sem parâmetros e que retorna void. f pode apontar para uma função compatível :

     f = maximo;

maximo é uma função declarada como

   void maximo() {

      puts(“Olá ! Eu sou o máximo”);

   }

maximo pode ser chamada a partir de  f   usando-se quaisquer das sintaxes abaixo.

     (*f)();      /* chama maximo */

     f();         /* chama maximo */

Veja o programa completo.

           

Podemos definir um tipo em C através de typedef:

 

   typedef

      int Number[10];

 

Agora Number é sinônimo de vetores inteiros:

    Number v;  //   v é um vetor de inteiros de 10 posições

 

Da mesma forma, podemos definir Func como um ponteiro para funções:

 

typedef

   void (*Func)();

 

Func f;

f = maximo;

f();   // chama maximo

 

Podemos definir também um vetor de ponteiros para funções:

 

Func v[] = {

   maximo,

   minimo

};

 

minimo é definida como

 

void minimo() {

   puts(“Oi. Sou o mínimo”);

}

 

Agora, v é um vetor de ponteiros para funções. Ou melhor, v é um vetor de ponteiros para funções que não têm parâmetros nem retornam nada. Então v[0] é um ponteiro para uma função:

 

    v[0]();   //   chama maximo

    v[1]();   //   chama minimo

    (*v[0])();  // chama maximo

    (*v[1])();  // chama minimo

 

Até agora vimos apenas funções sem parâmetros e sem tipo de retorno. E se tivermos uma função

   int addOne(int i) {

      return i + 1;

   }

?

Vejamos:

 

void (*f)();

f = addOne;   // oops ...

f();  // oops ...

 

Na atribuição, há um erro de tipos. Estamos atribuindo uma função com um parâmetro e valor de retorno para um ponteiro para uma função sem parâmetros e sem valor de retorno. Temos que usar um cast:

     f = (void (*)()  )  addOne;

O tipo “void (*)()” lê-se “ponteiro para uma função sem parâmetro retornando void”. Na chamada de f, há outro erro. Estamos chamando a função sem passar o parâmetro. f  aponta para addOne que espera um parâmetro. Temos que converter f para o tipo de addOne antes de chamar esta função:

     n = ((int (*)(int)  ) f)(1);

O tipo “int (*)(int)”  é um ponteiro para uma função que tem um inteiro como parâmetro e retorna valor inteiro. O código completo deste exemplo está aqui.

 

            Podemos colocar funções de vários tipos em um único vetor:

 

Func v[] = {

   maximo,

   addOne,

   minimo

};

...

v[0]();   // chama maximo

n = ((int (*)(int)  )  v[1])(5);   //  chama addOne passando 5 como parâmetro

v[2]();  // chama minimo

 

Estudando detalhadamente o exemplo acima, descobrimos que há um erro de tipos na inicialização de v. Cada elemento de v deve ser do tipo Func, função sem parâmetros retornando void. Mas addOne possui um parâmetro e retorna int. Então devemos usar um cast:

 

Func v[] = {

   maximo,

   (int (*)(int) ) addOne,

   minimo

};

 

É so.