User Tools

Site Tools


prog2:ponteiros_para_funcoes

Ponteiros para funções

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:

funcptr.c
#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.

funcparam.c
#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

Exercícios

  1. A função 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.
  2. Idem, para um vetor de tipo double.
  3. Idem, para um vetor de structs (ordenar por um dos campos do struct).
prog2/ponteiros_para_funcoes.txt · Last modified: 2019/04/09 13:36 (external edit)