Menu
Coddy logo textTech

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 na programação é trocar dois valores. Normalmente, você escreveria uma função swap 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 duas variáveis quaisquer.

A principal ideia é que a troca consiste apenas em 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. Internamente, usamos um buffer temporário e memcpy de <string.h> para reorganizar 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 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 de C implementa funções genéricas como qsort e bsearch.

challenge icon

Desafio

Fácil

Vamos criar um utilitário genérico de troca que possa trocar os valores de quaisquer duas variáveis, independentemente do tipo delas: usando o poder dos ponteiros void* e de 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 protetores de inclusão!
  • swap.c: implemente a função generic_swap. Use um buffer temporário e memcpy para mover bytes entre as duas localizações de memória. Lembre-se do padrão de troca em três etapas: copie o primeiro valor para o temporário, copie o segundo para o primeiro e copie o temporário para o segundo.
  • main.c: demonstre o funcionamento da sua troca genérica com diferentes tipos de dados. Leia um indicador de tipo (i para inteiros, d para números de ponto flutuante do tipo double), 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 double
  2. O primeiro valor
  3. O segundo valor

Após a troca, imprima os dois 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 dessa abordagem é que sua função generic_swap não faz ideia de quais tipos 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 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 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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online