Clases en C con struct: ejercicio resuelto de diseño modular

Clases en C con struct: ejercicio resuelto paso a paso

Si buscas clases en C con struct, esta guía te muestra un enfoque práctico para modelar objetos sin POO nativa: struct + funciones + archivos separados.

La idea es aproximar encapsulación y responsabilidades claras en C puro.

Enunciado

Diseña un módulo Cuenta que:

  1. defina una entidad con titular y saldo,
  2. exponga funciones para crear, depositar, retirar y mostrar estado,
  3. separe interfaz (cuenta.h) e implementación (cuenta.c),
  4. use un main.c para probar el flujo completo.

Solución en C

cuenta.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#ifndef CUENTA_H
#define CUENTA_H

typedef struct {
    char titular[64];
    double saldo;
} Cuenta;

Cuenta cuenta_crear(const char *titular, double saldo_inicial);
int cuenta_depositar(Cuenta *c, double importe);
int cuenta_retirar(Cuenta *c, double importe);
void cuenta_imprimir(const Cuenta *c);

#endif

cuenta.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "cuenta.h"
#include <stdio.h>
#include <string.h>

Cuenta cuenta_crear(const char *titular, double saldo_inicial) {
    Cuenta c;
    strncpy(c.titular, titular, sizeof(c.titular) - 1);
    c.titular[sizeof(c.titular) - 1] = '\0';
    c.saldo = (saldo_inicial >= 0.0) ? saldo_inicial : 0.0;
    return c;
}

int cuenta_depositar(Cuenta *c, double importe) {
    if (!c || importe <= 0.0) return 0;
    c->saldo += importe;
    return 1;
}

int cuenta_retirar(Cuenta *c, double importe) {
    if (!c || importe <= 0.0 || importe > c->saldo) return 0;
    c->saldo -= importe;
    return 1;
}

void cuenta_imprimir(const Cuenta *c) {
    if (!c) return;
    printf("Titular: %s | Saldo: %.2f\n", c->titular, c->saldo);
}

main.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "cuenta.h"
#include <stdio.h>

int main(void) {
    Cuenta c = cuenta_crear("Rodrigo", 1000.0);
    cuenta_imprimir(&c);

    cuenta_depositar(&c, 250.0);
    cuenta_retirar(&c, 400.0);
    cuenta_imprimir(&c);

    if (!cuenta_retirar(&c, 2000.0)) {
        printf("Retirada rechazada por saldo insuficiente.\n");
    }

    return 0;
}

Compilación:

1
gcc -Wall -Wextra -std=c11 main.c cuenta.c -o cuenta_demo

Resultado esperado

1
2
3
Titular: Rodrigo | Saldo: 1000.00
Titular: Rodrigo | Saldo: 850.00
Retirada rechazada por saldo insuficiente.

Errores frecuentes

  • Exponer toda la lógica en main.c y perder modularidad.
  • No validar punteros ni importes antes de operar.
  • Copiar cadenas sin límite y arriesgar desbordamientos.
  • Pensar que esto es POO completa: en C no hay herencia ni métodos nativos.

Aplicación práctica

Este patrón te sirve para:

  • diseñar módulos mantenibles en C,
  • separar API pública y detalles internos,
  • preparar código base para proyectos más grandes.

Es un enfoque útil cuando quieres estructura de “objeto” sin salir del lenguaje C.

Siguiente ejercicio recomendado

Práctica guiada y siguiente paso

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Se puede hacer orientación a objetos real en C?

No de forma nativa. Puedes simular parte del diseño con struct, funciones y punteros, pero sin herencia ni polimorfismo integrado.

¿Por qué separar .h y .c en este ejercicio?

Porque mejora mantenimiento, facilita reutilización y deja clara la interfaz pública del módulo.

¿Esto es útil para entrevistas o solo para proyectos grandes?

Para ambos casos. En entrevistas demuestra diseño limpio, y en proyectos reales evita código monolítico difícil de mantener.