Uma função é vista como uma referência para uma área de memória onde reside seu código. Por isso, o identificador de uma função pode ser visto como um ponteiro. Funções podem ser acessadas usando ponteiros, de forma similar às variáveis.
Declarar um ponteiro para uma função é relativamente simples. O código abaixo declara um ponteiro fp
para uma função que tem um parâmetro inteiro e retorna um inteiro (como a função inc
dos códigos acima):
int f (int) { ... } ; // função com protótipo "int function (int);" int (*fp) (int) ; // ponteiro para função com protótipo "int function (int)"
Observe que os parênteses envolvendo *fp
são necessários. Caso sejam omitidos, a declaração acima muda completamente de sentido:
int * fp (int) ; // protótipo de função retornando um int*
O uso de ponteiros para funções também é simples:
#include <stdio.h> void inc (int *n) { (*n)++ ; } int main () { void (*fp) (int *) ; // function pointer fp = inc ; // fp points to inc int a = 0 ; printf ("a vale %d\n", a) ; inc(&a) ; // normal call printf ("a vale %d\n", a) ; fp(&a) ; // call using the function pointer printf ("a vale %d\n", a) ; return (0) ; }
Sua execução resulta em:
a vale 0 a vale 1 a vale 2
Assim, funções podem ser usadas como parâmetros de outras funções, através de ponteiros.
#include <stdio.h> #define SIZE 10 // divides value by 2 void half (float *a) { (*a) /= 2.0 ; } // multiplies value by 2 void twice (float *a) { (*a) *= 2.0 ; } // applies function "func" to all elements of vector "v" void apply (float *v, int n, void (*func) (float*)) { int i ; for (i=0; i< n; i++) func (&v[i]) ; } // prints a float vector void printv (float *v, int n) { int i ; for (i=0; i<n; i++) printf ("%6.1f", v[i]) ; printf ("\n") ; } int main () { float vet[SIZE] ; int i ; for (i=0; i<SIZE; i++) vet[i] = i*10 ; printv (vet, SIZE) ; // applies the function "half" to the vector apply (vet, SIZE, half) ; printv (vet, SIZE) ; // applies the function "twice" to the vector apply (vet, SIZE, twice) ; printv (vet, SIZE) ; return (0) ; }
Resultado da execução:
0.0 10.0 20.0 30.0 40.0 50.0 60.0 70.0 80.0 90.0 0.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 0.0 10.0 20.0 30.0 40.0 50.0 60.0 70.0 80.0 90.0
qsort
(man 3 qsort) aplica o algoritmo QuickSort a um vetor de dados de um tipo definido pelo usuário (int, float, struct, …). Para ser genérica, essa função depende de uma função externa para comparar os elementos do vetor. Escreva um programa que a) crie um vetor de 100 inteiros aleatórios e ordene esse vetor usando a função qsort
.double
.