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.