Menu
Coddy logo textTech

Swap genérico

Parte de la sección Object Oriented Programming 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 separada para cada tipo — una para int, otra para double, y así sucesivamente. Pero con void* and memcpy, podemos escribir una única función que intercambie dos variables cualesquiera.

La idea clave es que el intercambio consiste simplemente en mover bytes. Si conoces el tamaño de los datos, puedes copiar bytes sin conocer el tipo real. La firma de la función se ve así:

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

El parámetro size le indica a la función cuántos bytes mover. En el interior, utilizamos un búfer temporal y memcpy de <string.h> para reorganizar 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 —usando void* con size_t— es como la biblioteca estándar de C implementa funciones genéricas como qsort y bsearch.

challenge icon

Desafío

Fácil

Vamos a construir una utilidad de intercambio genérica que pueda intercambiar los valores de cualquier par de variables, independientemente de su tipo — utilizando 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 a intercambiar. ¡No olvides los include guards!
  • swap.c: Implementa la función generic_swap. Utiliza 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 tu intercambio genérico funcionando con diferentes tipos de datos. Lee un indicador de tipo ('i' para enteros, 'd' para doubles) seguido de dos valores. Crea dos variables del tipo apropiado, intercámbialas usando tu función generic_swap, y luego imprime ambos valores después del intercambio.

Tu programa recibirá tres entradas:

  1. Un indicador de tipo: 'i' para entero o 'd' para double
  2. El primer valor
  3. El segundo valor

Después del intercambio, imprime ambos valores en líneas separadas. Para los doubles, utiliza 2 decimales.

Ejemplo de salida cuando las entradas son 'i', 5, y 10:

10
5

Ejemplo de salida cuando las entradas son 'd', 3.14, y 2.71:

2.71
3.14

Ejemplo de salida cuando las entradas son 'i', -7, y 42:

42
-7

Ejemplo de salida 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 sirve para enteros, doubles, structs o cualquier otro tipo de dato. Necesitarás incluir <string.h> para memcpy y <stddef.h> o <stdlib.h> para size_t.

Hoja de referencia

Una función de intercambio genérica utiliza punteros void* y memcpy para intercambiar valores de cualquier tipo moviendo bytes sin conocer el tipo real.

Firma de la función:

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

Implementación utilizando un búfer temporal y memcpy:

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
}

Uso con diferentes tipos:

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 ahora es 2.71, q ahora es 3.14

Cabeceras requeridas: <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: Llamar a generic_swap para intercambiar a y b
        // Pista: 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: Llamar a generic_swap para intercambiar a y b
        // Pista: 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 Object Oriented Programming