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 usar qsort.
  • Definir uma função de comparação que retorne valor positivo se o primeiro elemento for menor que o segundo (para ordem decrescente).
  • Chamar qsort passando 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

  1. Incluímos <stdlib.h> para ter acesso a qsort.
  2. Definimos compara_decrescente que recebe dois const void* e retorna um int. Convertemos para const int* e desreferenciamos.
  3. A expressão (ib > ia) - (ib < ia) retorna 1 se ib > ia, -1 se ib < ia e 0 se iguais. Isso inverte a ordem em relação ao critério crescente.
  4. No main, chamamos qsort(v, n, sizeof(int), compara_decrescente). O qsort usará nossa função para comparar pares de elementos.
  5. 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* para int* antes de desreferenciar: *(const int*)a é obrigatório; *a não compila.
  • Retornar ia - ib pode 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