Menu
Coddy logo textTech

Troca Genérica

Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 51 de 61.

Uma operação comum na programação é a troca de dois valores. Normalmente, você escreveria uma função de troca separada para cada tipo — uma para int, outra para double, e assim por diante. Mas com void* e memcpy, podemos escrever uma única função que troca quaisquer duas variáveis.

A percepção fundamental é que a troca (swapping) consiste apenas em mover bytes de um lugar para outro. Se você souber o tamanho dos dados, poderá copiar os bytes sem conhecer o tipo real. A assinatura da função se parece com isto:

void generic_swap(void* a, void* b, size_t size);

O parâmetro size informa à função quantos bytes mover. Internamente, usamos um buffer temporário e memcpy de <string.h> para embaralhar os bytes:

void generic_swap(void* a, void* b, size_t size) {
    char temp[size];      // buffer temporário
    memcpy(temp, a, size);  // temp = a
    memcpy(a, b, size);     // a = b
    memcpy(b, temp, size);  // b = temp
}

Agora esta única função funciona para qualquer tipo:

int x = 5, y = 10;
generic_swap(&x, &y, sizeof(int));
// x agora é 10, y agora é 5
double p = 3.14, q = 2.71;
generic_swap(&p, &q, sizeof(double));
// p agora é 2.71, q agora é 3.14

Este padrão — usando void* com size_t — é como a biblioteca padrão do C implementa funções genéricas como qsort e bsearch.

challenge icon

Desafio

Fácil

Vamos construir um utilitário de troca genérico que pode permutar os valores de quaisquer duas variáveis, independentemente de seu tipo — usando o poder dos ponteiros void* e do memcpy.

Você organizará seu código em três arquivos:

  • swap.h: Declare sua função generic_swap que recebe dois ponteiros void* e um parâmetro size_t indicando o tamanho dos dados a serem trocados. Não se esqueça dos include guards!
  • swap.c: Implemente a função generic_swap. Use um buffer temporário e memcpy para mover bytes entre os dois locais de memória. Lembre-se do padrão de troca de três etapas: copiar o primeiro valor para o temporário, copiar o segundo para o primeiro, copiar o temporário para o segundo.
  • main.c: Demonstre sua troca genérica funcionando com diferentes tipos de dados. Leia um indicador de tipo (i para inteiros, d para doubles) seguido por dois valores. Crie duas variáveis do tipo apropriado, troque-as usando sua função generic_swap e, em seguida, imprima ambos os valores após a troca.

Seu programa receberá três entradas:

  1. Um indicador de tipo: i para inteiro ou d para double
  2. O primeiro valor
  3. O segundo valor

Após a troca, imprima ambos os valores em linhas separadas. Para doubles, use 2 casas decimais.

Exemplo de saída quando as entradas são i, 5 e 10:

10
5

Exemplo de saída quando as entradas são d, 3.14 e 2.71:

2.71
3.14

Exemplo de saída quando as entradas são i, -7 e 42:

42
-7

Exemplo de saída quando as entradas são d, 99.99 e 0.01:

0.01
99.99

A beleza desta abordagem é que sua função generic_swap não tem ideia de quais tipos ela está trocando — ela apenas move bytes. A mesma função funciona para inteiros, doubles, structs ou qualquer outro tipo de dado. Você precisará incluir <string.h> para memcpy e <stddef.h> ou <stdlib.h> para size_t.

Folha de consulta

Uma função swap genérica usa ponteiros void* e memcpy para trocar valores de qualquer tipo, movendo bytes sem conhecer o tipo real.

Assinatura da função:

void generic_swap(void* a, void* b, size_t size);

Implementação usando um buffer temporário e memcpy:

void generic_swap(void* a, void* b, size_t size) {
    char temp[size];      // buffer temporário
    memcpy(temp, a, size);  // temp = a
    memcpy(a, b, size);     // a = b
    memcpy(b, temp, size);  // b = temp
}

Uso com diferentes tipos:

int x = 5, y = 10;
generic_swap(&x, &y, sizeof(int));
// x agora é 10, y agora é 5

double p = 3.14, q = 2.71;
generic_swap(&p, &q, sizeof(double));
// p agora é 2.71, q agora é 3.14

Cabeçalhos necessários: <string.h> para memcpy e <stddef.h> ou <stdlib.h> para size_t.

Experimente você mesmo

#include <stdio.h>
#include "swap.h"

int main() {
    char type;
    scanf("%c", &type);
    
    if (type == 'i') {
        int a, b;
        scanf("%d", &a);
        scanf("%d", &b);
        
        // TODO: Chame generic_swap para trocar a e b
        // Dica: Use &a, &b e sizeof(int)
        
        printf("%d\n", a);
        printf("%d\n", b);
    } else if (type == 'd') {
        double a, b;
        scanf("%lf", &a);
        scanf("%lf", &b);
        
        // TODO: Chame generic_swap para trocar a e b
        // Dica: Use &a, &b e sizeof(double)
        
        printf("%.2f\n", a);
        printf("%.2f\n", b);
    }
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming