Menu
Coddy logo textTech

Swap genérico

Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 51 de 61.

Una operación común en programación es intercambiar dos valores. Normalmente, escribirías una función de intercambio independiente para cada tipo: una para int, otra para double, y así sucesivamente. Pero con void* y memcpy, podemos escribir una sola función que intercambie dos variables cualesquiera.

La idea clave es que intercambiar consiste simplemente en mover bytes. Si conoces el tamaño de los datos, puedes copiar bytes sin conocer el tipo real. La signatura de la función tiene este aspecto:

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

El parámetro size indica a la función cuántos bytes mover. Dentro, usamos un búfer temporal y memcpy de <string.h> para intercambiar los bytes:

void generic_swap(void* a, void* b, size_t size) {
    char temp[size];      // búfer temporal
    memcpy(temp, a, size);  // temp = a
    memcpy(a, b, size);     // a = b
    memcpy(b, temp, size);  // b = temp
}

Ahora esta única función funciona para cualquier tipo:

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

Este patrón, que utiliza void* con size_t, es la forma en que la biblioteca estándar de C implementa funciones genéricas como qsort y bsearch.

challenge icon

Desafío

Fácil

Construyamos una utilidad de intercambio genérica que pueda intercambiar los valores de dos variables cualesquiera, independientemente de su tipo: usando el poder de los punteros void* y memcpy.

Organizarás tu código en tres archivos:

  • swap.h: Declara tu función generic_swap, que recibe dos punteros void* y un parámetro size_t que indica el tamaño de los datos que se intercambiarán. ¡No olvides las protecciones de inclusión!
  • swap.c: Implementa la función generic_swap. Usa un búfer temporal y memcpy para mover bytes entre las dos ubicaciones de memoria. Recuerda el patrón de intercambio de tres pasos: copiar el primer valor al temporal, copiar el segundo al primero y copiar el temporal al segundo.
  • main.c: Demuestra que tu intercambio genérico funciona con distintos tipos de datos. Lee un indicador de tipo (i para enteros, d para números de doble precisión) seguido de dos valores. Crea dos variables del tipo apropiado, intercámbialas usando tu función generic_swap y, después, imprime ambos valores tras el intercambio.

Tu programa recibirá tres entradas:

  1. Un indicador de tipo: i para entero o d para número de doble precisión
  2. El primer valor
  3. El segundo valor

Después del intercambio, imprime ambos valores en líneas separadas. Para los números de doble precisión, usa 2 decimales.

Salida de ejemplo cuando las entradas son i, 5 y 10:

10
5

Salida de ejemplo cuando las entradas son d, 3.14 y 2.71:

2.71
3.14

Salida de ejemplo cuando las entradas son i, -7 y 42:

42
-7

Salida de ejemplo cuando las entradas son d, 99.99 y 0.01:

0.01
99.99

La belleza de este enfoque es que tu función generic_swap no tiene idea de qué tipos está intercambiando. Simplemente mueve bytes. La misma función funciona con enteros, números de doble precisión, estructuras o cualquier otro tipo de datos. Tendrás que incluir <string.h> para memcpy y <stddef.h> o <stdlib.h> para size_t.

Pruébalo tú mismo

#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: Llama a generic_swap para intercambiar a y b
        // Hint: Usa &a, &b y sizeof(int)
        
        printf("%d\n", a);
        printf("%d\n", b);
    } else if (type == 'd') {
        double a, b;
        scanf("%lf", &a);
        scanf("%lf", &b);
        
        // TODO: Llama a generic_swap para intercambiar a y b
        // Hint: Usa &a, &b y sizeof(double)
        
        printf("%.2f\n", a);
        printf("%.2f\n", b);
    }
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C online