Ferramentas do usuário

Ferramentas do site


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:

// uma função com protótipo "int name (int)"
int f (int)
{ 
  ... 
}
 
// um ponteiro para funções com protótipo "int name (int)"
int (*fp) (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 é 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
 
// this function divides value by 2
void half (float *a)
{
  (*a) /= 2.0 ;
}
 
// this function multiplies value by 2
void twice (float *a)
{
  (*a) *= 2.0 ;
}
 
// this function applies function "func" to elements in vector "v"
void apply (float *v, int n, void (*func) (float*))
{
  for (int i=0; i< n; i++)
    func (&v[i]) ;
}
 
// this function prints a vector of floats
void printv (float *v, int n)
{
  for (int i=0; i<n; i++)
    printf ("%6.1f", v[i]) ;
  printf ("\n") ;
}
 
int main ()
{
  float vet[SIZE] ;
 
  // initial vector
  for (int i=0; i<SIZE; i++)
    vet[i] = i*10 ;
  printf ("Vet:   ") ;
  printv (vet, SIZE) ;
 
  // applies the function "half" to the vector
  apply (vet, SIZE, half) ;
  printf ("Half:  ") ;
  printv (vet, SIZE) ;
 
  // applies the function "twice" to the vector
  apply (vet, SIZE, twice) ;
  printf ("Twice: ") ;
  printv (vet, SIZE) ;
 
  return (0) ;
}

Resultado da execução:

Vet:      0.0  10.0  20.0  30.0  40.0   ...
Half:     0.0   5.0  10.0  15.0  20.0   ...
Twice:    0.0  10.0  20.0  30.0  40.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 · Última modificação: 2019/05/14 15:22 por maziero