Programación modular
Introducción
En P1 empezaste a dividir el programa en funciones para:
- evitar duplicación de código,
- validar entradas de forma reutilizable,
- mejorar legibilidad y mantenimiento.
En P2 seguimos igual, pero con C++ solemos:
- usar
std::cout/std::cinpara entrada/salida, - usar
constexprpara constantes, - preferir
enum classfrente aenumpara evitar colisiones de nombres, - (más adelante) organizar en ficheros
.h/.cppo con clases.
En este tema nos quedamos con 3 ejemplos representativos.
1) Validación + dibujo con funciones: imprimir una “T”
Pide un número impar >= 3 y dibuja una T de ese tamaño.
Se valida la entrada y se usan funciones.
P1 — C
#include <stdio.h>
#define TAM_MIN 3
int pedirTamImpar();void dibujaT(int tam);
int main() { int tam = pedirTamImpar(); dibujaT(tam); return 0;}
int pedirTamImpar() { int n; do { printf("Introduce un num impar (>= %d): ", TAM_MIN); scanf("%d", &n); } while (n < TAM_MIN || n % 2 == 0); return n;}
void dibujaT(int tam) { int centro = tam / 2 + 1; for (int fil = 1; fil <= tam; fil++) { for (int col = 1; col <= tam; col++) { if (fil == 1 || col == centro) { printf("*"); } else { printf(" "); } } printf("\n"); }}P2 — C++
#include <iostream>
constexpr int TAM_MIN = 3;
int pedirTamImpar();void dibujaT(int tam);
int main() { int tam = pedirTamImpar(); dibujaT(tam); return 0;}
int pedirTamImpar() { int n; do { std::cout << "Introduce un num impar (>= " << TAM_MIN << "): "; std::cin >> n; } while (n < TAM_MIN || n % 2 == 0); return n;}
void dibujaT(int tam) { int centro = tam / 2; // en 0..tam-1 for (int fil = 0; fil < tam; fil++) { for (int col = 0; col < tam; col++) { if (fil == 0 || col == centro) { std::cout << '*'; } else { std::cout << ' '; } } std::cout << '\n'; }}2) Menú + funciones: conversión Celsius ↔ Fahrenheit
Se muestra un menú con 3 opciones (C→F, F→C, terminar). Cada conversión está en su función.
P1 — C
#include <stdio.h>
#define TERMINAR 3#define FACTOR_CONVERSION 1.8f#define AJUSTE_FAHRENHEIT 32.0f
void mostrarMenu();float celsiusAFahrenheit(float c);float fahrenheitACelsius(float f);
int main() { int opcion; float celsius, fahr;
do { mostrarMenu(); printf("Opción: "); scanf("%d", &opcion);
switch(opcion) { case 1: printf("Introduce Celsius: "); scanf("%f", &celsius); fahr = celsiusAFahrenheit(celsius); printf("Fahrenheit: %.2f\n", fahr); break; case 2: printf("Introduce Fahrenheit: "); scanf("%f", &fahr); celsius = fahrenheitACelsius(fahr); printf("Celsius: %.2f\n", celsius); break; case TERMINAR: printf("Ha seleccionado la opción Salir\n"); break; default: printf("Opción inválida (1-3)\n"); } } while(opcion != TERMINAR);
return 0;}
void mostrarMenu() { printf("Seleccione conversión:\n"); printf("1. Celsius -> Fahrenheit\n"); printf("2. Fahrenheit -> Celsius\n"); printf("3. Terminar\n");}
float celsiusAFahrenheit(float c) { return c * FACTOR_CONVERSION + AJUSTE_FAHRENHEIT;}
float fahrenheitACelsius(float f) { return (f - AJUSTE_FAHRENHEIT) / FACTOR_CONVERSION;}P2 — C++
#include <iostream>#include <iomanip>
constexpr int TERMINAR = 3;constexpr double FACTOR = 1.8;constexpr double AJUSTE = 32.0;
void mostrarMenu();double celsiusAFahrenheit(double c);double fahrenheitACelsius(double f);
int main() { int opcion; double celsius, fahr;
do { mostrarMenu(); std::cout << "Opción: "; std::cin >> opcion;
switch (opcion) { case 1: std::cout << "Introduce Celsius: "; std::cin >> celsius; fahr = celsiusAFahrenheit(celsius); std::cout << std::fixed << std::setprecision(2) << "Fahrenheit: " << fahr << "\n"; break;
case 2: std::cout << "Introduce Fahrenheit: "; std::cin >> fahr; celsius = fahrenheitACelsius(fahr); std::cout << std::fixed << std::setprecision(2) << "Celsius: " << celsius << "\n"; break;
case TERMINAR: std::cout << "Ha seleccionado la opción Salir\n"; break;
default: std::cout << "Opción inválida (1-3)\n"; } } while (opcion != TERMINAR);
return 0;}
void mostrarMenu() { std::cout << "Seleccione conversión:\n" << "1. Celsius -> Fahrenheit\n" << "2. Fahrenheit -> Celsius\n" << "3. Terminar\n";}
double celsiusAFahrenheit(double c) { return c * FACTOR + AJUSTE;}
double fahrenheitACelsius(double f) { return (f - AJUSTE) / FACTOR;}3) Modularidad + enumerados: control de un robot con palanca
Se lee la posición de una palanca (avance o retroceso), validando entrada. Se usa un enumerado para mejorar legibilidad y funciones para separar responsabilidades.
P1 — C
#include <stdio.h>
typedef enum {AVANCE, RETROCESO} TPalanca;
TPalanca leerPalanca();void moverMotor(TPalanca);void moverMotorAdelante();void moverMotorAtras();
int main() { TPalanca estadoPalanca = leerPalanca(); moverMotor(estadoPalanca); return 0;}
TPalanca leerPalanca() { TPalanca palanca;
do { printf("¿En qué posición está la palanca? 0-Avance 1-Retroceso\n"); scanf("%u", &palanca); } while(palanca != AVANCE && palanca != RETROCESO);
return palanca;}
void moverMotor(TPalanca estado) { switch(estado) { case AVANCE: moverMotorAdelante(); break; case RETROCESO: moverMotorAtras(); break; }}
void moverMotorAdelante() { printf("El motor se está moviendo hacia adelante.\n");}
void moverMotorAtras() { printf("El motor se está moviendo hacia atrás.\n");}P2 — C++
#include <iostream>
enum class Palanca { Avance = 0, Retroceso = 1 };
Palanca leerPalanca();void moverMotor(Palanca);void moverMotorAdelante();void moverMotorAtras();
int main() { Palanca estado = leerPalanca(); moverMotor(estado); return 0;}
Palanca leerPalanca() { int x; do { std::cout << "¿En qué posición está la palanca? 0-Avance 1-Retroceso\n"; std::cin >> x; } while (x != 0 && x != 1);
return (x == 0) ? Palanca::Avance : Palanca::Retroceso;}
void moverMotor(Palanca estado) { switch (estado) { case Palanca::Avance: moverMotorAdelante(); break; case Palanca::Retroceso: moverMotorAtras(); break; }}
void moverMotorAdelante() { std::cout << "El motor se está moviendo hacia adelante.\n";}
void moverMotorAtras() { std::cout << "El motor se está moviendo hacia atrás.\n";}Recordatorio
- Las funciones deben hacer una tarea concreta.
- Si una función hace varias cosas, divídela en varias.
- Usa nombres descriptivos.
- Evita duplicación: si repites un bloque varias veces, probablemente merece una función.