sexta-feira, 30 de novembro de 2012

Ponteiros para Funções

Quando utilizarmos a função qsort da stdlib.h precisamos aprender a usar ponteiros para funções. No caso do qsort, o programador precisa passar como parâmetro uma função compar que será utilizado pelo algoritmo quicksort para realizar a comparação.

void qsort ( void * base, size_t num, size_t size,
            int ( * compar ) ( const void *, const void * ) );

Observe que o último parâmetro é um ponteiro para função. Considere o seguinte exemplo:
#include <stdio.h>
#include <stdlib.h>
int soma(int a, int b){
 return a+b;
}
int mul(int a, int b){
 return a*b;
}
int g(int a, int b, int (*f) (int,int) ){
 return f(a,b);
}
int main(){
  int (*f) (int,int); 
  f = soma;
  printf("%d\n",f(2,3));
  f = mul;
  printf("%d\n",f(2,3));
  printf("%d\n", g(2,3,soma) );
  printf("%d\n", g(2,3,mul) );
  return 0;
}

Declarando um ponteiro para função

int (*f) (int,int);

O f é um ponteiro para função que retorna um tipo int e recebe dois inteiros como parâmetros. Note que a função soma e mul tem o mesmo tipo da função apontada por f. Todas as funções que retornam um int e recebem dois inteiros como parâmetros podem ser utilizadas através do ponteiro f.


f = soma;

printf("%d\n",f(2,3)); //imprime 5

f = mul;

printf("%d\n",f(2,3)); //imprime 6

Recebendo ponteiros para funções como parâmetros
A função g recebe como parâmetro uma função f da seguinte maneira:


int g(int a, int b, int (*f) (int,int) ){
 return f(a,b);
}


Usando a função qsort
void qsort ( void * base, size_t num, size_t size, int ( * compar ) ( const void *, const void * ) );
base ponteiro para o primeiro elemento do vetor a ser classificado. num Número de elementos no vetor apontada por base. size_t é o tamanho em bytes de cada elemento no vetor. compar função que compara dois elementos. Esta função é chamada repetidamente pelo qsort para comparar dois elementos. Ele deve seguir o seguinte protótipo: int compar (const void * elem1, const void * elem2);
A função recebe dois ponteiros como argumentos (ambos do tipo const void *). A função deve comparar os dados apontados por ambos: se eles são iguais na classificação, a função deve retornar zero, se elem1 vem antes elem2, deve retornar um valor negativo, e se ele vai depois, um valor positivo.
#include <stdio.h>
#include <stdlib.h>

int compara1(const void *a, const void *b){
 int pa = *(int *)a;
 int pb = *(int *)b;
 return pa-pb;
}

int compara2(const void *a, const void *b){
 int pa = *(int *)a;
 int pb = *(int *)b;
 return pb-pa;
}
int main(){
int i; 
 int v[] = {3,4,6,1,2};
 qsort(v,5,sizeof(int),  compara1);
 printf("vetor ordenado em ordem crescente\n");
 for(i=0;i <5; i++)
  printf("%d\n",v[i]);
 qsort(v,5,sizeof(int),  compara2);
 printf("vetor ordenado em ordem decrescente\n");
 for(i=0;i <5; i++)
  printf("%d\n",v[i]);
}
Saída
vetor ordenado em ordem crescente 1
2
3
4
6
vetor ordenado em ordem decrescente
6
4
3
2
1

Nenhum comentário: