Utilizando a função QSort em C
Neste artigo darei uma breve introdução a ponteiros de funções: O que são? Como declará-los? É possível usá-los?. Além disso falaremos de uma função muito mistificada por nós brasileiros, a QSort. A QSort é definida pelo ANSI C e seu nome se deve a utilizar o algoritmo QuickSort.
Parte 3: QSort
Agora que já falamos sobre ponteiros de funções, estamos preparados
para ver o protótipo da função QSort:
void qsort( void *base, size_t quantidade, size_t tamanho, int(*compar)(const void *, const void *) );
A função QSort, como já falamos, serve para ordenar coisas. A função para manter seu nível de abstração o mais alto possível adotou uma saída inteligente para saber como ordenar as coisas sem se preocupar com isso. A solução está no último parâmetro:
int(*compar)(const void *, const void *)
A função QSort é dependente de outra função e esta é criada pelo programador. A única coisa que temos que ter em mente é que a função retornará um inteiro e receberá dois parâmetros do tipo void.
Voltando ao QSort, o primeiro parâmetro recebe a base do nosso vetor, em seguida temos de dizer a quantidade de elementos existentes no vetor. Nosso terceiro parâmetro é o tamanho de cada elemento do vetor, seguido por um ponteiro para função.
A função que o ponteiro para função apontar será chamada sempre com dois elementos e seu retorno ditará se os elementos serão trocados de lugar ou não. Para ficar mais claro, os valores de retorno para o QSort são:
Baseado nisso, temos uma função chamada "compara" para ser utilizada por QSort no nosso exemplo. O QSort sempre irá ordenar os vetores em ordem ascendente, mas podemos aproveitar de sua dependência da função externa e ao inverter a lógica usada, ordenar de forma descendente. Isto torna possível o programador escolher se a ordenação será do maior pro menor ou do menor pro maior. Além disso, como QSort lida com qualquer dado, seria impossível de automatizar uma tarefa dessas.
void qsort( void *base, size_t quantidade, size_t tamanho, int(*compar)(const void *, const void *) );
A função QSort, como já falamos, serve para ordenar coisas. A função para manter seu nível de abstração o mais alto possível adotou uma saída inteligente para saber como ordenar as coisas sem se preocupar com isso. A solução está no último parâmetro:
int(*compar)(const void *, const void *)
A função QSort é dependente de outra função e esta é criada pelo programador. A única coisa que temos que ter em mente é que a função retornará um inteiro e receberá dois parâmetros do tipo void.
Voltando ao QSort, o primeiro parâmetro recebe a base do nosso vetor, em seguida temos de dizer a quantidade de elementos existentes no vetor. Nosso terceiro parâmetro é o tamanho de cada elemento do vetor, seguido por um ponteiro para função.
A função que o ponteiro para função apontar será chamada sempre com dois elementos e seu retorno ditará se os elementos serão trocados de lugar ou não. Para ficar mais claro, os valores de retorno para o QSort são:
- Se o primeiro for maior que o segundo deve retornar um número maior que zero;
- Se o primeiro for menor que o segundo deve retornar um valor menor que zero;
- Se forem iguais então retorna zero.
Baseado nisso, temos uma função chamada "compara" para ser utilizada por QSort no nosso exemplo. O QSort sempre irá ordenar os vetores em ordem ascendente, mas podemos aproveitar de sua dependência da função externa e ao inverter a lógica usada, ordenar de forma descendente. Isto torna possível o programador escolher se a ordenação será do maior pro menor ou do menor pro maior. Além disso, como QSort lida com qualquer dado, seria impossível de automatizar uma tarefa dessas.
Notei que você usou cast dentro da função que compara os valores, tem outro meio de fazer isso (as vezes até mais facil).
A função para comparar você já define como inteiro..
int compara(int *x, int *y)
{
if (*x > *y)
return 1;
else if (*x == *y)
return 0;
else if (*x < *y)
return -1;
}
E na hora de usar o qsort você faz um cast para void* na função...
qsort( vetor, (size_t) tamanho, sizeof(int), (void *) compara );
Abraços,
Fiquem com Deus.