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, soporte de aserciones y verificación lógica.
Herramientas de Verificación: Valgrind (memcheck) y AddressSanitizer (
-fsanitize=address,undefined) para garantizar la ausencia de lecturas o accesos inválidos.Conocimientos Previos: Funciones en C, paso por valor, tipos escalares de retorno, contratos pre/postcondición y aserciones unitarias (
assert).
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Analizar el mecanismo de paso por valor, aislamiento de ámbito local y ciclo de vida de variables automáticas.
Nivel 3 (Aplicación): Implementar funciones puras y reutilizables en C11 desacopladas de operaciones de entrada/salida.
Nivel 4 (Análisis): Evaluar precondiciones aritméticas (prevención de overflow) y postcondiciones mediante contratos formales.
Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Capítulos de Apunte Correspondientes¶
Cuestiones de Estilo Aplicables¶
Resolución mediante funciones: Según la 0x2008h: Los ejercicios deben ser resueltos mediante funciones, la lógica debe ser encapsulada en funciones independientes.
Nomenclatura en funciones: Los nombres de funciones y variables locales deben seguir la convención
snake_caseen minúsculas, de acuerdo con las reglas 0x2009h: Los nombres de funciones y procedimientos deben usar snake_case en minúsculas y 0x0102h: Los argumentos de función y las variables locales deben usar snake_case en minúsculas.Separación de entrada/salida: En concordancia con la 0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito, se debe evitar que las funciones de cálculo realicen entrada/salida (
printf/scanf) a menos que ese sea su propósito explícito. Deben retornar valores o códigos de estado.
Ejercicio 1.04.01 - Duplicación Aritmética Escalar ⭐⭐☆☆☆¶
Solution to Exercise funciones-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15#include <assert.h> int doble(int n) { return 2 * n; } int main(void) { assert(doble(5) == 10); assert(doble(-7) == -14); assert(doble(0) == 0); assert(doble(1000000) == 2000000); return 0; }
Ejercicio 1.04.02 - Máximo de Dos Enteros ⭐⭐☆☆☆¶
Solution to Exercise funciones-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19#include <assert.h> int mayor(int a, int b) { if (a >= b) { return a; } return b; } int main(void) { assert(mayor(10, 7) == 10); assert(mayor(3, 15) == 15); assert(mayor(42, 42) == 42); assert(mayor(-20, -5) == -5); return 0; }
Ejercicio 1.04.03 - Predicado Booleano de Paridad ⭐⭐☆☆☆¶
Solution to Exercise funciones-3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17#include <assert.h> #include <stdbool.h> bool es_par(int n) { return (n % 2) == 0; } int main(void) { assert(es_par(12) == true); assert(es_par(7) == false); assert(es_par(0) == true); assert(es_par(-8) == true); assert(es_par(-15) == false); return 0; }
Ejercicio 1.04.04 - Promedio Ponderado de Notas en Punto Flotante ⭐⭐☆☆☆¶
Solution to Exercise funciones-4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16#include <assert.h> #include <math.h> double calcular_promedio(int a, int b, int c) { return (double)(a + b + c) / 3.0; } int main(void) { assert(fabs(calcular_promedio(7, 8, 10) - (25.0 / 3.0)) < 0.0001); assert(fabs(calcular_promedio(6, 8, 10) - 8.0) < 0.0001); assert(fabs(calcular_promedio(0, 0, 0) - 0.0) < 0.0001); assert(fabs(calcular_promedio(10, 10, 10) - 10.0) < 0.0001); return 0; }
Ejercicio 1.04.05 - Cálculo de Superficie de Rectángulo ⭐⭐☆☆☆¶
Solution to Exercise funciones-5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20#include <assert.h> long calcular_area_rectangulo(int base, int altura) { if (base <= 0 || altura <= 0) { return -1; } return (long)base * (long)altura; } int main(void) { assert(calcular_area_rectangulo(5, 4) == 20); assert(calcular_area_rectangulo(6, 6) == 36); assert(calcular_area_rectangulo(0, 10) == -1); assert(calcular_area_rectangulo(-5, 4) == -1); assert(calcular_area_rectangulo(5, -4) == -1); return 0; }
Ejercicio 1.04.06 - División Real Segura con Código de Estado ⭐⭐☆☆☆¶
Solution to Exercise funciones-6
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#include <assert.h> #include <math.h> #include <stdbool.h> #include <stddef.h> bool dividir_seguro(double dividendo, double divisor, double *resultado) { if (resultado == NULL || fabs(divisor) < 1e-9) { return false; } *resultado = dividendo / divisor; return true; } int main(void) { double res = 0.0; assert(dividir_seguro(10.0, 2.0, &res) == true); assert(fabs(res - 5.0) < 0.0001); assert(dividir_seguro(7.0, 2.0, &res) == true); assert(fabs(res - 3.5) < 0.0001); assert(dividir_seguro(5.0, 0.0, &res) == false); assert(dividir_seguro(5.0, 2.0, NULL) == false); return 0; }
Ejercicio 1.04.07 - Predicado de Primalidad Optimizado ⭐⭐⭐☆☆¶
Solution to Exercise funciones-7
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#include <assert.h> #include <stdbool.h> bool es_primo(int n) { if (n <= 1) { return false; } if (n == 2) { return true; } if (n % 2 == 0) { return false; } for (int i = 3; (long)i * i <= n; i += 2) { if (n % i == 0) { return false; } } return true; } int main(void) { assert(es_primo(13) == true); assert(es_primo(15) == false); assert(es_primo(2) == true); assert(es_primo(1) == false); assert(es_primo(0) == false); assert(es_primo(-7) == false); assert(es_primo(29) == true); assert(es_primo(49) == false); return 0; }
Ejercicio 1.04.08 - Máximo Común Divisor Euclidiano ⭐⭐⭐☆☆¶
Solution to Exercise funciones-8
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#include <assert.h> #include <stdlib.h> int calcular_mcd(int a, int b) { a = abs(a); b = abs(b); while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } int main(void) { assert(calcular_mcd(48, 18) == 6); assert(calcular_mcd(17, 13) == 1); assert(calcular_mcd(0, 25) == 25); assert(calcular_mcd(-24, 36) == 12); assert(calcular_mcd(100, 100) == 100); return 0; }
Ejercicio 1.04.09 - Resolución de Ecuación Cuadrática y Discriminante ⭐⭐⭐☆☆¶
Solution to Exercise funciones-9
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 85 86 87 88 89 90#include <assert.h> #include <math.h> #include <stddef.h> typedef enum { CUADRATICA_DEGENERADA, CUADRATICA_SIN_REALES, CUADRATICA_RAIZ_DOBLE, CUADRATICA_DOS_REALES } tipo_solucion_t; tipo_solucion_t resolver_cuadratica(double a, double b, double c, double *x1, double *x2) { const double EPSILON = 1e-9; if (fabs(a) < EPSILON) { return CUADRATICA_DEGENERADA; } double discriminante = (b * b) - (4.0 * a * c); if (discriminante < -EPSILON) { return CUADRATICA_SIN_REALES; } if (fabs(discriminante) <= EPSILON) { double raiz = -b / (2.0 * a); if (x1 != NULL) { *x1 = raiz; } if (x2 != NULL) { *x2 = raiz; } return CUADRATICA_RAIZ_DOBLE; } double raiz_delta = sqrt(discriminante); double r1 = (-b - raiz_delta) / (2.0 * a); double r2 = (-b + raiz_delta) / (2.0 * a); if (r1 > r2) { double temp = r1; r1 = r2; r2 = temp; } if (x1 != NULL) { *x1 = r1; } if (x2 != NULL) { *x2 = r2; } return CUADRATICA_DOS_REALES; } int main(void) { double r1 = 0.0; double r2 = 0.0; /* Caso degenerado (a = 0) */ assert(resolver_cuadratica(0.0, 3.0, -6.0, &r1, &r2) == CUADRATICA_DEGENERADA); /* Sin raíces reales (x^2 + 1 = 0) */ assert(resolver_cuadratica(1.0, 0.0, 1.0, &r1, &r2) == CUADRATICA_SIN_REALES); /* Raíz doble ((x - 2)^2 = x^2 - 4x + 4 = 0) */ assert(resolver_cuadratica(1.0, -4.0, 4.0, &r1, &r2) == CUADRATICA_RAIZ_DOBLE); assert(fabs(r1 - 2.0) < 1e-6); assert(fabs(r2 - 2.0) < 1e-6); /* Dos raíces reales ((x - 2)(x - 3) = x^2 - 5x + 6 = 0) */ assert(resolver_cuadratica(1.0, -5.0, 6.0, &r1, &r2) == CUADRATICA_DOS_REALES); assert(fabs(r1 - 2.0) < 1e-6); assert(fabs(r2 - 3.0) < 1e-6); /* Seguridad ante punteros NULL */ assert(resolver_cuadratica(1.0, -5.0, 6.0, NULL, NULL) == CUADRATICA_DOS_REALES); return 0; }