Médio C
Callbacks com qsort
Enunciado
Escreva um programa que ordene um array de int usando qsort e uma função de comparação que ordene em ordem decrescente. Imprima o array ordenado.
Requisitos
- Incluir
<stdlib.h>para usarqsort. - Definir uma função de comparação que retorne valor positivo se o primeiro elemento for menor que o segundo (para ordem decrescente).
- Chamar
qsortpassando o array, seu tamanho, o tamanho de cada elemento e a função de comparação. - Imprimir os elementos separados por espaço.
Código inicial
#include <stdio.h>
#include <stdlib.h>
int compara_decrescente(const void *a, const void *b) {
// Implemente a comparação para ordem decrescente
return 0;
}
int main(void) {
int v[] = {3, 1, 4, 1, 5, 9, 2, 6};
int n = sizeof(v) / sizeof(v[0]);
// Chame qsort e imprima
return 0;
}
Saída esperada
9 6 5 4 3 2 1 1
Ver dica
Para ordem decrescente, retorne *(int*)b - *(int*)a. Lembre-se de converter os ponteiros void* para int* antes de desreferenciar.
Mostrar solução
#include <stdio.h>
#include <stdlib.h>
// Comparação para ordem decrescente
int compara_decrescente(const void *a, const void *b) {
int ia = *(const int *)a;
int ib = *(const int *)b;
return (ib > ia) - (ib < ia); // retorna positivo se ib > ia, negativo se ib < ia
}
int main(void) {
int v[] = {3, 1, 4, 1, 5, 9, 2, 6};
int n = sizeof(v) / sizeof(v[0]);
// qsort recebe o array, número de elementos, tamanho de cada elemento e a função de comparação
qsort(v, n, sizeof(int), compara_decrescente);
for (int i = 0; i < n; i++) {
printf("%d ", v[i]);
}
printf("\n");
return 0;
}
Passo a passo
- Incluímos
<stdlib.h>para ter acesso aqsort. - Definimos
compara_decrescenteque recebe doisconst void*e retorna umint. Convertemos paraconst int*e desreferenciamos. - A expressão
(ib > ia) - (ib < ia)retorna 1 seib > ia, -1 seib < iae 0 se iguais. Isso inverte a ordem em relação ao critério crescente. - No
main, chamamosqsort(v, n, sizeof(int), compara_decrescente). Oqsortusará nossa função para comparar pares de elementos. - Imprimimos o array com um laço
for.
Por que funciona
qsort é uma função genérica de ordenação que não sabe o tipo dos dados. Ela recebe um ponteiro para função de comparação que define a relação de ordem. Nosso callback retorna positivo quando o primeiro argumento deve vir depois do segundo, implementando a ordem decrescente.
Erros comuns
- Esquecer de converter
void*paraint*antes de desreferenciar:*(const int*)aé obrigatório;*anão compila. - Retornar
ia - ibpode causar overflow se os valores forem muito grandes. A forma segura é(ia > ib) - (ia < ib). - Passar a função de comparação sem o
&ou com parênteses extras:qsort(..., compara_decrescente)está correto;qsort(..., compara_decrescente())chama a função e passa o resultado (erro).
Outra forma de resolver
Usar qsort_r (extensão) ou uma função de comparação que use uma variável global para definir a ordem. Mas a solução com callback é mais limpa e reutilizável.
Saída esperada
9 6 5 4 3 2 1 1