Ejercicios: Creación de Librerías de Funciones
Diseño, encapsulamiento e implementación de módulos reutilizables en C
Prerrequisitos y Entorno de Ejecución Requerido¶
Para compilar y resolver los módulos de esta guía se requiere:
Entorno de compilación: GCC 9+ o Clang con soporte estricto ISO C11 (
-std=c11 -Wall -Wextra -Werror -pedantic) bajo Linux/POSIX.Dependencias del sistema: Biblioteca matemática de C (
libm), enlazada explícitamente mediante el flag-lm.Conceptos previos de arquitectura de software:
Separación estricta entre cabecera pública (
.h) e implementación privada (.c).Guardas del preprocesador contra inclusión múltiple (
#ifndef,#define,#endif).Visibilidad interna y ocultamiento de símbolos auxiliares con el calificador
static.Comparación numérica con tolerancia épsilon (
fabs(a - b) < 1e-6) para punto flotante.
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Comprender el principio de ocultamiento de información y modularidad en C.
Nivel 3 (Aplicación): Diseñar e implementar bibliotecas cohesivas con prefijo de módulo unificado y funciones auxiliares estáticas.
Nivel 4 (Análisis): Evaluar el diseño de APIs públicas mínimas, contratos defensivos y suites de verificación con aserciones.
Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Acerca de¶
La creación de librerías de funciones (módulos reutilizables) permite estructurar programas de forma limpia, testeable y mantenible. Se recomienda la estructura canónica modular:
include/: Cabeceras (.h) públicas con prototipos y guardas.src/: Implementaciones (.c) con funciones estáticas auxiliares.tests/: Suite de pruebas unitarias (assert) para validar pre/postcondiciones.Makefile: Automatización de construcción (make,make test,make clean).
1. Librerías Matemáticas y Numéricas¶
Ejercicio 1.04b.01 - Librería de Operaciones Geométricas 2D ⭐⭐☆☆☆¶
```c #include <stdio.h> #include <math.h> #include <assert.h> #define EPSILON 1e-7 static int casi_igual(double a, double b) { return fabs(a - b) < EPSILON; } double geo_distancia(double x1, double y1, double x2, double y2) { double dx = x2 - x1; double dy = y2 - y1; return sqrt(dx * dx + dy * dy); } double geo_area_rectangulo(double ancho, double alto) { if (ancho < 0.0 || alto < 0.0) { return -1.0; } return ancho * alto; } double geo_perimetro_rectangulo(double ancho, double alto) { if (ancho < 0.0 || alto < 0.0) { return -1.0; } return 2.0 * (ancho + alto); } int main(void) { assert(casi_igual(geo_distancia(0.0, 0.0, 3.0, 4.0), 5.0)); assert(casi_igual(geo_distancia(1.0, 1.0, 1.0, 1.0), 0.0)); assert(casi_igual(geo_area_rectangulo(4.0, 5.0), 20.0)); assert(casi_igual(geo_perimetro_rectangulo(4.0, 5.0), 18.0)); /* Casos defensivos */ assert(casi_igual(geo_area_rectangulo(-1.0, 5.0), -1.0)); assert(casi_igual(geo_perimetro_rectangulo(4.0, -2.0), -1.0)); return 0; } ```
---
(ej_b1_c04b_02)=
### Ejercicio 1.04b.02 - Librería de Conversión de Unidades ⭐⭐☆☆☆
:::{exercise}
:label: ej_b1_c04b_02_conversiones
Creá un módulo de conversión de unidades termodinámicas y cinemáticas:
- `double conv_celsius_a_fahrenheit(double c)`
- `double conv_fahrenheit_a_celsius(double f)`
- `double conv_kmh_a_ms(double kmh)`
- `double conv_ms_a_kmh(double ms)`
**Tabla de Vectores de Prueba:**
| Magnitud | Entrada | Función Invocada | Resultado Esperado | Tolerancia |
| :--- | :--- | :--- | :--- | :--- |
| Temperatura | `0.0 °C` | `conv_celsius_a_fahrenheit` | `32.0 °F` | `1e-6` |
| Temperatura | `212.0 °F`| `conv_fahrenheit_a_celsius` | `100.0 °C` | `1e-6` |
| Velocidad | `36.0 km/h` | `conv_kmh_a_ms` | `10.0 m/s` | `1e-6` |
| Velocidad | `10.0 m/s` | `conv_ms_a_kmh` | `36.0 km/h` | `1e-6` |
::::{solution}
```c
#include <stdio.h>
#include <math.h>
#include <assert.h>
#define EPSILON 1e-6
static int casi_igual(double a, double b) {
return fabs(a - b) < EPSILON;
}
double conv_celsius_a_fahrenheit(double c) {
return (c * 9.0 / 5.0) + 32.0;
}
double conv_fahrenheit_a_celsius(double f) {
return (f - 32.0) * 5.0 / 9.0;
}
double conv_kmh_a_ms(double kmh) {
return kmh / 3.6;
}
double conv_ms_a_kmh(double ms) {
return ms * 3.6;
}
int main(void) {
assert(casi_igual(conv_celsius_a_fahrenheit(0.0), 32.0));
assert(casi_igual(conv_celsius_a_fahrenheit(100.0), 212.0));
assert(casi_igual(conv_fahrenheit_a_celsius(32.0), 0.0));
assert(casi_igual(conv_fahrenheit_a_celsius(212.0), 100.0));
assert(casi_igual(conv_kmh_a_ms(36.0), 10.0));
assert(casi_igual(conv_ms_a_kmh(10.0), 36.0));
return 0;
}
```
---
(ej_b1_c04b_03)=
### Ejercicio 1.04b.03 - Librería de Estadística Básica ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b1_c04b_03_estadistica
Implementá un módulo para cálculo de estadísticas básicas sobre arreglos de punto flotante en C11:
- `double est_media(const double *datos, size_t n)`: retorna la media aritmética, o `0.0` si `n == 0` o `datos == NULL`.
- `double est_minimo(const double *datos, size_t n)`: retorna el valor mínimo del arreglo.
- `double est_maximo(const double *datos, size_t n)`: retorna el valor máximo del arreglo.
**Tabla de Vectores de Prueba:**
| Caso de Prueba | Arreglo de Datos | Función Invocada | Retorno Esperado |
| :--- | :--- | :--- | :--- |
| Muestra estándar | `[2.0, 4.0, 6.0]` | `est_media` | `4.0` |
| Rango extremos | `[10.5, -3.2, 8.0, 15.1]` | `est_minimo` / `est_maximo` | `-3.2` / `15.1` |
| Arreglo unitario | `[42.0]` | `est_media` | `42.0` |
| Puntero nulo | `NULL, 0` | `est_media` | `0.0` |
::::{solution}
```c
#include <stdio.h>
#include <stddef.h>
#include <math.h>
#include <assert.h>
#define EPSILON 1e-6
static int casi_igual(double a, double b) {
return fabs(a - b) < EPSILON;
}
double est_media(const double *datos, size_t n) {
if (datos == NULL || n == 0) {
return 0.0;
}
double suma = 0.0;
for (size_t i = 0; i < n; ++i) {
suma += datos[i];
}
return suma / (double)n;
}
double est_minimo(const double *datos, size_t n) {
if (datos == NULL || n == 0) {
return 0.0;
}
double min = datos[0];
for (size_t i = 1; i < n; ++i) {
if (datos[i] < min) {
min = datos[i];
}
}
return min;
}
double est_maximo(const double *datos, size_t n) {
if (datos == NULL || n == 0) {
return 0.0;
}
double max = datos[0];
for (size_t i = 1; i < n; ++i) {
if (datos[i] > max) {
max = datos[i];
}
}
return max;
}
int main(void) {
double m1[3] = {2.0, 4.0, 6.0};
assert(casi_igual(est_media(m1, 3), 4.0));
double m2[4] = {10.5, -3.2, 8.0, 15.1};
assert(casi_igual(est_minimo(m2, 4), -3.2));
assert(casi_igual(est_maximo(m2, 4), 15.1));
double m3[1] = {42.0};
assert(casi_igual(est_media(m3, 1), 42.0));
assert(casi_igual(est_media(NULL, 0), 0.0));
assert(casi_igual(est_minimo(NULL, 0), 0.0));
assert(casi_igual(est_maximo(NULL, 0), 0.0));
return 0;
}
```
(ej_b1_c04b_04)=
### Ejercicio 1.04b.04 - Librería de Números Primos y Factorización ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b1_c04b_04_primos
Implementá una biblioteca para la verificación y generación de números primos con tipado estricto:
- `bool primo_es_primo(unsigned long n)`: retorna `true` si $n$ es primo ($n \ge 2$), `false` en caso contrario.
- `unsigned long primo_siguiente(unsigned long n)`: retorna el menor número primo estrictamente mayor que $n$.
**Tabla de Vectores de Prueba:**
| Caso de Prueba | Parámetro `n` | `primo_es_primo` | `primo_siguiente` |
| :--- | :--- | :--- | :--- |
| Primer primo | `2` | `true` | `3` |
| Número compuesto | `4` | `false` | `5` |
| Primo impar | `13` | `true` | `17` |
| Casos límite | `0`, `1` | `false` | `2` |
::::{solution}
```c
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
bool primo_es_primo(unsigned long n) {
if (n < 2) {
return false;
}
if (n == 2 || n == 3) {
return true;
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
for (unsigned long i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
unsigned long primo_siguiente(unsigned long n) {
if (n < 2) {
return 2;
}
unsigned long candidato = n + 1;
while (!primo_es_primo(candidato)) {
candidato++;
}
return candidato;
}
int main(void) {
assert(primo_es_primo(0) == false);
assert(primo_es_primo(1) == false);
assert(primo_es_primo(2) == true);
assert(primo_es_primo(3) == true);
assert(primo_es_primo(4) == false);
assert(primo_es_primo(13) == true);
assert(primo_es_primo(25) == false);
assert(primo_siguiente(0) == 2);
assert(primo_siguiente(1) == 2);
assert(primo_siguiente(2) == 3);
assert(primo_siguiente(4) == 5);
assert(primo_siguiente(13) == 17);
return 0;
}
```
---
(ej_b1_c04b_05)=
### Ejercicio 1.04b.05 - Librería de Trigonometría y Resolución de Triángulos ⭐⭐⭐☆☆
:::{exercise}
:label: ej_b1_c04b_05_trigonometria
:enumerator: librerias-5
Diseñá un módulo de cálculos geométricos y trigonométricos en C11 utilizando `<math.h>`:
```c
double trigo_hipotenusa(double cateto1, double cateto2);
double trigo_angulo_vector(double x, double y);
bool trigo_resolver_triangulo_sss(double a, double b, double c,
double *alpha, double *beta, double *gamma);
```
- `trigo_hipotenusa`: Calcula $\sqrt{c_1^2 + c_2^2}$ utilizando `hypot` o la fórmula de Pitágoras.
- `trigo_angulo_vector`: Calcula el ángulo polar en radianes en el rango $[-\pi, \pi]$ mediante `atan2(y, x)`.
- `trigo_resolver_triangulo_sss`: Determina los tres ángulos interiores (en radianes) a partir de las longitudes de los lados $a, b, c$ usando el teorema del coseno:
$$\cos(\alpha) = \frac{b^2 + c^2 - a^2}{2bc}$$
Retorna `false` si los lados no cumplen la desigualdad triangular estricta ($a+b>c$, $a+c>b$, $b+c>a$) o si alguno de los punteros de salida es `NULL`.
**Nivel de Bloom:** Nivel 3 (Aplicación) y Nivel 4 (Análisis).
**Conceptos requeridos:** Funciones de `<math.h>` (`hypot`, `atan2`, `acos`), validación de desigualdades geométricas, paso por referencia.
**Techo conceptual:** Prohibido el uso de valores no numéricos (`NaN`) o divisiones por cero sin validación previa.
#### Contrato de las Funciones
- **Precondiciones:** Lados y catetos estrictamente positivos. Punteros de salida no nulos para `trigo_resolver_triangulo_sss`.
- **Postcondiciones:** Retorna `true` y escribe los ángulos cuya suma es exactamente $\pi$ radianes.
#### Tabla de Vectores de Prueba
| Triángulo ($a, b, c$) | Retorno | Ángulos ($\alpha, \beta, \gamma$) | Justificación Técnica |
| :--- | :--- | :--- | :--- |
| Equilátero ($2, 2, 2$) | `true` | $\pi/3, \pi/3, \pi/3$ | Tres ángulos iguales a $60^\circ$ |
| Rectángulo ($3, 4, 5$) | `true` | $\gamma = \pi/2$ | Hipotenusa opuesta al ángulo recto |
| Inválido ($1, 2, 10$) | `false` | Sin escrituras | Viola desigualdad triangular ($1 + 2 < 10$) |
| Puntero nulo | `false` | Sin escrituras | Rechazo defensivo |
Solution to ej_b1_c04b_05_trigonometria
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84#include <assert.h> #include <math.h> #include <stdbool.h> #include <stddef.h> #define EPSILON 1e-6 #ifndef M_PI #define M_PI 3.14159265358979323846 #endif static bool casi_iguales(double a, double b) { return fabs(a - b) < EPSILON; } double trigo_hipotenusa(double cateto1, double cateto2) { return hypot(cateto1, cateto2); } double trigo_angulo_vector(double x, double y) { return atan2(y, x); } bool trigo_resolver_triangulo_sss(double a, double b, double c, double *alpha, double *beta, double *gamma) { if (alpha == NULL || beta == NULL || gamma == NULL) { return false; } if (a <= 0.0 || b <= 0.0 || c <= 0.0) { return false; } // Desigualdad triangular estricta if ((a + b <= c) || (a + c <= b) || (b + c <= a)) { return false; } double cos_a = (b * b + c * c - a * a) / (2.0 * b * c); double cos_b = (a * a + c * c - b * b) / (2.0 * a * c); double cos_c = (a * a + b * b - c * c) / (2.0 * a * b); *alpha = acos(cos_a); *beta = acos(cos_b); *gamma = acos(cos_c); return true; } int main(void) { // Hipotenusa assert(casi_iguales(trigo_hipotenusa(3.0, 4.0), 5.0)); // Ángulo polar vector (1, 1) = pi/4 assert(casi_iguales(trigo_angulo_vector(1.0, 1.0), M_PI / 4.0)); // Triángulo equilátero double a = 0.0, b = 0.0, c = 0.0; assert(trigo_resolver_triangulo_sss(2.0, 2.0, 2.0, &a, &b, &c) == true); assert(casi_iguales(a, M_PI / 3.0)); assert(casi_iguales(b, M_PI / 3.0)); assert(casi_iguales(c, M_PI / 3.0)); assert(casi_iguales(a + b + c, M_PI)); // Triángulo rectángulo (3, 4, 5) -> gamma opuesto al lado 5 es pi/2 assert(trigo_resolver_triangulo_sss(3.0, 4.0, 5.0, &a, &b, &c) == true); assert(casi_iguales(c, M_PI / 2.0)); // Triángulo inválido assert(trigo_resolver_triangulo_sss(1.0, 2.0, 10.0, &a, &b, &c) == false); // Punteros nulos assert(trigo_resolver_triangulo_sss(3.0, 4.0, 5.0, NULL, &b, &c) == false); return 0; }
2. Librerías de Manipulación de Texto y Cadenas¶
Ejercicio 1.04b.06 - Biblioteca de Strings seguros ⭐⭐⭐⭐⭐¶
Reimplementá funciones estándar de <string.h> en la librería seguras.h y seguras.c:
int mi_strlen(const char *str, size_t len_str)void mi_strcpy(char *dest, size_t len_dest, const char *src, size_t len_src)int mi_strcmp(const char *s1, size_t len_s1, const char *s2, size_t len_s2)void mi_strcat(char *dest, size_t len_dest, const char *src, size_t len_src)char *mi_strchr(const char *str, size_t len_str, char c)
Orientación:
strlen: contá hasta'\0'o hasta alcanzarlen_strstrcpy: copiá carácter por carácter respetando los límites de tamañostrcmp: retorna la diferencia numérica del primer carácter distinto dentro de los límitesstrcat: copiásrcal final dedestsin sobrepasarlen_deststrchr: retorna puntero a la primera aparición decdentro del límite indicadoVerificá límites de destino para evitar desbordamientos de búfer.
Ejercicio 1.04b.07 - Librería de Transformación de Cadenas In-Place ⭐⭐⭐☆☆¶
Solution to Exercise 1
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77#include <ctype.h> #include <string.h> #include <assert.h> #include <stddef.h> void str_a_mayusculas(char *str) { if (str == NULL) { return; } for (size_t i = 0; str[i] != '\0'; i++) { str[i] = (char)toupper((unsigned char)str[i]); } } void str_a_minusculas(char *str) { if (str == NULL) { return; } for (size_t i = 0; str[i] != '\0'; i++) { str[i] = (char)tolower((unsigned char)str[i]); } } void str_invertir(char *str) { if (str == NULL) { return; } size_t len = strlen(str); if (len <= 1) { return; } size_t i = 0; size_t j = len - 1; while (i < j) { char temp = str[i]; str[i] = str[j]; str[j] = temp; i++; j--; } } int main(void) { char buf1[] = "Hola Mundo 123!"; str_a_mayusculas(buf1); assert(strcmp(buf1, "HOLA MUNDO 123!") == 0); str_a_minusculas(buf1); assert(strcmp(buf1, "hola mundo 123!") == 0); char buf2[] = "algoritmo"; str_invertir(buf2); assert(strcmp(buf2, "omtirogla") == 0); char buf3[] = ""; str_invertir(buf3); assert(strcmp(buf3, "") == 0); /* Seguridad defensiva */ str_a_mayusculas(NULL); str_a_minusculas(NULL); str_invertir(NULL); return 0; }
Ejercicio 1.04b.08 - Librería de Búsqueda y Conteo en Texto ⭐⭐⭐☆☆¶
Implementá la librería text_search.h y text_search.c:
size_t text_contar_palabras(const char *texto, size_t len_texto)size_t text_contar_caracter(const char *texto, size_t len_texto, char c)size_t text_contar_vocales(const char *texto, size_t len_texto)bool text_es_palindromo(const char *texto, size_t len_texto)
Ejercicio 1.04b.09 - Librería de Formateo y Padding de Texto ⭐⭐⭐☆☆¶
Diseñá str_format.h y str_format.c:
bool str_pad_left(const char *src, size_t len_src, char *dest, size_t dest_size, size_t total_len, char pad_char)bool str_pad_right(const char *src, size_t len_src, char *dest, size_t dest_size, size_t total_len, char pad_char)bool str_centrar(const char *src, size_t len_src, char *dest, size_t dest_size, size_t total_len, char pad_char)
Ejercicio 1.04b.10 - Librería de Sanitización e Inspección de Entradas ⭐⭐⭐☆☆¶
Creá sanitizer.h y sanitizer.c:
bool san_es_entero_valido(const char *str, size_t len_str)bool san_es_decimal_valido(const char *str, size_t len_str)bool san_es_email_basico(const char *str, size_t len_str)(presencia de@y al menos un.)void san_reemplazar_caracter(char *str, size_t len_str, char viejo, char nuevo)
3. Librerías de Manejo de Arreglos y Matrices¶
Ejercicio 1.04b.11 - Librería de Vectores de Enteros ⭐⭐⭐☆☆¶
---
(ej_b1_c04b_12)=
### Ejercicio 1.04b.12 - Librería de Ordenamiento y Búsqueda ⭐⭐⭐⭐☆
Creá `sort_search.h` y `sort_search.c`:
- `void sort_burbuja(int *v, size_t n)`
- `void sort_seleccion(int *v, size_t n)`
- `void sort_insercion(int *v, size_t n)`
- `ssize_t busqueda_binaria(const int *v, size_t n, int elem)`
:::{hint} Lógica y Consideraciones
- Recordá que `busqueda_binaria` requiere que el arreglo esté previamente ordenado.Ejercicio 1.04b.13 - Librería de Operaciones sobre Matrices 2D ⭐⭐⭐⭐☆¶
Diseñá matriz2d.h y matriz2d.c para matrices con dimensiones fijas o pasadas linealmente:
void mat_sumar(size_t filas, size_t cols, const double A[filas][cols], const double B[filas][cols], double C[filas][cols])void mat_multiplicar_escalar(size_t filas, size_t cols, double M[filas][cols], double escalar)void mat_transponer(size_t filas, size_t cols, const double A[filas][cols], double T[cols][filas])double mat_traza(size_t n, const double A[n][n])
Ejercicio 1.04b.14 - Librería de Manipulación de Conjuntos sobre Arreglos ⭐⭐⭐⭐☆¶
Implementá conjunto_arr.h y conjunto_arr.c:
size_t conj_union(const int *A, size_t nA, const int *B, size_t nB, int *C)size_t conj_interseccion(const int *A, size_t nA, const int *B, size_t nB, int *C)size_t conj_diferencia(const int *A, size_t nA, const int *B, size_t nB, int *C)bool conj_pertenece(const int *A, size_t nA, int elem)
Ejercicio 1.04b.15 - Librería de Transformación y Filtrado de Arreglos ⭐⭐⭐⭐☆¶
Diseñá array_utils.h y array_utils.c para procesar secuencias numéricas mediante funciones modulares:
size_t arr_filtrar_pares(const int *src, size_t n, int *dest): copia solo los valores pares adesty retorna la cantidad colocada.size_t arr_filtrar_mayores_que(const int *src, size_t n, int umbral, int *dest): copia solo los valores mayores queumbral.void arr_escalar(int *v, size_t n, int factor): multiplica cada elemento del arreglo por un factor escalar.long long arr_sumatoria(const int *v, size_t n): calcula la suma total de los elementos.
4. Librerías de Utilidades del Sistema y E/S¶
Ejercicio 1.04b.16 - Librería de Validación de Entradas de Usuario ⭐⭐☆☆☆¶
Diseñá input_val.h y input_val.c para simplificar la lectura segura desde stdin:
int leer_entero_rango(const char *mensaje, size_t len_msg, int min, int max)double leer_double_positivo(const char *mensaje, size_t len_msg)bool leer_confirmacion_s_n(const char *mensaje, size_t len_msg)void leer_cadena_segura(const char *mensaje, size_t len_msg, char *buffer, size_t tam)
Ejercicio 1.04b.17 - Librería de Fechas y Calendario ⭐⭐⭐☆☆¶
Creá fechas.h y fechas.c:
bool fecha_es_bisiesto(int anio)bool fecha_es_valida(int dia, int mes, int anio)int fecha_dias_del_mes(int mes, int anio)int fecha_diferencia_dias(int d1, int m1, int a1, int d2, int m2, int a2)
Ejercicio 1.04b.18 - Librería de Consola y Formato de Salida ⭐⭐☆☆☆¶
Diseñá console_ui.h y console_ui.c:
void ui_limpiar_pantalla(void)void ui_imprimir_titulo(const char *titulo, size_t len_titulo, char adorno)void ui_imprimir_barra_progreso(size_t actual, size_t total, int ancho)void ui_esperar_tecla(void)
Ejercicio 1.04b.19 - Librería de Medición de Tiempos de Ejecución ⭐⭐⭐☆☆¶
Implementá cronometro.h y cronometro.c:
void crono_iniciar(void)double crono_detener_ms(void)double crono_lapso_ms(void)
Ejercicio 1.04b.20 - Librería de Generación Numérica Pseudoaleatoria ⭐⭐⭐☆☆¶
Creá azar.h y azar.c:
void azar_inicializar(unsigned int semilla)int azar_entero_en_rango(int min, int max)double azar_double_0_1(void)bool azar_probabilidad(double p)(retornatruecon probabilidadpentre 0.0 y 1.0)void azar_desordenar_arreglo(int *v, size_t n)
5. Librerías de Simulación y Dominios Específicos¶
Ejercicio 1.04b.21 - Librería de Física: Cinemática ⭐⭐☆☆☆¶
Diseñá fisica_cinematica.h y fisica_cinematica.c:
double fis_posicion_mru(double x0, double v, double t)double fis_posicion_mruv(double x0, double v0, double a, double t)double fis_velocidad_mruv(double v0, double a, double t)double fis_tiempo_caida_libre(double altura, double g)
Ejercicio 1.04b.22 - Librería de Finanzas Básicas ⭐⭐☆☆☆¶
Creá finanzas.h y finanzas.c:
double fin_interes_simple(double capital, double tasa, double tiempo)double fin_interes_compuesto(double capital, double tasa, int periodos)double fin_cuota_prestamo(double capital, double tasa_mensual, int meses)double fin_valor_futuro_anualidad(double cuota, double tasa, int periodos)
Ejercicio 1.04b.23 - Librería de Geometría 3D ⭐⭐⭐☆☆¶
Diseñá geometria3d.h y geometria3d.c:
double geo3d_volumen_esfera(double radio)double geo3d_area_esfera(double radio)double geo3d_volumen_cilindro(double radio, double altura)double geo3d_volumen_cono(double radio, double altura)double geo3d_distancia_puntos(double x1, double y1, double z1, double x2, double y2, double z2)
Ejercicio 1.04b.24 - Librería de Conversión de Bases Numéricas ⭐⭐⭐☆☆¶
Implementá bases.h y bases.c:
bool base_dec_a_binario(unsigned int dec, char *buf, size_t buf_size)bool base_dec_a_hex(unsigned int dec, char *buf, size_t buf_size)unsigned int base_binario_a_dec(const char *bin_str, size_t len_str)unsigned int base_hex_a_dec(const char *hex_str, size_t len_str)
Ejercicio 1.04b.25 - Librería de Criptografía Clásica ⭐⭐⭐☆☆¶
Diseñá cripto_simple.h y cripto_simple.c:
void cripto_cesar_cifrar(char *texto, size_t len_texto, int desplazamiento)void cripto_cesar_descifrar(char *texto, size_t len_texto, int desplazamiento)void cripto_xor_transformar(char *texto, size_t len_texto, char clave)
6. Librerías Avanzadas y Estructuración Compleja¶
Ejercicio 1.04b.26 - Librería de Manejo de Colores RGB ⭐⭐⭐☆☆¶
Creá color_utils.h y color_utils.c para cálculos de color mediante operaciones aritméticas y fórmulas estándar:
double color_luminancia(unsigned char r, unsigned char g, unsigned char b): calcula la luminosidad relativa ().unsigned char color_escala_grises(unsigned char r, unsigned char g, unsigned char b): calcula el promedio de intensidad.unsigned char color_mezclar_componente(unsigned char c1, unsigned char c2, double factor): realiza una interpolación lineal entre dos colores.
Ejercicio 1.04b.27 - Librería de Evaluación de Expresiones lógicas ⭐⭐⭐⭐☆¶
Diseñá eval_logica.h y eval_logica.c:
bool eval_and_3(bool a, bool b, bool c)bool eval_or_3(bool a, bool b, bool c)bool eval_xor(bool a, bool b)bool eval_implicacion(bool p, bool q)bool eval_equivalencia(bool p, bool q)
Ejercicio 1.04b.28 - Librería de Gestión de Estados y Banderas Booleanas ⭐⭐⭐⭐☆¶
Implementá flags.h y flags.c para gestionar conjuntos de opciones mediante arreglos booleanos:
void flag_activar(bool banderas[], size_t n, size_t indice): activa la bandera en la posición indicada.void flag_desactivar(bool banderas[], size_t n, size_t indice): desactiva la bandera indicada.bool flag_consultar(const bool banderas[], size_t n, size_t indice): consulta el estado de la bandera.void flag_reiniciar_todas(bool banderas[], size_t n, bool valor_defecto): asigna un valor uniforme a todas las banderas.size_t flag_contar_activas(const bool banderas[], size_t n): cuenta cuántas banderas están entrue.
Ejercicio 1.04b.29 - Librería de Manejo de Registro de Logs ⭐⭐⭐⭐☆¶
Diseñá logger.h y logger.c:
typedef enum { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR } log_nivel_tvoid log_set_nivel_minimo(log_nivel_t nivel)void log_mensaje(log_nivel_t nivel, const char *modulo, size_t len_mod, const char *mensaje, size_t len_msg)
Ejercicio 1.04b.30 - Librería de Verificación de Integridad (Checksum) ⭐⭐⭐⭐⭐¶
Creá checksum.h y checksum.c:
unsigned char chk_luhn_calcular(const char *digitos, size_t len_digitos): algoritmo de Luhn para números de tarjeta/identificación.bool chk_luhn_validar(const char *digitos, size_t len_digitos)unsigned char chk_suma_paridad(const unsigned char *datos, size_t len)uint16_t chk_fletcher16(const unsigned char *datos, size_t len)