Programación modular | P2 GIR Saltearse al contenido

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::cin para entrada/salida,
  • usar constexpr para constantes,
  • preferir enum class frente a enum para evitar colisiones de nombres,
  • (más adelante) organizar en ficheros .h/.cpp o 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.