Prerrequisitos y Entorno de Ejecución Requerido¶
Para compilar y verificar las soluciones de este módulo bajo el estándar C11 estricto de cátedra, se requiere:
Compilador C11: GCC 9+ o Clang 11+ configurado con flags
-Wall -Wextra -Werror -pedantic -std=c11.Entorno POSIX: Linux o WSL con utilidades estándar y verificación estática.
Herramientas de Verificación: Valgrind (memcheck) y AddressSanitizer (
-fsanitize=address,undefined) para garantizar la ausencia de lecturas fuera de límites en mapeos de variantes.Conocimientos Previos: Sintaxis de
enum, constantes discretas con nombre, dispatched conswitch-caseexhaustivo y conversión de estados a texto (stringification).
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Analizar el valor de tipos enumerados frente a enteros mágicos y optimización de representación de memoria.
Nivel 3 (Aplicación): Implementar máquinas de estado discretas, validadores de opciones y funciones de traducción bidireccional en C11.
Nivel 4 (Análisis): Evaluar uniones etiquetadas (tagged unions) y composición heterogénea estructurada con seguridad de tipos.
Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Capítulos de Apunte Correspondientes¶
Días de la Semana¶
Crear un tipo enum para representar los días de la semana y funciones básicas
para trabajar con ellos:
1 2 3 4 5 6 7 8 9 10enum dia_semana { LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO };
Ejercicio 2.11.01 - Operaciones con Días de la Semana ⭐⭐☆☆☆¶
```c #include <stdio.h> #include <stdbool.h> #include <string.h> #include <assert.h> enum dia_semana { LUNES = 0, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO }; enum dia_semana dia_siguiente(enum dia_semana dia_actual) { if (dia_actual < LUNES || dia_actual > DOMINGO) { return LUNES; } return (enum dia_semana)((dia_actual + 1) % 7); } bool es_dia_laboral(enum dia_semana dia) { switch (dia) { case LUNES: case MARTES: case MIERCOLES: case JUEVES: case VIERNES: return true; case SABADO: case DOMINGO: default: return false; } } const char *nombre_dia(enum dia_semana dia) { switch (dia) { case LUNES: return "Lunes"; case MARTES: return "Martes"; case MIERCOLES: return "Miercoles"; case JUEVES: return "Jueves"; case VIERNES: return "Viernes"; case SABADO: return "Sabado"; case DOMINGO: return "Domingo"; default: return "Desconocido"; } } int main(void) { assert(dia_siguiente(LUNES) == MARTES); assert(dia_siguiente(SABADO) == DOMINGO); assert(dia_siguiente(DOMINGO) == LUNES); assert(dia_siguiente((enum dia_semana)99) == LUNES); assert(es_dia_laboral(LUNES) == true); assert(es_dia_laboral(VIERNES) == true); assert(es_dia_laboral(SABADO) == false); assert(es_dia_laboral(DOMINGO) == false); assert(es_dia_laboral((enum dia_semana)99) == false); assert(strcmp(nombre_dia(LUNES), "Lunes") == 0); assert(strcmp(nombre_dia(DOMINGO), "Domingo") == 0); assert(strcmp(nombre_dia((enum dia_semana)99), "Desconocido") == 0); return 0; } ```
## Estados de Conexión
Modelar los estados de una conexión de red usando enumeraciones.
```{code-block} c
:linenos:
enum estado_red
{
DESCONECTADO,
CONECTANDO,
CONECTADO,
DESCONECTANDO,
ERROR_TIMEOUT,
ERROR_AUTH
};
```
<!-- {code-block} c -->
(ej_b2_c11_04)=
### Ejercicio 2.11.04 - Máquina de Estados de Conexión de Red ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b2_c11_04_maquina_estados
Implementá la función de transición para una máquina de estados determinística de conexión de red:
```c
enum estado_red procesar_evento(enum estado_red estado, enum evento_red evento);
```
**Reglas de transición:**
1. Desde `DESCONECTADO`, `EVENTO_CONECTAR` transiciona a `CONECTANDO`.
2. Desde `CONECTANDO`, `EVENTO_OK` transiciona a `CONECTADO`; `EVENTO_TIMEOUT` a `ERROR_TIMEOUT`; `EVENTO_ERROR` a `ERROR_AUTH`.
3. Desde `CONECTADO`, `EVENTO_DESCONECTAR` transiciona a `DESCONECTANDO`.
4. Desde `DESCONECTANDO`, cualquier evento transiciona a `DESCONECTADO`.
5. Cualquier evento no contemplado para el estado actual mantiene el estado inalterado.
**Tabla de Vectores de Prueba:**
| Estado Inicial | Evento Recibido | Estado Resultante | Justificación |
| :--- | :--- | :--- | :--- |
| `DESCONECTADO` | `EVENTO_CONECTAR` | `CONECTANDO` | Inicio de negociación |
| `CONECTANDO` | `EVENTO_OK` | `CONECTADO` | Conexión establecida |
| `CONECTANDO` | `EVENTO_TIMEOUT` | `ERROR_TIMEOUT` | Falla por tiempo |
| `CONECTADO` | `EVENTO_DESCONECTAR` | `DESCONECTANDO` | Cierre solicitado |
| `CONECTADO` | `EVENTO_CONECTAR` | `CONECTADO` | Evento inválido ignorado |
::::{solution}
```c
#include <stdio.h>
#include <assert.h>
enum estado_red {
DESCONECTADO = 0,
CONECTANDO,
CONECTADO,
DESCONECTANDO,
ERROR_TIMEOUT,
ERROR_AUTH
};
enum evento_red {
EVENTO_CONECTAR = 0,
EVENTO_OK,
EVENTO_DESCONECTAR,
EVENTO_TIMEOUT,
EVENTO_ERROR
};
enum estado_red procesar_evento(enum estado_red estado, enum evento_red evento) {
switch (estado) {
case DESCONECTADO:
if (evento == EVENTO_CONECTAR) {
return CONECTANDO;
}
break;
case CONECTANDO:
if (evento == EVENTO_OK) {
return CONECTADO;
}
if (evento == EVENTO_TIMEOUT) {
return ERROR_TIMEOUT;
}
if (evento == EVENTO_ERROR) {
return ERROR_AUTH;
}
break;
case CONECTADO:
if (evento == EVENTO_DESCONECTAR) {
return DESCONECTANDO;
}
break;
case DESCONECTANDO:
return DESCONECTADO;
case ERROR_TIMEOUT:
case ERROR_AUTH:
if (evento == EVENTO_CONECTAR) {
return CONECTANDO;
}
if (evento == EVENTO_DESCONECTAR) {
return DESCONECTADO;
}
break;
}
return estado;
}
int main(void) {
assert(procesar_evento(DESCONECTADO, EVENTO_CONECTAR) == CONECTANDO);
assert(procesar_evento(DESCONECTADO, EVENTO_DESCONECTAR) == DESCONECTADO);
assert(procesar_evento(CONECTANDO, EVENTO_OK) == CONECTADO);
assert(procesar_evento(CONECTANDO, EVENTO_TIMEOUT) == ERROR_TIMEOUT);
assert(procesar_evento(CONECTANDO, EVENTO_ERROR) == ERROR_AUTH);
assert(procesar_evento(CONECTADO, EVENTO_DESCONECTAR) == DESCONECTANDO);
assert(procesar_evento(CONECTADO, EVENTO_CONECTAR) == CONECTADO);
assert(procesar_evento(DESCONECTANDO, EVENTO_OK) == DESCONECTADO);
return 0;
}
```
(ej_b2_c11_05)=
### Ejercicio 2.11.05 - Validación de estado ⭐⭐⭐☆☆
Implementar una función que valide si un valor numérico corresponde a un estado
válido de la enumeración. Usar el patrón del valor centinela.
```{code-block} c
:linenos:
enum estado_red
{
DESCONECTADO,
CONECTANDO,
CONECTADO,
DESCONECTANDO,
ERROR_TIMEOUT,
ERROR_AUTH,
_ESTADO_MAX // Valor centinela
};
bool estado_valido(int valor);
```
<!-- {code-block} c -->
## Sistema de Permisos con Flags
Implementar un sistema de permisos usando flags de bits. Este ejercicio
demuestra cómo combinar múltiples opciones en un único valor.
```{code-block} c
:linenos:
enum permisos
{
PERMISO_LECTURA = 1 << 0, // 0x01
PERMISO_ESCRITURA = 1 << 1, // 0x02
PERMISO_EJECUCION = 1 << 2, // 0x04
PERMISO_ELIMINAR = 1 << 3 // 0x08
};
```
<!-- {code-block} c -->
(ej_b2_c11_06)=
### Ejercicio 2.11.06 - Verificación y Manipulación de Permisos con Bits ⭐⭐☆☆☆
:::{exercise}
:label: ej_b2_c11_06_verificar_permiso
Implementá funciones puras para consultar y mutar un conjunto de permisos representados mediante un enum con potencias de dos:
```c
enum permiso {
PERMISO_LECTURA = 1 << 0,
PERMISO_ESCRITURA = 1 << 1,
PERMISO_EJECUCION = 1 << 2,
PERMISO_ELIMINAR = 1 << 3
};
bool permiso_tiene(unsigned int permisos, enum permiso objetivo);
unsigned int permiso_agregar(unsigned int permisos, enum permiso nuevo);
unsigned int permiso_quitar(unsigned int permisos, enum permiso remover);
```
**Tabla de Vectores de Prueba:**
| Caso de Prueba | Permisos Iniciales | Operación | Retorno / Resultado |
| :--- | :--- | :--- | :--- |
| Consulta lectura | `LECTURA \| ESCRITURA` | `permiso_tiene(..., LECTURA)` | `true` |
| Consulta ejecución | `LECTURA \| ESCRITURA` | `permiso_tiene(..., EJECUCION)` | `false` |
| Agregar permiso | `LECTURA` | `permiso_agregar(..., EJECUCION)` | `LECTURA \| EJECUCION` |
| Quitar permiso | `LECTURA \| ESCRITURA` | `permiso_quitar(..., ESCRITURA)` | `LECTURA` |
::::{solution}
```c
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
enum permiso {
PERMISO_LECTURA = 1 << 0,
PERMISO_ESCRITURA = 1 << 1,
PERMISO_EJECUCION = 1 << 2,
PERMISO_ELIMINAR = 1 << 3
};
bool permiso_tiene(unsigned int permisos, enum permiso objetivo) {
return (permisos & (unsigned int)objetivo) == (unsigned int)objetivo;
}
unsigned int permiso_agregar(unsigned int permisos, enum permiso nuevo) {
return permisos | (unsigned int)nuevo;
}
unsigned int permiso_quitar(unsigned int permisos, enum permiso remover) {
return permisos & ~(unsigned int)remover;
}
int main(void) {
unsigned int p = PERMISO_LECTURA | PERMISO_ESCRITURA;
assert(permiso_tiene(p, PERMISO_LECTURA) == true);
assert(permiso_tiene(p, PERMISO_ESCRITURA) == true);
assert(permiso_tiene(p, PERMISO_EJECUCION) == false);
p = permiso_agregar(p, PERMISO_EJECUCION);
assert(permiso_tiene(p, PERMISO_EJECUCION) == true);
p = permiso_quitar(p, PERMISO_ESCRITURA);
assert(permiso_tiene(p, PERMISO_ESCRITURA) == false);
assert(permiso_tiene(p, PERMISO_LECTURA) == true);
return 0;
}
```
(ej_b2_c11_08)=
### Ejercicio 2.11.08 - Listar permisos activos ⭐⭐☆☆☆
Implementar una función que imprima todos los permisos activos en un conjunto de
permisos.
``` c
void mostrar_permisos(unsigned int permisos);
```
<!-- c -->
## Colores RGB con Enum
Definir una enumeración para colores predefinidos y una estructura para
representar colores RGB personalizados.
```{code-block} c
:linenos:
enum color_predefinido
{
COLOR_NEGRO,
COLOR_BLANCO,
COLOR_ROJO,
COLOR_VERDE,
COLOR_AZUL,
COLOR_AMARILLO,
COLOR_MAGENTA,
COLOR_CIAN
};
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
} rgb_t;
```
<!-- {code-block} c -->
(ej_b2_c11_09)=
### Ejercicio 2.11.09 - Conversión de color predefinido a RGB ⭐⭐☆☆☆
Implementar una función que convierta un color predefinido a sus componentes
RGB.
``` c
rgb_t color_a_rgb(enum color_predefinido color);
```
<!-- c -->
**Valores sugeridos:**
- `COLOR_ROJO`: (255, 0, 0)
- `COLOR_VERDE`: (0, 255, 0)
- `COLOR_AZUL`: (0, 0, 255)
- `COLOR_AMARILLO`: (255, 255, 0)
(ej_b2_c11_10)=
### Ejercicio 2.11.10 - Mezcla de colores ⭐⭐☆☆☆
Implementar una función que mezcle dos colores RGB usando promedio aritmético.
``` c
rgb_t mezclar_colores(rgb_t c1, rgb_t c2);
```
<!-- c -->
## Configuración de Dispositivo con Unión Etiquetada
Implementar una unión etiquetada para almacenar diferentes tipos de
configuración de dispositivos.
```{code-block} c
:linenos:
enum tipo_dispositivo
{
DISPOSITIVO_SENSOR_TEMP,
DISPOSITIVO_MOTOR,
DISPOSITIVO_LED
};
typedef struct
{
double temperatura_min;
double temperatura_max;
} config_sensor_t;
typedef struct
{
unsigned int velocidad_rpm;
bool direccion_horaria;
} config_motor_t;
typedef struct
{
unsigned char intensidad;
enum color_predefinido color;
} config_led_t;
typedef struct
{
enum tipo_dispositivo tipo;
union
{
config_sensor_t sensor;
config_motor_t motor;
config_led_t led;
} config;
} dispositivo_t;
```
<!-- {code-block} c -->
(ej_b2_c11_11)=
### Ejercicio 2.11.11 - Configurar dispositivo ⭐⭐☆☆☆
Implementar funciones para configurar cada tipo de dispositivo de forma segura.
``` c
dispositivo_t crear_sensor(double temp_min, double temp_max);
dispositivo_t crear_motor(unsigned int rpm, bool horario);
dispositivo_t crear_led(unsigned char intensidad,
enum color_predefinido color);
```
<!-- c -->
(ej_b2_c11_12)=
### Ejercicio 2.11.12 - Imprimir configuración ⭐⭐☆☆☆
Implementar una función que imprima la configuración de un dispositivo según su
tipo. Este ejercicio demuestra el uso correcto de uniones etiquetadas.
``` c
void imprimir_dispositivo(const dispositivo_t *dispositivo);
```
<!-- c -->
## Códigos de Error
Definir una enumeración exhaustiva para códigos de error de un sistema.
```{code-block} c
:linenos:
enum codigo_error
{
ERROR_NINGUNO = 0,
ERROR_MEMORIA,
ERROR_ARCHIVO_NO_ENCONTRADO,
ERROR_PERMISO_DENEGADO,
ERROR_ARGUMENTO_INVALIDO,
ERROR_TIMEOUT,
ERROR_CONEXION,
ERROR_DESCONOCIDO
};
```
<!-- {code-block} c -->
(ej_b2_c11_13)=
### Ejercicio 2.11.13 - Mensaje de error ⭐⭐☆☆☆
Implementar una función que retorne un mensaje descriptivo para cada código de
error.
``` c
const char *mensaje_error(enum codigo_error error);
```
<!-- c -->
(ej_b2_c11_14)=
### Ejercicio 2.11.14 - Tipo de resultado ⭐⭐⭐☆☆
Implementar un tipo `resultado_t` que encapsule un valor de retorno o un código
de error usando unión etiquetada.
```{code-block} c
:linenos:
typedef struct
{
enum codigo_error error;
union
{
int valor_int;
double valor_double;
void *valor_ptr;
} datos;
} resultado_t;
```
<!-- {code-block} c -->
Implementar funciones auxiliares:
``` c
resultado_t resultado_ok_int(int valor);
resultado_t resultado_error(enum codigo_error error);
bool resultado_es_error(const resultado_t *resultado);
```
<!-- c -->
## Estados de Reproducción Multimedia
Modelar un reproductor multimedia con estados y modos de reproducción.
```{code-block} c
:linenos:
enum estado_reproductor
{
ESTADO_DETENIDO,
ESTADO_REPRODUCIENDO,
ESTADO_PAUSADO,
ESTADO_AVANZANDO,
ESTADO_RETROCEDIENDO
};
enum modo_reproduccion
{
MODO_NORMAL,
MODO_REPETIR_UNO,
MODO_REPETIR_TODOS,
MODO_ALEATORIO
};
```
<!-- {code-block} c -->
(ej_b2_c11_15)=
### Ejercicio 2.11.15 - Controlador de reproducción ⭐⭐☆☆☆
Implementar una estructura que encapsule el estado completo del reproductor.
```{code-block} c
:linenos:
typedef struct
{
enum estado_reproductor estado;
enum modo_reproduccion modo;
unsigned int pista_actual;
unsigned int total_pistas;
} reproductor_t;
```
<!-- {code-block} c -->
(ej_b2_c11_16)=
### Ejercicio 2.11.16 - Comandos de control ⭐⭐☆☆☆
Implementar funciones para controlar el reproductor.
``` c
void reproducir(reproductor_t *rep);
void pausar(reproductor_t *rep);
void detener(reproductor_t *rep);
void siguiente_pista(reproductor_t *rep);
void anterior_pista(reproductor_t *rep);
```
<!-- c -->
Las funciones deben respetar el estado actual y el modo de reproducción.
## Prioridades y Niveles de Log
Implementar un sistema de logging con niveles de prioridad.
```{code-block} c
:linenos:
enum nivel_log
{
LOG_DEBUG = 0,
LOG_INFO,
LOG_WARNING,
LOG_ERROR,
LOG_FATAL
};
```
<!-- {code-block} c -->
(ej_b2_c11_17)=
### Ejercicio 2.11.17 - Filtrado de logs ⭐⭐☆☆☆
Implementar una función que determine si un mensaje debe ser registrado según el
nivel mínimo configurado.
``` c
bool debe_registrar(enum nivel_log nivel_mensaje, enum nivel_log nivel_minimo);
```
<!-- c -->
(ej_b2_c11_18)=
### Ejercicio 2.11.18 - Formateo de mensaje de log ⭐⭐☆☆☆
Implementar una función que formatee un mensaje de log incluyendo el nivel como
prefijo.
``` c
void log_mensaje(enum nivel_log nivel, const char *mensaje);
```
<!-- c -->
Ejemplo de salida: `[ERROR] Archivo no encontrado`
## Protocolo de Comunicación
Diseñar estructuras para un protocolo simple de comunicación usando campos de
bits.
```{code-block} c
:linenos:
enum tipo_mensaje
{
MSG_DATOS = 0,
MSG_ACK = 1,
MSG_NACK = 2,
MSG_RESET = 3
};
typedef struct
{
unsigned int tipo : 2; // 2 bits para tipo (0-3)
unsigned int prioridad : 2; // 2 bits para prioridad (0-3)
unsigned int secuencia : 4; // 4 bits para número de secuencia (0-15)
} cabecera_mensaje_t;
```
<!-- {code-block} c -->
(ej_b2_c11_19)=
### Ejercicio 2.11.19 - Crear y decodificar cabecera ⭐⭐☆☆☆
Implementar funciones para construir y extraer información de la cabecera.
``` c
cabecera_mensaje_t crear_cabecera(enum tipo_mensaje tipo,
unsigned int prioridad,
unsigned int secuencia);
void imprimir_cabecera(cabecera_mensaje_t cabecera);
```
<!-- c -->
(ej_b2_c11_20)=
### Ejercicio 2.11.20 - Validación de cabecera ⭐⭐☆☆☆
Implementar una función que valide que los valores de una cabecera están dentro
de los rangos permitidos.
``` c
bool cabecera_valida(cabecera_mensaje_t cabecera);
```
<!-- c -->
## Opciones de Compilación con Flags
Modelar opciones de compilación como flags combinables.
```{code-block} c
:linenos:
enum opcion_compilacion
{
OPT_NINGUNA = 0,
OPT_OPTIMIZAR = 1 << 0, // -O
OPT_DEBUG = 1 << 1, // -g
OPT_WARNINGS = 1 << 2, // -Wall
OPT_WARNINGS_EXTRA = 1 << 3, // -Wextra
OPT_PEDANTIC = 1 << 4 // -pedantic
};
```
<!-- {code-block} c -->
(ej_b2_c11_21)=
### Ejercicio 2.11.21 - Generar línea de comandos ⭐⭐☆☆☆
Implementar una función que genere una cadena con las opciones de compilación
correspondientes a los flags activos.
``` c
void generar_comando_compilacion(unsigned int opciones, char *buffer,
size_t tam);
```
<!-- c -->
Ejemplo: Si `opciones` tiene `OPT_DEBUG | OPT_WARNINGS`, el buffer debe contener
`"-g -Wall"`.
(ej_b2_c11_22)=
### Ejercicio 2.11.22 - Detectar conflictos ⭐⭐☆☆☆
Implementar una función que detecte combinaciones incompatibles de opciones.
``` c
bool opciones_compatibles(unsigned int opciones);
```
<!-- c -->
Por ejemplo, `OPT_OPTIMIZAR` y `OPT_DEBUG` podrían considerarse incompatibles en
ciertos contextos.
## Menú de Aplicación
Implementar un sistema de menú interactivo usando enumeraciones.
```{code-block} c
:linenos:
enum opcion_menu
{
MENU_NUEVO = 1,
MENU_ABRIR,
MENU_GUARDAR,
MENU_CERRAR,
MENU_SALIR,
MENU_INVALIDO = -1
};
```
<!-- {code-block} c -->
(ej_b2_c11_23)=
### Ejercicio 2.11.23 - Parser de opción ⭐⭐☆☆☆
Implementar una función que convierta la entrada del usuario en una opción del
menú.
``` c
enum opcion_menu parsear_opcion(int entrada);
```
<!-- c -->
(ej_b2_c11_24)=
### Ejercicio 2.11.24 - Ejecutor de menú ⭐⭐☆☆☆
Implementar una función que ejecute la acción correspondiente a cada opción del
menú.
``` c
void ejecutar_opcion(enum opcion_menu opcion);
```
<!-- c -->
(ej_b2_c11_25)=
### Ejercicio 2.11.25 - Menú interactivo completo ⭐⭐☆☆☆
Implementar un lazo principal que muestre el menú, lea la opción del usuario y
ejecute la acción hasta que el usuario seleccione `MENU_SALIR`.
## Tipos de Figuras Geométricas con Unión
Combinar enumeraciones, estructuras y uniones para representar diferentes
figuras geométricas.
```{code-block} c
:linenos:
enum tipo_figura
{
FIGURA_CIRCULO,
FIGURA_RECTANGULO,
FIGURA_TRIANGULO
};
typedef struct
{
double radio;
} circulo_t;
typedef struct
{
double base;
double altura;
} rectangulo_t;
typedef struct
{
double lado_a;
double lado_b;
double lado_c;
} triangulo_t;
typedef struct
{
enum tipo_figura tipo;
union
{
circulo_t circulo;
rectangulo_t rectangulo;
triangulo_t triangulo;
} datos;
} figura_t;
```
<!-- {code-block} c -->
(ej_b2_c11_26)=
### Ejercicio 2.11.26 - Cálculo de área ⭐⭐☆☆☆
Implementar una función que calcule el área de cualquier figura usando su tipo y
datos.
``` c
double calcular_area(const figura_t *figura);
```
<!-- c -->
**Fórmulas:**
- Círculo: $A = \pi r^2$
- Rectángulo: $A = base \times altura$
- Triángulo (Fórmula de Herón):
- $s = \frac{a+b+c}{2}$
- $A = \sqrt{s(s-a)(s-b)(s-c)}$
(ej_b2_c11_27)=
### Ejercicio 2.11.27 - Constructores de figuras ⭐⭐⭐☆☆
Implementar funciones para crear cada tipo de figura de forma segura.
``` c
figura_t crear_circulo(double radio);
figura_t crear_rectangulo(double base, double altura);
figura_t crear_triangulo(double a, double b, double c);
```
<!-- c -->
## Conversión entre Enums y Strings
(ej_b2_c11_28)=
### Ejercicio 2.11.28 - Tabla de conversión ⭐⭐☆☆☆
Implementar un sistema genérico para convertir entre valores enum y strings
usando tablas de conversión.
```{code-block} c
:linenos:
typedef struct
{
int valor;
const char *nombre;
} enum_string_t;
// Ejemplo de uso con días de la semana
const enum_string_t tabla_dias[] = {
{LUNES, "Lunes"},
{MARTES, "Martes"},
{MIERCOLES, "Miércoles"},
// ...
};
```
<!-- {code-block} c -->
(ej_b2_c11_29)=
### Ejercicio 2.11.29 - Funciones de conversión genéricas ⭐⭐☆☆☆
Implementar funciones genéricas que usen la tabla para realizar conversiones.
``` c
const char *enum_a_string(int valor, const enum_string_t *tabla, size_t tam);
int string_a_enum(const char *nombre, const enum_string_t *tabla, size_t tam,
int valor_defecto);
```
<!-- c -->
## Estado de Juego
Modelar el estado de un juego simple usando múltiples enumeraciones.
```{code-block} c
:linenos:
enum estado_juego
{
JUEGO_MENU,
JUEGO_JUGANDO,
JUEGO_PAUSADO,
JUEGO_GAME_OVER,
JUEGO_VICTORIA
};
enum dificultad
{
DIFICULTAD_FACIL,
DIFICULTAD_NORMAL,
DIFICULTAD_DIFICIL,
DIFICULTAD_EXPERTO
};
typedef struct
{
enum estado_juego estado;
enum dificultad dificultad;
unsigned int puntuacion;
unsigned int nivel;
unsigned int vidas;
} juego_t;
```
<!-- {code-block} c -->
(ej_b2_c11_30)=
### Ejercicio 2.11.30 - Inicializar juego ⭐☆☆☆☆
Implementar una función que inicialice un juego nuevo con la dificultad
especificada.
``` c
juego_t inicializar_juego(enum dificultad dif);
```
<!-- c -->
La dificultad debe afectar el número inicial de vidas y otros parámetros.
(ej_b2_c11_31)=
### Ejercicio 2.11.31 - Gestión de estado ⭐⭐⭐☆☆
Implementar funciones para transiciones de estado comunes.
``` c
void pausar_juego(juego_t *juego);
void reanudar_juego(juego_t *juego);
void perder_vida(juego_t *juego);
void ganar_nivel(juego_t *juego);
```
<!-- c -->
## Análisis de Tráfico con Enums Aninados
Modelar un sistema de análisis de tráfico de red con múltiples niveles de
clasificación.
```{code-block} c
:linenos:
enum protocolo
{
PROTOCOLO_TCP,
PROTOCOLO_UDP,
PROTOCOLO_ICMP,
PROTOCOLO_OTRO
};
enum tipo_trafico
{
TRAFICO_NORMAL,
TRAFICO_SOSPECHOSO,
TRAFICO_MALICIOSO
};
typedef struct
{
enum protocolo proto;
enum tipo_trafico tipo;
unsigned int puerto_origen;
unsigned int puerto_destino;
size_t bytes_transferidos;
} paquete_red_t;
```
<!-- {code-block} c -->
(ej_b2_c11_32)=
### Ejercicio 2.11.32 - Clasificador de tráfico ⭐⭐☆☆☆
Implementar una función que clasifique un paquete basándose en reglas
heurísticas.
``` c
enum tipo_trafico clasificar_paquete(const paquete_red_t *paquete);
```
<!-- c -->
**Reglas sugeridas:**
- Puertos conocidos (80, 443, 22) → `TRAFICO_NORMAL`
- Puertos altos no estándar → `TRAFICO_SOSPECHOSO`
- Transferencias muy grandes o patrones anómalos → `TRAFICO_MALICIOSO`
(ej_b2_c11_33)=
### Ejercicio 2.11.33 - Estadísticas por protocolo ⭐⭐⭐☆☆
Implementar una función que cuente paquetes por protocolo en un arreglo de
paquetes.
```{code-block} c
:linenos:
typedef struct
{
unsigned int tcp;
unsigned int udp;
unsigned int icmp;
unsigned int otro;
} estadisticas_protocolo_t;
estadisticas_protocolo_t contar_por_protocolo(const paquete_red_t *paquetes,
size_t cantidad);
```
<!-- {code-block} c -->
## Enums en Sistemas de Archivos
(ej_b2_c11_34)=
### Ejercicio 2.11.34 - Permisos de archivo (UNIX) ⭐⭐☆☆☆
Modelar permisos de archivo estilo UNIX usando flags.
```{code-block} c
:linenos:
enum permiso_unix
{
OWNER_READ = 0400, // 0100000000 en octal
OWNER_WRITE = 0200,
OWNER_EXECUTE = 0100,
GROUP_READ = 0040,
GROUP_WRITE = 0020,
GROUP_EXECUTE = 0010,
OTHER_READ = 0004,
OTHER_WRITE = 0002,
OTHER_EXECUTE = 0001
};
```
<!-- {code-block} c -->
Implementar funciones para manipular permisos:
``` c
bool tiene_permiso_unix(unsigned int permisos, enum permiso_unix permiso);
unsigned int agregar_permiso_unix(unsigned int permisos,
enum permiso_unix nuevo);
void mostrar_permisos_unix(unsigned int permisos); // Formato: rwxr-xr--
```
<!-- c -->
(ej_b2_c11_35)=
### Ejercicio 2.11.35 - Tipos de archivo ⭐⭐☆☆☆
Modelar diferentes tipos de archivo en un sistema de archivos.
```{code-block} c
:linenos:
enum tipo_archivo
{
TIPO_REGULAR,
TIPO_DIRECTORIO,
TIPO_ENLACE_SIMBOLICO,
TIPO_ENLACE_DURO,
TIPO_DISPOSITIVO,
TIPO_PIPE,
TIPO_SOCKET
};
typedef struct
{
char nombre[256];
enum tipo_archivo tipo;
size_t tamanio;
unsigned int permisos;
} archivo_info_t;
```
<!-- {code-block} c -->
## Sistema de Eventos
(ej_b2_c11_36)=
### Ejercicio 2.11.36 - Tipos de eventos de UI ⭐⭐☆☆☆
Modelar eventos de interfaz de usuario.
```{code-block} c
:linenos:
enum tipo_evento
{
EVENTO_CLICK,
EVENTO_DOBLE_CLICK,
EVENTO_PRESIONAR_TECLA,
EVENTO_SOLTAR_TECLA,
EVENTO_MOVER_MOUSE,
EVENTO_SCROLL
};
enum boton_mouse
{
BOTON_IZQUIERDO = 1,
BOTON_DERECHO = 2,
BOTON_MEDIO = 4
};
typedef struct
{
enum tipo_evento tipo;
int x, y; // Coordenadas
unsigned int botones; // Flags de botones presionados
unsigned int tecla;
} evento_t;
```
<!-- {code-block} c -->
(ej_b2_c11_37)=
### Ejercicio 2.11.37 - Procesador de eventos ⭐⭐☆☆☆
Implementar un procesador que maneje diferentes tipos de eventos.
``` c
void procesar_evento(const evento_t *evento);
```
<!-- c -->
## Estados de Procesos (Sistema Operativo)
(ej_b2_c11_38)=
### Ejercicio 2.11.38 - Modelo de estados ⭐⭐⭐☆☆
Modelar el ciclo de vida de un proceso en un sistema operativo.
```{code-block} c
:linenos:
enum estado_proceso
{
PROCESO_NUEVO,
PROCESO_LISTO,
PROCESO_EJECUTANDO,
PROCESO_BLOQUEADO,
PROCESO_TERMINADO
};
enum razon_bloqueo
{
BLOQ_IO,
BLOQ_MUTEX,
BLOQ_SEMAFORO,
BLOQ_MENSAJE
};
typedef struct
{
int pid;
enum estado_proceso estado;
enum razon_bloqueo razon; // Solo válido si estado == BLOQUEADO
int prioridad;
} proceso_t;
```
<!-- {code-block} c -->
(ej_b2_c11_39)=
### Ejercicio 2.11.39 - Planificador simple ⭐☆☆☆☆
Implementar funciones de transición de estado para un planificador.
``` c
bool transicion_estado(proceso_t *proceso, enum estado_proceso nuevo_estado);
bool puede_ejecutar(const proceso_t *proceso);
```
<!-- c -->
## Protocolo HTTP
(ej_b2_c11_40)=
### Ejercicio 2.11.40 - Métodos y códigos HTTP ⭐⭐☆☆☆
Modelar métodos y códigos de estado HTTP.
```{code-block} c
:linenos:
enum metodo_http
{
HTTP_GET,
HTTP_POST,
HTTP_PUT,
HTTP_DELETE,
HTTP_PATCH,
HTTP_HEAD,
HTTP_OPTIONS
};
enum codigo_http
{
HTTP_200_OK = 200,
HTTP_201_CREATED = 201,
HTTP_204_NO_CONTENT = 204,
HTTP_301_MOVED = 301,
HTTP_302_FOUND = 302,
HTTP_400_BAD_REQUEST = 400,
HTTP_401_UNAUTHORIZED = 401,
HTTP_403_FORBIDDEN = 403,
HTTP_404_NOT_FOUND = 404,
HTTP_500_INTERNAL_ERROR = 500,
HTTP_503_UNAVAILABLE = 503
};
```
<!-- {code-block} c -->
(ej_b2_c11_41)=
### Ejercicio 2.11.41 - Parser de respuesta HTTP ⭐⭐☆☆☆
Implementar funciones para trabajar con HTTP.
``` c
const char *metodo_a_string(enum metodo_http metodo);
const char *codigo_a_mensaje(enum codigo_http codigo);
bool es_codigo_exito(enum codigo_http codigo); // 2xx
bool es_codigo_error_cliente(enum codigo_http codigo); // 4xx
bool es_codigo_error_servidor(enum codigo_http codigo); // 5xx
```
<!-- c -->
## Semáforo (Sistema de Control)
(ej_b2_c11_42)=
### Ejercicio 2.11.42 - Estados de semáforo ⭐⭐⭐☆☆
Modelar un sistema de semáforo de tráfico.
```{code-block} c
:linenos:
enum estado_semaforo
{
SEMAFORO_ROJO,
SEMAFORO_AMARILLO,
SEMAFORO_VERDE,
SEMAFORO_INTERMITENTE
};
enum direccion_trafico
{
DIR_NORTE_SUR,
DIR_ESTE_OESTE,
DIR_TODAS
};
typedef struct
{
enum estado_semaforo estado;
enum direccion_trafico direccion_activa;
int tiempo_restante; // Segundos
} semaforo_t;
```
<!-- {code-block} c -->
(ej_b2_c11_43)=
### Ejercicio 2.11.43 - Controlador de semáforo ⭐⭐☆☆☆
Implementar la lógica de transición de un semáforo.
``` c
void actualizar_semaforo(semaforo_t *semaforo);
enum estado_semaforo siguiente_estado(enum estado_semaforo actual);
bool puede_pasar(const semaforo_t *semaforo, enum direccion_trafico direccion);
```
<!-- c -->
## Transacciones de Base de Datos
(ej_b2_c11_44)=
### Ejercicio 2.11.44 - Estados de transacción ⭐⭐⭐☆☆
Modelar el ciclo de vida de una transacción.
```{code-block} c
:linenos:
enum estado_transaccion
{
TX_INICIADA,
TX_ACTIVA,
TX_PREPARADA,
TX_COMPROMETIDA,
TX_ABORTADA
};
enum tipo_aislamiento
{
AISLAMIENTO_READ_UNCOMMITTED,
AISLAMIENTO_READ_COMMITTED,
AISLAMIENTO_REPEATABLE_READ,
AISLAMIENTO_SERIALIZABLE
};
typedef struct
{
unsigned long id;
enum estado_transaccion estado;
enum tipo_aislamiento aislamiento;
int num_operaciones;
} transaccion_t;
```
<!-- {code-block} c -->
(ej_b2_c11_45)=
### Ejercicio 2.11.45 - Gestor de transacciones ⭐⭐☆☆☆
Implementar funciones para gestionar transacciones.
``` c
transaccion_t iniciar_transaccion(enum tipo_aislamiento aislamiento);
bool commit_transaccion(transaccion_t *tx);
bool rollback_transaccion(transaccion_t *tx);
bool puede_hacer_commit(const transaccion_t *tx);
```
<!-- c -->
## Tipos de Datos SQL
(ej_b2_c11_46)=
### Ejercicio 2.11.46 - Tipos de columna ⭐⭐☆☆☆
Modelar tipos de datos SQL y sus propiedades.
```{code-block} c
:linenos:
enum tipo_sql
{
SQL_INT,
SQL_BIGINT,
SQL_FLOAT,
SQL_DOUBLE,
SQL_VARCHAR,
SQL_TEXT,
SQL_DATE,
SQL_DATETIME,
SQL_BOOLEAN,
SQL_BLOB
};
enum constraint_sql
{
CONSTRAINT_NINGUNO = 0,
CONSTRAINT_NOT_NULL = 1 << 0,
CONSTRAINT_UNIQUE = 1 << 1,
CONSTRAINT_PRIMARY_KEY = 1 << 2,
CONSTRAINT_FOREIGN_KEY = 1 << 3,
CONSTRAINT_AUTO_INCREMENT = 1 << 4
};
typedef struct
{
char nombre[64];
enum tipo_sql tipo;
unsigned int constraints;
int longitud; // Para VARCHAR
} columna_t;
```
<!-- {code-block} c -->
(ej_b2_c11_47)=
### Ejercicio 2.11.47 - Validación de columnas ⭐⭐☆☆☆
Implementar funciones para validar definiciones de columnas.
``` c
bool es_tipo_numerico(enum tipo_sql tipo);
bool es_tipo_texto(enum tipo_sql tipo);
bool constraints_validos(unsigned int constraints);
size_t tamanio_tipo(enum tipo_sql tipo);
```
<!-- c -->
## Formatos de Imagen
(ej_b2_c11_48)=
### Ejercicio 2.11.48 - Tipos y formatos ⭐⭐☆☆☆
Modelar diferentes formatos de imagen y sus propiedades.
```{code-block} c
:linenos:
enum formato_imagen
{
FORMATO_JPEG,
FORMATO_PNG,
FORMATO_GIF,
FORMATO_BMP,
FORMATO_WEBP,
FORMATO_TIFF,
FORMATO_SVG
};
enum modo_color
{
COLOR_ESCALA_GRISES,
COLOR_RGB,
COLOR_RGBA,
COLOR_CMYK,
COLOR_INDEXADO
};
typedef struct
{
enum formato_imagen formato;
enum modo_color modo;
int ancho;
int alto;
int profundidad_bits;
bool tiene_transparencia;
bool es_animado;
} metadata_imagen_t;
```
<!-- {code-block} c -->
(ej_b2_c11_49)=
### Ejercicio 2.11.49 - Análisis de formatos ⭐⭐☆☆☆
Implementar funciones para analizar propiedades de formatos.
``` c
bool soporta_transparencia(enum formato_imagen formato);
bool soporta_animacion(enum formato_imagen formato);
bool es_formato_comprimido(enum formato_imagen formato);
const char *extension_formato(enum formato_imagen formato);
```
<!-- c -->
## Sistema de Notificaciones
(ej_b2_c11_50)=
### Ejercicio 2.11.50 - Niveles de notificación ⭐⭐☆☆☆
Modelar un sistema de notificaciones con prioridades.
```{code-block} c
:linenos:
enum nivel_notificacion
{
NOTIF_DEBUG,
NOTIF_INFO,
NOTIF_ADVERTENCIA,
NOTIF_ERROR,
NOTIF_CRITICO
};
enum canal_notificacion
{
CANAL_NINGUNO = 0,
CANAL_CONSOLE = 1 << 0,
CANAL_EMAIL = 1 << 1,
CANAL_SMS = 1 << 2,
CANAL_PUSH = 1 << 3,
CANAL_SYSLOG = 1 << 4
};
typedef struct
{
enum nivel_notificacion nivel;
unsigned int canales;
char mensaje[256];
time_t timestamp;
} notificacion_t;
```
<!-- {code-block} c -->
(ej_b2_c11_51)=
### Ejercicio 2.11.51 - Gestor de notificaciones ⭐⭐☆☆☆
Implementar funciones para filtrar y enviar notificaciones.
``` c
void enviar_notificacion(const notificacion_t *notif);
bool debe_notificar(enum nivel_notificacion nivel,
enum nivel_notificacion nivel_minimo);
unsigned int canales_para_nivel(enum nivel_notificacion nivel);
```
<!-- c -->
## Compresión de Datos
(ej_b2_c11_52)=
### Ejercicio 2.11.52 - Algoritmos de compresión ⭐⭐☆☆☆
Modelar diferentes algoritmos de compresión y sus niveles.
```{code-block} c
:linenos:
enum algoritmo_compresion
{
COMP_NINGUNO,
COMP_DEFLATE,
COMP_GZIP,
COMP_BZIP2,
COMP_LZMA,
COMP_ZSTD,
COMP_LZ4
};
enum nivel_compresion
{
NIVEL_MINIMO = 1,
NIVEL_RAPIDO = 3,
NIVEL_NORMAL = 5,
NIVEL_MAXIMO = 9
};
typedef struct
{
enum algoritmo_compresion algoritmo;
enum nivel_compresion nivel;
size_t tamanio_original;
size_t tamanio_comprimido;
double ratio; // tamanio_comprimido / tamanio_original
} resultado_compresion_t;
```
<!-- {code-block} c -->
(ej_b2_c11_53)=
### Ejercicio 2.11.53 - Análisis de compresión ⭐⭐☆☆☆
Implementar funciones para analizar rendimiento de compresión.
``` c
double calcular_ratio(const resultado_compresion_t *resultado);
double porcentaje_ahorro(const resultado_compresion_t *resultado);
bool es_algoritmo_rapido(enum algoritmo_compresion alg);
const char *nombre_algoritmo(enum algoritmo_compresion alg);
```
<!-- c -->
## Máquina de Estados Finita Genérica
(ej_b2_c11_54)=
### Ejercicio 2.11.54 - Framework de FSM ⭐⭐☆☆☆
Implementar un framework genérico para máquinas de estados finitas.
```{code-block} c
:linenos:
#define MAX_ESTADOS 32
#define MAX_TRANSICIONES 64
typedef enum
{
FSM_ESTADO_0,
FSM_ESTADO_1,
FSM_ESTADO_2,
// ... más estados
FSM_ESTADO_MAX
} estado_fsm_t;
typedef enum
{
FSM_EVENTO_0,
FSM_EVENTO_1,
// ... más eventos
FSM_EVENTO_MAX
} evento_fsm_t;
typedef struct
{
estado_fsm_t desde;
estado_fsm_t hasta;
evento_fsm_t evento;
void (*accion)(void *contexto);
} transicion_t;
typedef struct
{
estado_fsm_t estado_actual;
transicion_t transiciones[MAX_TRANSICIONES];
int num_transiciones;
void *contexto;
} maquina_estados_t;
```
<!-- {code-block} c -->
(ej_b2_c11_55)=
### Ejercicio 2.11.55 - Motor de FSM ⭐⭐☆☆☆
Implementar el motor que procesa eventos y ejecuta transiciones.
``` c
void fsm_inicializar(maquina_estados_t *fsm, estado_fsm_t inicial);
bool fsm_agregar_transicion(maquina_estados_t *fsm, transicion_t trans);
bool fsm_procesar_evento(maquina_estados_t *fsm, evento_fsm_t evento);
estado_fsm_t fsm_estado_actual(const maquina_estados_t *fsm);
```
<!-- c -->
## Análisis Comparativo de Enums
(ej_b2_c11_56)=
### Ejercicio 2.11.56 - Comparación de implementaciones ⭐⭐☆☆☆
Analizar diferentes formas de implementar el mismo concepto:
**Opción 1: Enum simple**
``` c
enum dia
{
LUNES,
MARTES,
MIERCOLES,
JUEVES,
VIERNES,
SABADO,
DOMINGO
};
```
<!-- c -->
**Opción 2: Enum con valores explícitos**
``` c
enum dia
{
LUNES = 1,
MARTES = 2,
MIERCOLES = 3,
JUEVES = 4,
VIERNES = 5,
SABADO = 6,
DOMINGO = 7
};
```
<!-- c -->
**Opción 3: Flags con potencias de 2**
``` c
enum dia
{
LUNES = 1 << 0,
MARTES = 1 << 1,
MIERCOLES = 1 << 2,
JUEVES = 1 << 3,
VIERNES = 1 << 4,
SABADO = 1 << 5,
DOMINGO = 1 << 6
};
```
<!-- c -->
Discutir casos de uso, ventajas y desventajas de cada enfoque.
(ej_b2_c11_57)=
### Ejercicio 2.11.57 - Tamaño y rendimiento ⭐⭐☆☆☆
Investigar y documentar:
- Tamaño en memoria de enums (usualmente `sizeof(int)`)
- Rendimiento de operaciones con enums vs constantes
- Optimizaciones del compilador con enums
- Diferencias entre C y C++ en el manejo de enums
(ej_b2_c11_58)=
## Ejercicio 2.11.58 - Enumeración de Días ⭐☆☆☆☆
Definí una enumeración para días de la semana y mostrá el nombre según el valor.
**Orientación:**
``` c
typedef enum
{
LUNES,
MARTES,
MIERCOLES,
JUEVES,
VIERNES,
SABADO,
DOMINGO
} dia_semana_t;
```
<!-- c -->
- Usá `switch` para convertir enum a string
---
(ej_b2_c11_59)=
## Ejercicio 2.11.59 - Estructura Punto 2D ⭐☆☆☆☆
Definí estructura para punto en 2D y función para calcular distancia entre dos
puntos.
**Orientación:**
``` c
typedef struct
{
double x;
double y;
} punto_t;
```
<!-- c -->
- Distancia: `sqrt((p2.x - p1.x)² + (p2.y - p1.y)²)`
---
(ej_b2_c11_60)=
## Ejercicio 2.11.60 - Estructura Fecha ⭐⭐☆☆☆
Creá estructura para fecha y función de validación.
**Orientación:**
``` c
typedef struct
{
int dia;
int mes;
int anio;
} fecha_t;
```
<!-- c -->
- Validar: 1 ≤ mes ≤ 12, día según mes, considerar bisiestos
---
(ej_b2_c11_61)=
## Ejercicio 2.11.61 - Estructura Persona ⭐⭐☆☆☆
Definí estructura persona y función para mostrar información.
**Orientación:**
``` c
typedef struct
{
char nombre[50];
char apellido[50];
int edad;
} persona_t;
```
<!-- c -->
- Función `void mostrar_persona(const persona_t *p)`
---
(ej_b2_c11_62)=
## Ejercicio 2.11.62 - Array de Estructuras ⭐⭐⭐☆☆
Creá array de estudiantes y función para encontrar el de mayor promedio.
**Orientación:**
``` c
typedef struct
{
char nombre[50];
float promedio;
} estudiante_t;
estudiante_t clase[30];
```
<!-- c -->
- Recorré array comparando promedios
---
(ej_b2_c11_63)=
## Ejercicio 2.11.63 - Enumeración con Valores Explícitos ⭐⭐☆☆☆
Definí enumeración para códigos de error HTTP.
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
HTTP_OK = 200,
HTTP_CREATED = 201,
HTTP_BAD_REQUEST = 400,
HTTP_NOT_FOUND = 404,
HTTP_SERVER_ERROR = 500
} http_status_t;
```
<!-- {code-block} c -->
---
(ej_b2_c11_64)=
## Ejercicio 2.11.64 - Estructura Anidada ⭐⭐⭐☆☆
Creá estructura para dirección y persona que incluya dirección.
**Orientación:**
```{code-block} c
:linenos:
typedef struct
{
char calle[100];
int numero;
char ciudad[50];
} direccion_t;
typedef struct
{
char nombre[50];
direccion_t direccion; // Estructura anidada
} persona_t;
```
<!-- {code-block} c -->
---
(ej_b2_c11_65)=
## Ejercicio 2.11.65 - Estructura con Puntero ⭐⭐⭐☆☆
Definí estructura nodo para lista enlazada.
**Orientación:**
``` c
typedef struct nodo
{
int dato;
struct nodo *siguiente; // Puntero a mismo tipo
} nodo_t;
```
<!-- c -->
- Funciones: crear_nodo, insertar_inicio, mostrar_lista
---
(ej_b2_c11_66)=
## Ejercicio 2.11.66 - Union para Tipos Múltiples ⭐⭐⭐☆☆
Usá union para almacenar valor que puede ser int, float o char.
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
TIPO_INT,
TIPO_FLOAT,
TIPO_CHAR
} tipo_t;
typedef struct
{
tipo_t tipo;
union
{
int i;
float f;
char c;
} valor;
} variable_t;
```
<!-- {code-block} c -->
- El tipo indica cuál campo de la union es válido
---
(ej_b2_c11_67)=
## Ejercicio 2.11.67 - Inicialización Designada ⭐⭐☆☆☆
Practicá diferentes formas de inicializar estructuras.
**Orientación:**
```{code-block} c
:linenos:
// Orden
punto_t p1 = {3.0, 4.0};
// Designadores (C99)
punto_t p2 = {.x = 3.0, .y = 4.0};
punto_t p3 = {.y = 4.0, .x = 3.0}; // Orden no importa
// Parcial (resto en 0)
punto_t p4 = {.x = 3.0};
```
<!-- {code-block} c -->
---
(ej_b2_c11_68)=
## Ejercicio 2.11.68 - Rectángulo con Puntos ⭐⭐⭐☆☆
Definí rectángulo con dos puntos (esquinas opuestas) y calcula área/perímetro.
**Orientación:**
``` c
typedef struct
{
punto_t superior_izq;
punto_t inferior_der;
} rectangulo_t;
```
<!-- c -->
- Área: ancho × alto
- Perímetro: 2 × (ancho + alto)
---
(ej_b2_c11_69)=
## Ejercicio 2.11.69 - Biblioteca de Libros ⭐⭐⭐⭐☆
Sistema con estructuras para libro, autor, editorial.
**Orientación:**
```{code-block} c
:linenos:
typedef struct
{
char nombre[50];
int anio_nacimiento;
} autor_t;
typedef struct
{
char titulo[100];
autor_t autor;
int anio_publicacion;
float precio;
} libro_t;
```
<!-- {code-block} c -->
- Funciones: buscar por título, filtrar por autor, ordenar por precio
---
(ej_b2_c11_70)=
## Ejercicio 2.11.70 - Enum como Flags (Bits) ⭐⭐⭐⭐☆
Usá enum para permisos de archivo estilo Unix.
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
PERM_READ = 1 << 0, // 0001
PERM_WRITE = 1 << 1, // 0010
PERM_EXECUTE = 1 << 2, // 0100
} permisos_t;
// Combinar permisos con OR
int permisos = PERM_READ | PERM_WRITE;
// Verificar con AND
if (permisos & PERM_READ)
{ /* tiene lectura */
}
```
<!-- {code-block} c -->
---
(ej_b2_c11_71)=
## Ejercicio 2.11.71 - Struct con Padding ⭐⭐⭐⭐☆
Explorá alineación de memoria en estructuras.
**Orientación:**
```{code-block} c
:linenos:
typedef struct
{
char c; // 1 byte + 3 padding
int i; // 4 bytes
char d; // 1 byte + 3 padding
} mal_alineada_t; // Total: 12 bytes
typedef struct
{
int i; // 4 bytes
char c; // 1 byte
char d; // 1 byte + 2 padding
} bien_alineada_t; // Total: 8 bytes
```
<!-- {code-block} c -->
- Usá `sizeof()` para ver diferencias
---
(ej_b2_c11_72)=
## Ejercicio 2.11.72 - Registro de Paquetes de Red con Enums y Structs ⭐⭐⭐⭐⭐
Implementá un sistema de clasificación y manejo de paquetes de red combinando tipos enumerados y estructuras:
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
PROTO_TCP,
PROTO_UDP,
PROTO_ICMP
} protocolo_t;
typedef enum
{
ESTADO_PENDIENTE,
ESTADO_EN_TRANSITO,
ESTADO_ENTREGADO,
ESTADO_DESCARTADO
} estado_paquete_t;
typedef struct
{
unsigned int id;
protocolo_t protocolo;
estado_paquete_t estado;
unsigned short puerto_origen;
unsigned short puerto_destino;
size_t bytes_datos;
} paquete_red_t;
```
<!-- {code-block} c -->
- Funciones: `paquete_crear`, `paquete_actualizar_estado`, `paquete_mostrar_info`
---
(ej_b2_c11_73)=
## Ejercicio 2.11.73 - Polimorfismo con Union ⭐⭐⭐⭐⭐
Creá sistema de figuras geométricas con union.
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
CIRCULO,
RECTANGULO,
TRIANGULO
} tipo_figura_t;
typedef struct
{
punto_t centro;
double radio;
} circulo_t;
typedef struct
{
punto_t p1, p2;
} rectangulo_t;
typedef struct
{
tipo_figura_t tipo;
union
{
circulo_t circulo;
rectangulo_t rectangulo;
} datos;
} figura_t;
double calcular_area(const figura_t *f);
```
<!-- {code-block} c -->
---
(ej_b2_c11_74)=
## Ejercicio 2.11.74 - Cola con Struct ⭐⭐⭐⭐☆
Implementá cola FIFO con estructura.
**Orientación:**
```{code-block} c
:linenos:
typedef struct
{
int *datos;
int frente;
int fin;
int capacidad;
int tamanio;
} cola_t;
```
<!-- {code-block} c -->
- Funciones: crear, encolar, desencolar, esta_llena, destruir
---
(ej_b2_c11_75)=
## Ejercicio 2.11.75 - Inventario de Dispositivos de Red con Enums y Structs ⭐⭐⭐⭐⭐
Representá un inventario de dispositivos y conexiones con tipos y estados enumerados:
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
DISP_ROUTER,
DISP_SWITCH,
DISP_SERVIDOR,
DISP_TERMINAL
} tipo_dispositivo_t;
typedef enum
{
CONEXION_ACTIVA,
CONEXION_INACTIVA,
CONEXION_FALLA
} estado_conexion_t;
typedef struct
{
unsigned int id;
char hostname[32];
tipo_dispositivo_t tipo;
estado_conexion_t estado;
unsigned int ip;
} dispositivo_t;
```
<!-- {code-block} c -->
- Funciones: `dispositivo_crear`, `dispositivo_cambiar_estado`, `dispositivo_imprimir`
---
(ej_b2_c11_76)=
## Ejercicio 2.11.76 - Base de Datos Simple ⭐⭐⭐⭐⭐
Sistema CRUD para empleados.
**Orientación:**
```{code-block} c
:linenos:
typedef struct
{
int id;
char nombre[50];
char departamento[50];
float salario;
} empleado_t;
typedef struct
{
empleado_t *empleados;
int cantidad;
int capacidad;
} base_datos_t;
```
<!-- {code-block} c -->
- Funciones: crear, agregar, buscar, actualizar, eliminar, listar
---
(ej_b2_c11_77)=
## Ejercicio 2.11.77 - Máquina de Estados con Enum ⭐⭐⭐⭐⭐
Implementá máquina de estados finitos.
**Orientación:**
```{code-block} c
:linenos:
typedef enum
{
ESTADO_INICIO,
ESTADO_PROCESANDO,
ESTADO_PAUSA,
ESTADO_ERROR,
ESTADO_FIN
} estado_t;
typedef enum
{
EVENTO_INICIAR,
EVENTO_PAUSAR,
EVENTO_REANUDAR,
EVENTO_ERROR,
EVENTO_COMPLETAR
} evento_t;
typedef struct
{
estado_t estado_actual;
// Datos del contexto
} maquina_t;
estado_t transicion(estado_t actual, evento_t evento);
```
<!-- {code-block} c -->
---
## Notas Finales
:::{tip} Convenciones de Nomenclatura
**Enumeraciones:**
``` c
typedef enum
{
COLOR_ROJO,
COLOR_VERDE,
COLOR_AZUL
} color_t;
```
<!-- c -->
- Sufijo `_t` para el tipo
- Prefijo común para los valores
**Estructuras:**
``` c
typedef struct
{
// campos
} nombre_t;
```
<!-- c -->
- Sufijo `_t` indica que es un tipo definido por el usuario
Estas consignas cubren tipos de datos personalizados desde básicos hasta sistemas complejos, preparando para diseño de TADs profesionales.