Menu
CoddyTech

Troca genérica

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 51 de 61.

Uma operação comum em programação é trocar 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 principal percepção é que trocar significa apenas mover bytes. Se você souber o tamanho dos dados, poderá copiar bytes sem conhecer o tipo real. A assinatura da função é assim:

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

O parâmetro size informa à função quantos bytes mover. Dentro dela, usamos um buffer temporário e memcpy de <string.h> para trocar 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 essa única função funciona com 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

Esse padrão, que usa void* com size_t, é como a biblioteca padrão de C implementa funções genéricas como qsort e bsearch.

challenge icon

Desafio

Fácil

Vamos criar uma utilidade genérica de troca que pode trocar os valores de quaisquer duas variáveis, independentemente do tipo delas: usando o poder dos ponteiros void* e de memcpy.

Você vai 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 que indica o tamanho dos dados a serem trocados. Não se esqueça dos protetores de inclusão!
  • 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 em três etapas: copie o primeiro valor para temp, copie o segundo para o primeiro e copie temp 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 números de ponto flutuante) seguido por dois valores. Crie duas variáveis do tipo apropriado, troque-as usando sua função generic_swap e, em seguida, imprima os dois valores após a troca.

Seu programa receberá três entradas:

  1. Um indicador de tipo: i para inteiro ou d para número de ponto flutuante
  2. O primeiro valor
  3. O segundo valor

Após a troca, imprima os dois valores em linhas separadas. Para números de ponto flutuante, 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 vantagem dessa abordagem é que sua função generic_swap não sabe quais tipos está trocando. Ela apenas move bytes. A mesma função funciona com inteiros, números de ponto flutuante, structs ou qualquer outro tipo de dado. Você precisará incluir <string.h> para usar memcpy e <stddef.h> ou <stdlib.h> para usar 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 os valores de 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 os valores de 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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online