Estructuras de Control y Modularidad

2.02 · Selectivas Anidadas y `switch`

PF-202 ⏱ 90 min ⭐ 100 XP intermedio

🎯 Objetivo de aprendizaje

Al terminar este tema vas a poder:

  1. Escribir cadenas de if-else if-else limpias y eficientes para decisiones con 3+ caminos.
  2. Construir menús interactivos profesionales que se repiten hasta que el usuario elige salir.
  3. Usar la estructura switch/case para decisiones con valores discretos (menús, días de la semana, etc.).
  4. Decidir cuándo usar if-else if-else vs switch/case según el problema.
  5. Aplicar la regla de oro: "una decisión, una indentación" para evitar la "pirámide del doom".
  6. Identificar y corregir el error de "case sin break" y la falta de default.
  7. Construir un sistema de menús modular con funciones y switch, base de cualquier programa interactivo.

Este tema te lleva de "tomo decisiones simples" a "construyo programas interactivos profesionales". El `switch` es una de las herramientas más usadas en interfaces de consola, formularios web, y menús de cualquier tipo.

🧠 Teoría y conceptos — 2.2.1 — La cadena if-else if-else: la forma elegante de múltiples caminos

Cadena if-else if-else: múltiples caminos
Cadena if-else if-else: múltiples caminos

El problema: 3 o más caminos

En el Tema 2.1 vimos cómo decidir entre 2 caminos con if-else. Pero en la vida real hay decisiones con muchos más caminos:

  • Clasificar una nota en A, B, C, D, F (5 caminos).
  • Determinar el día de la semana (7 caminos).
  • Asignar un precio según el tipo de cliente (regular, premium, VIP, etc.).
  • Decidir qué operación hacer en una calculadora (sumar, restar, multiplicar, dividir).

Con anidación tradicional de if-else esto se vuelve ilegible. La solución: `else if`, una sintaxis especial de C++ y Java que mantiene la indentación plana.

Sintaxis de else if

if (condición1) {

// bloque 1

} else if (condición2) {

// bloque 2

} else if (condición3) {

// bloque 3

} else {

// bloque "ninguno de los anteriores"

}

Cómo funciona:

  • Se evalúa condición1. Si es verdadera, se ejecuta el bloque 1 y se sale.
  • Si es falsa, se evalúa condición2. Si es verdadera, se ejecuta el bloque 2 y se sale.
  • Y así sucesivamente.
  • Si ninguna es verdadera, se ejecuta el bloque del else final (opcional pero recomendado).

Equivale a: anidar varios if-else pero con la indentación plana, mucho más legible.

Ejemplo: clasificar nota

Versión anidada (fea):

if (nota >= 9) {
cout << "A" << endl;
} else {
if (nota >= 8) {
cout << "B" << endl;
} else {
if (nota >= 7) {
cout << "C" << endl;
} else {
if (nota >= 6) {
cout << "D" << endl;
} else {
cout << "F" << endl;

}

}

}

}

Versión con `else if` (clara):

if (nota >= 9) {
cout << "A" << endl;
} else if (nota >= 8) {
cout << "B" << endl;
} else if (nota >= 7) {
cout << "C" << endl;
} else if (nota >= 6) {
cout << "D" << endl;
} else {
cout << "F" << endl;

}

Las dos hacen EXACTAMENTE LO MISMO, pero la segunda se lee en 5 segundos, la primera requiere concentración.

Regla de oro: orden de más específico a más general

// ✅ BIEN: de más específico a más general

if (nota >= 9) {       // 9-10
cout << "A" << endl;
} else if (nota >= 8) {  // 8-8.9
cout << "B" << endl;
} else if (nota >= 7) {  // 7-7.9
cout << "C" << endl;
} else if (nota >= 6) {  // 6-6.9
cout << "D" << endl;
} else {                // 0-5.9
cout << "F" << endl;

}

// ❌ MAL: orden invertido

if (nota >= 0) {       // Todas las notas positivas
cout << "F" << endl;  // ¡Todas imprimen F!
} else if (nota >= 6) {
cout << "D" << endl;

} // ... esto no funciona

Por qué: la primera condición que sea verdadera se ejecuta y las siguientes NO. Si pones la más general primero, las específicas nunca se evalúan.

El else final es tu red de seguridad

// ✅ Con else final: todo caso queda cubierto

if (nota >= 9) {
cout << "A" << endl;
} else if (nota >= 8) {
cout << "B" << endl;

} // ... etc

else {

cout << "Nota fuera de rango" << endl;  // Captura notas < 0 o > 10

}

Cuaderno físico (obligatorio)

convierte 3 algoritmos de cadenas de decisión anidadas (de los LAB 1.3, 1.4, 1.5) a la versión con `else if`. Mide la diferencia de líneas y legibilidad.

2.2.2 — El problema de la "pirámide del doom" y cómo evitarla

La pirámide del doom y cómo evitarla
La pirámide del doom y cómo evitarla

Qué es

La pirámide del doom (en inglés "arrow anti-pattern" o "deeply nested code") es cuando anidas tantos if que el código se va corriendo hacia la derecha:

if (condición1) {
if (condición2) {
if (condición3) {
if (condición4) {
if (condición5) {

// ... 4 espacios, 8, 12, 16, 20 ...

cout << "¡Por fin!" << endl;

}

}

}

}

}

Problemas:

  • Es difícil de leer.
  • Es difícil de mantener.
  • Es difícil de debuggear (¿en qué nivel estoy?).
  • Suele indicar que el código está mal diseñado.

4 técnicas para evitarla

  1. Usar `else if` en vez de anidar `if-else` (cuando los casos son excluyentes):
if (a) {

// ...

} else if (b) {

// ...

} else {

// ...

}

  1. Invertir la condición y hacer "early return" (salida temprana):

// ❌ Pirámide

void f() {

if (usuarioValido) {
if (tienePermisos) {
if (datosCorrectos) {

hacerAlgo();

}

}

}

}

// ✅ Sin pirámide

void f() {

if (!usuarioValido) return;
if (!tienePermisos) return;
if (!datosCorrectos) return;

hacerAlgo();

}

  1. Extraer a funciones:

// ❌ Pirámide

if (a) {
if (b) {
if (c) {

hacerX();

}

}

}

// ✅ Sin pirámide

if (a && b && c) {

hacerX();

}

  1. Usar la cláusula `default` en `switch` (lo veremos en 2.2.3): Para decisiones discretas con muchos casos, switch es más limpio que una cadena de if-else if.

La regla de los 3 niveles

Si tu código tiene más de 3 niveles de anidación de `if`, **es una señal de que hay que refactorizar**. Usa las 4 técnicas de arriba.
Cuaderno físico (obligatorio)

de tus programas del LAB 1.5 o 1.7, identifica alguno con más de 3 niveles de anidación. Refactorízalo usando una de las 4 técnicas. Mide la reducción de líneas y de niveles.

2.2.3 — La estructura switch/case: decisiones discretas

La estructura switch/case: decisiones discretas
La estructura switch/case: decisiones discretas

Qué es

La estructura switch/case es una forma especializada de decisión para cuando quieres comparar una variable contra múltiples valores discretos (enteros, caracteres, enumeraciones).

Aplica cuando:

  • La variable es un entero, un carácter o una enumeración (no string, no double).
  • Tienes 3 o más casos discretos a comparar.
  • Cada caso es un valor específico, no un rango.

Sintaxis

switch (expresión) {

case valor1:

// instrucciones si expresión == valor1

break;

case valor2:

// instrucciones si expresión == valor2

break;

case valor3:

// instrucciones si expresión == valor3

break;

default:

// instrucciones si ningún caso coincide

break;

}

Cómo funciona:

  1. Se evalúa la expresión UNA SOLA VEZ.
  2. Se compara con cada case en orden.
  3. Cuando hay coincidencia, se ejecutan las instrucciones de ese case.
  4. El break hace que se salga del switch. Si no hay `break`, se sigue ejecutando el siguiente `case` (fall-through).
  5. Si ningún case coincide, se ejecuta default (si existe).

Ejemplo: día de la semana

#include <iostream>
using namespace std;
int main() {

int dia;

cout << "Ingresa un número del 1 al 7: ";
cin >> dia;

switch (dia) {

case 1:

cout << "Lunes" << endl;

break;

case 2:

cout << "Martes" << endl;

break;

case 3:

cout << "Miércoles" << endl;

break;

case 4:

cout << "Jueves" << endl;

break;

case 5:

cout << "Viernes" << endl;

break;

case 6:

cout << "Sábado" << endl;

break;

case 7:

cout << "Domingo" << endl;

break;

default:

cout << "Número inválido. Debe ser del 1 al 7." << endl;

break;

}

return 0;

}

Comparación con `if-else if`: la versión con switch es 50% más corta y más fácil de leer cuando hay muchos casos.

Ejemplo: menú de calculadora

#include <iostream>
using namespace std;
int main() {

int opcion;

double a, b;

cout << "=== Calculadora Simple ===" << endl;
cout << "1. Sumar" << endl;
cout << "2. Restar" << endl;
cout << "3. Multiplicar" << endl;
cout << "4. Dividir" << endl;
cout << "Opción: ";
cin >> opcion;
cout << "Número 1: ";
cin >> a;
cout << "Número 2: ";
cin >> b;

switch (opcion) {

case 1:

cout << "Resultado: " << a + b << endl;

break;

case 2:

cout << "Resultado: " << a - b << endl;

break;

case 3:

cout << "Resultado: " << a * b << endl;

break;

case 4:

if (b != 0) {
cout << "Resultado: " << a / b << endl;
} else {
cout << "Error: división entre 0" << endl;

}

break;

default:

cout << "Opción inválida" << endl;

break;

}

return 0;

}

Diagrama de flujo clásico del switch/case (menú calculadora)

┌─────────────┐

│ INICIO │ ⬭

└──────┬──────┘

│

▼

╱───────────────╲

╱ Mostrar menú ╲ ▱

╲ y leer opción ╱

╲───────────────╱

│

▼

◆─────────────◆ ◇ (decisión múltiple)

╱╱╱╱╱╱╱╲╲╲╲╲╲╲

┌──────────┴──┴──┴──┴──┴──────────┐

│ opción es... │

▼ ▼ ▼ ▼

╱─────────╲ ╱──────╲ ╱─────────╲ ╱─────────╲

╱ ESCRIBIR ╲║ ESCRIBIR ╲║ ESCRIBIR ╲║ ¿b!=0? ╲

╲ "Suma: ╱║ "Resta: ╱║ "Mult: ╱║ ──── ╲

╲ a+b" ╱ ║ a-b" ╱ ║ a*b" ╱ ║ │ ╲

╲────────╱ ╲─────────╱ ╲─────────╱ ║Sí │ ╲ No

│ │ │ │ │ │

│ │ │ ▼ │ ▼

│ │ │ ╱───────╲ ╱─────────╲

│ │ │║"Div: ╲║ "Opción ╲

│ │ │║ a/b" ╱║ inválida"╱

│ │ │ ╲────────╱ ╲─────────╱

│ │ │ │ │

└────────────┴─────┬──────┴──────┴──────────┘

│

▼

┌─────────────┐

│ FIN │ ⬭

└─────────────┘

Sobre el diagrama: el `switch/case` se representa con un rombo de decisión múltiple del que salen 4+ flechas (una por cada `case`). En draw.io, esto se dibuja como un rombo grande con varias salidas etiquetadas (1, 2, 3, 4, default). Es la forma estándar de representar decisiones discretas con varios casos.

Cuaderno físico (obligatorio)

convierte el menú de calculadora a `if-else if`. Compara líneas y claridad. ¿Cuál es mejor para este caso? ¿Por qué? Dibuja ambas versiones en tu cuaderno (con la simbología clásica).

2.2.4 — El default y el break: las claves del switch correcto

El default y el break: claves del switch correcto
El default y el break: claves del switch correcto

El break: la pieza que casi nadie entiende al principio

Sin break, el switch NO termina cuando encuentra un caso. Sigue ejecutando los siguientes casos (esto se llama fall-through).

int x = 1;

switch (x) {

case 1:

cout << "Caso 1" << endl;

// SIN break: sigue al siguiente caso

case 2:

cout << "Caso 2" << endl;

break; // Aquí sí termina

case 3:

cout << "Caso 3" << endl;

break;

}

Salida:

Caso 1

Caso 2

El `break` es necesario al final de CADA caso, excepto cuando intencionalmente quieres fall-through (raro).

El default: el caso "ninguno de los anteriores"

switch (opcion) {

case 1: /* ... */ break;

case 2: /* ... */ break;

// ...

default:

cout << "Opción inválida" << endl;

break;

}

`default` es opcional pero MUY recomendado. Sin él, si la opción no coincide con ningún case, el programa simplemente no hace nada (sin error, sin mensaje). Con default, capturas el caso no esperado y muestras un mensaje útil.

El error "case sin break"

El error más común de switch:

// ❌ MAL: olvidaste el break en case 1

switch (opcion) {

case 1:

cout << "Sumar" << endl;

// Falta break aquí

case 2:

cout << "Restar" << endl;  // Se ejecuta también para opción 1

break;

// ...

}

Cómo evitarlo:

  1. Escribe el break INMEDIATAMENTE después de cada case, antes de las instrucciones.
  2. Usa la extensión de VS Code "C/C++" que resalta casos sin break.
  3. Compila con -Wall para que el compilador te avise: g++ -Wall main.cpp -o programa.

Cuándo SÍ quieres fall-through (raro pero existe)

A veces quieres que varios casos ejecuten el mismo código:

// Válido en C++: agrupar casos que ejecutan lo mismo

switch (dia) {

case 1: // lunes

case 2: // martes

case 3: // miércoles

case 4: // jueves

case 5: // viernes

cout << "Día laboral" << endl;

break;

case 6: // sábado

case 7: // domingo

cout << "Fin de semana" << endl;

break;

default:

cout << "Inválido" << endl;

break;

}

Esto es un patrón válido y útil. Los case sin break ni código ejecutan el mismo bloque que el siguiente.

Cuaderno físico (obligatorio)

el ejemplo de "día laboral vs fin de semana" usando `if-else` Y `switch`. ¿Cuál es más claro para este caso?

2.2.5 — switch vs if-else if: cuándo usar cada uno

switch vs if-else if: cuándo usar cada uno
switch vs if-else if: cuándo usar cada uno

La regla de decisión

¿La variable es un entero, carácter o enumeración?

├── NO → usa if-else if

└── SÍ

├── ¿Hay 3+ casos discretos?

│ ├── NO (1-2 casos) → if-else if es suficiente

│ └── SÍ → switch es más claro

└── ¿Cada caso es un valor específico (no un rango)?

├── NO (rangos: nota >= 7) → if-else if

└── SÍ (valores: 1, 2, 3, 4) → switch

Tabla comparativa

Ejemplos de cuándo usar cada uno

Usa `if-else if` cuando:

  • La variable es double (no se puede usar en switch).
  • La variable es string (en C++; Java sí permite String con Java 14+).
  • Los casos son rangos: nota >= 7, edad < 18.
  • Las comparaciones son complejas: edad >= 18 && tieneLicencia.

Usa `switch` cuando:

  • La variable es int, char, o un enum.
  • Los casos son valores específicos: 1, 2, 3, 4.
  • Hay 3+ casos.
  • Estás implementando un menú.

Ejemplo combinado

A veces necesitas ambos en el mismo programa:

// Menú con switch

switch (opcion) {

case 1:

// Login: usa if-else if para validar

if (usuario == "admin" && password == "12345") {
cout << "Acceso permitido" << endl;
} else if (intentos < 3) {
cout << "Contraseña incorrecta" << endl;
} else {
cout << "Cuenta bloqueada" << endl;

}

break;

case 2:

// Ver perfil: usa if-else para clasificar

if (edad < 18) {
cout << "Perfil de menor" << endl;
} else if (edad < 65) {
cout << "Perfil de adulto" << endl;
} else {
cout << "Perfil de adulto mayor" << endl;

}

break;

// ... más opciones

}

Cuaderno físico (obligatorio)

toma un programa tuyo del LAB 1.5 o 1.7 que tenga 4+ decisiones. Reescríbelo usando `switch` donde aplique y `if-else if` donde no. Mide la claridad.

2.2.6 — Menús interactivos profesionales con do-while + switch

Menús interactivos con do-while + switch
Menús interactivos con do-while + switch

El patrón fundamental de los programas interactivos

Casi cualquier programa de consola tiene este flujo:

  1. Mostrar menú de opciones
  2. Leer la opción del usuario
  3. Ejecutar la opción elegida
  4. Volver al paso 1
  5. Salir cuando el usuario elija "Salir"
Esto se implementa con un bucle do-while (que veremos en detalle en el Tema 2.5) que contiene un switch:
#include <iostream>
using namespace std;
int main() {

int opcion;

do {

// 1. Mostrar menú

cout << "\n=== Menú Principal ===" << endl;
cout << "1. Saludar" << endl;
cout << "2. Calcular suma" << endl;
cout << "3. Ver fecha" << endl;
cout << "4. Salir" << endl;
cout << "Opción: ";
cin >> opcion;

// 2. Procesar opción

switch (opcion) {

case 1:

cout << "¡Hola! ¿Cómo estás?" << endl;

break;

case 2: {

double a, b;

cout << "Número 1: ";
cin >> a;
cout << "Número 2: ";
cin >> b;
cout << "Suma: " << a + b << endl;

break;

}

case 3:

cout << "Hoy es un gran día para programar." << endl;

break;

case 4:

cout << "Saliendo..." << endl;

break;

default:

cout << "Opción inválida. Intente de nuevo." << endl;

break;

}

} while (opcion != 4);
cout << "Programa terminado." << endl;
return 0;

}

Cómo funciona:

  • El do-while repite el bloque al menos una vez.
  • Dentro, se muestra el menú, se lee la opción, y se procesa con switch.
  • El bucle se repite mientras la opción NO sea 4 (Salir).
  • Cuando el usuario elige 4, el bucle termina y se sale.

Los detalles que importan

  1. El menú debe ser claro:
  • Títulos con bordes o separadores.
  • Opciones numeradas.
  • Una opción explícita de "Salir" (por convención, la última).
  1. La validación de la opción:
  • Si el usuario escribe "5" cuando solo hay 1-4, el default lo captura.
  • Si el usuario escribe letras, cin entra en estado de error. Necesitas limpiarlo:
if (cin.fail()) {
cin.clear();  // Limpia el estado de error
cin.ignore(10000, '\n');  // Ignora el resto de la línea

opcion = 0; // Fuerza al default

}

  1. La función para cada opción (limpio): En lugar de meter todo en el case, llama a una función:

switch (opcion) {

case 1:

saludar();

break;

case 2:

calcularSuma();

break;

case 3:

verFecha();

break;

case 4:

cout << "Saliendo..." << endl;

break;

default:

cout << "Opción inválida" << endl;

break;

}

Esto lo veremos en detalle en el Tema 2.9 (Funciones). Por ahora, está bien que el código esté dentro del case.

  1. Las llaves en `case 2:`:

case 2: {

double a, b; // Variables locales a este case

// ...

break;

}

Si declaras variables dentro de un case, necesitas llaves {} para crear un bloque. Si no, el compilador da error.
Cuaderno físico (obligatorio)

diseña 3 menús diferentes para 3 problemas (calculadora, agenda, sistema de calificaciones). Para cada uno, escribe el pseudocódigo y luego tradúcelo a C++ con `do-while + switch`.

⚠️ Errores típicos — ❌ Errores típicos del razonamiento

Error 1: "Si tengo muchos casos, mejor uso switch aunque sean rangos"

Idea equivocada: "Tengo que clasificar 5 rangos de notas, mejor uso switch."

Realidad: switch SOLO funciona con valores discretos. Para rangos (nota >= 7), necesitas if-else if. No se puede hacer `case nota >= 7:` en C++. La única excepción son los range patterns de Rust o C# 9+.

Cómo evitarlo: si los casos son rangos, usa if-else if. Si son valores discretos, usa switch.

Error 2: "Olvidé un break pero el programa funciona, no importa"

Idea equivocada: "Mi switch funciona aunque le falten breaks en algunos casos."

Realidad: "funciona" en un caso de prueba no significa que funcione en todos. Si cambias los casos o agregas más, el fall-through va a causar bugs difíciles de encontrar.

Cómo evitarlo: SIEMPRE pon break al final de cada case. Si intencionalmente quieres fall-through, pon un comentario // fall-through intencional.

Error 3: "No necesito default en el switch"

Idea equivocada: "Si cubrí todos los casos válidos, el default es redundante."

Realidad: los casos válidos son los que TÚ conoces. El usuario puede meter opciones no esperadas (por error, por malicia, por descuido). El default captura esos casos.

Cómo evitarlo: siempre incluye default en TODOS tus switch. Es 1 línea de código y te salva de bugs difíciles.

Error 4: "El menú se ve bien, pero los nombres de las opciones son feos"

Idea equivocada: "Poner '1. Opción 1' es suficiente."

Realidad: un buen menú tiene opciones descriptivas ("1. Registrar nuevo usuario", no "1. Opción 1"). El usuario no sabe qué hace cada opción solo por el número.

Cómo evitarlo: escribe opciones que digan QUÉ HACE cada una, no solo un número. Si es un sistema de biblioteca: "1. Buscar libro por título", no "1. Buscar".

Error 5: "Mi programa termina cuando el usuario elige 4, pero si escribe otra cosa sigue"

Idea equivocada: "El do-while con opcion != 4 es suficiente."

Realidad: ¿qué pasa si el usuario escribe "5" o "abc"? El default lo captura y muestra "opción inválida", pero el bucle sigue. Eso es correcto. El problema es cuando el cin entra en estado de error y el bucle se vuelve infinito.
Cómo evitarlo: valida SIEMPRE la entrada antes de procesarla. Si cin.fail(), limpia el buffer y vuelve a pedir.

🤖 IA como copiloto — 🤖 AI Mission 2.2 — Menús con IA

Regla de los 3 minutos (obligatoria): primero intenta por tu cuenta.

Prompts sugeridos

Prompt 1 — Diseñar un menú:

"Estoy construyendo un sistema de gestión de biblioteca en C++. Dame la estructura de un menú principal con 5 opciones: alta de libro, baja de libro, búsqueda, listado, salir. Dame el pseudocódigo del menú, NO el código en C++. Máximo 100 palabras."

Prompt 2 — Convertir if-else a switch:

"Te voy a pegar una cadena de if-else if en C++ que creo que se puede convertir a switch. NO me lo conviertas. Solo dime: (1) ¿se puede convertir? (2) ¿por qué sí o por qué no? (3) qué casos NO se podrían convertir. Máximo 100 palabras."

Prompt 3 — Encontrar error en switch:

"Te pego un switch en C++ que se comporta raro: '[código]'. NO me lo corrijas. Solo dime: (1) qué hace línea por línea, (2) dónde puede estar el problema. Máximo 150 palabras."

Prompt 4 — Comparar menús:

"Te voy a pegar 2 versiones de un menú en C++ que deberían hacer lo mismo. NO me digas cuál es mejor. Solo dime: (1) qué hace cada una, (2) qué ventajas y desventajas tiene cada una. Máximo 150 palabras."

🧪 Laboratorio — 🧪 LAB 2.2 — 6 ejercicios de decisiones complejas

Tiempo total: 1 h 30 min | Entregable: 6 programas funcionando.

🛠️ Herramienta recomendada para los diagramas de flujo de este LAB: Para los ejercicios que pidan un diagrama de flujo, usa [draw.io (diagrams.net)](https://app.diagrams.net/) — herramienta gratis, sin registro, que funciona en el navegador. Tiene plantillas con la simbología ANSI/ISO lista (en `General → Flowchart`). Exporta tus diagramas como PNG e insértalos en tu cuaderno digital o entrégalos junto con el código. Otras opciones libres: - [Mermaid](https://mermaid.live/) — diagramas desde código Markdown. Ideal para Git. - [Excalidraw](https://excalidraw.com/) — estilo "dibujado a mano", muy intuitivo. - Dibujar a mano en tu cuaderno — siempre válido, especialmente para trazar el razonamiento.

Ejercicio 1 — Clasificador de notas completo (básico, 15 min)

Enunciado. Crea un programa que pida una nota (0-10) y la clasifique:

  • 9-10: A
  • 8-8.9: B
  • 7-7.9: C
  • 6-6.9: D
  • 0-5.9: F
  • Cualquier otro: "Nota inválida"

Usa la cadena if-else if-else. Hazlo en los 3 lenguajes.

Criterio de éxito: los 6 casos (5 letras + inválido) funcionan.

Rúbrica (10 pts): 3 pts por versión + 1 pt por el caso inválido.

Ejercicio 2 — Calculadora con menú (básico, 20 min)

Enunciado. Construye una calculadora que tenga un menú con 5 opciones: sumar, restar, multiplicar, dividir, salir. Usa do-while + switch. Pide los 2 números solo si la opción es 1-4. Si elige división y el divisor es 0, muestra error.

Criterio de éxito: el menú se repite hasta elegir "Salir", y la división entre 0 se valida.

Rúbrica (10 pts): menú (3 pts) + 4 operaciones correctas (4 pts) + validación de división (2 pts) + salida limpia (1 pt).

Ejercicio 3 — Estación del año (intermedio, 20 min)

Enunciado. Crea un programa que pida un número de mes (1-12) y diga la estación del año (en el hemisferio norte, usando switch):

  • 12, 1, 2: Invierno
  • 3, 4, 5: Primavera
  • 6, 7, 8: Verano
  • 9, 10, 11: Otoño
  • Otro: "Mes inválido"

Criterio de éxito: los 4 rangos de meses se asignan correctamente usando fall-through.

Rúbrica (10 pts): 4 estaciones correctas (8 pts) + caso inválido (2 pts).

Ejercicio 4 — Cajero automático (intermedio, 30 min)

Enunciado. Construye un cajero automático con menú: consultar saldo, depositar, retirar, salir. El saldo inicial es $5,000.

  • Consultar: muestra el saldo.
  • Depositar: pide monto (positivo), suma al saldo.
  • Retirar: pide monto (positivo y menor o igual al saldo), resta al saldo. Si no hay suficiente, muestra error.
  • Salir: termina.

Usa do-while + switch. Si el usuario elige una opción inválida, muestra "Opción inválida".

Criterio de éxito: el cajero maneja correctamente las 4 opciones, valida montos inválidos y saldo insuficiente.

Rúbrica (10 pts): menú (2 pts) + 4 opciones funcionales (4 pts) + validaciones (3 pts) + saldo final correcto (1 pt).

Ejercicio 5 — Sistema de calificaciones con switch (avanzado, 30 min)

Enunciado. Construye un sistema que pida 5 calificaciones y luego muestre un menú con opciones:

  1. Mostrar todas las calificaciones.
  2. Calcular y mostrar el promedio.
  3. Mostrar la calificación más alta y la más baja.
  4. Mostrar cuántos aprobados (>= 7) y reprobados (< 7).
  5. Salir.

Usa do-while + switch. Cada opción debe ser un bloque de código que use la información ya capturada.

Criterio de éxito: el sistema funciona como una mini-aplicación de consola.

Rúbrica (10 pts): menú (2 pts) + 4 opciones (6 pts) + datos consistentes (2 pts).

Ejercicio 6 — Mini sistema de ventas (avanzado, 30 min)

Enunciado. Construye un sistema de ventas con menú:

  1. Registrar producto (nombre, precio, stock).
  2. Vender producto (pide nombre, descuenta del stock, suma a ventas totales).
  3. Ver inventario (muestra todos los productos).
  4. Ver total de ventas.
  5. Salir.

Como aún no usamos arreglos, registra solo UN producto (variables simples). El sistema debe manejar el caso de que ya hay un producto registrado y no se puede registrar otro.

Criterio de éxito: el sistema maneja los 5 casos correctamente con validaciones.

Rúbrica (10 pts): estructura de datos (2 pts) + 4 opciones funcionales (4 pts) + validaciones (2 pts) + formato de salida (2 pts).

Ejercicio bonus — Conversor de unidades con menú (opcional, 30 min)

Enunciado. Construye un conversor de unidades con menú que tenga:

  1. Kilómetros a millas
  2. Celsius a Fahrenheit
  3. Kilogramos a libras
  4. Salir

Cada opción pide el dato y muestra la conversión. Usa do-while + switch + funciones (las funciones las verás en el Tema 2.9, pero intenta definirlas tú mismo por ahora).

Criterio de éxito: las 3 conversiones son correctas y el menú se repite.

Rúbrica bonus (5 pts): 3 conversiones correctas (3 pts) + menú (1 pt) + uso de funciones (1 pt).

🎯 Cierre del tema

Lo que aprendiste hoy:

  • La cadena if-else if-else para decisiones con 3+ caminos.
  • La "pirámide del doom" y 4 técnicas para evitarla.
  • La estructura switch/case para valores discretos.
  • El default y el break: las claves del switch correcto.
  • Cuándo usar switch vs if-else if.
  • El patrón do-while + switch para menús interactivos.

Lo que sigue: en el Tema 2.3 — Operadores Lógicos y Tablas de Verdad (6h), vas a profundizar en &&, || y !. Aunque ya los usaste en el Tema 2.1, aquí vas a dominar las tablas de verdad, las propiedades (conmutativa, asociativa, De Morgan), y vas a aprender a simplificar condiciones complejas para hacerlas más legibles.

Antes de seguir, asegúrate de tener en tu cuaderno:

  • [ ] 6 programas del LAB 2.2 funcionando.
  • [ ] Tabla comparativa de switch en C++/Java/Python.
  • [ ] Pseudocódigo de 2 menús interactivos propios.
  • [ ] Glosario con: if-else if-else, pirámide del doom, switch, case, break, default, fall-through, early return.

XP obtenida al completar este tema: 100 base + 30 por LAB (6 ejercicios) + 20 por Quest = 150 XP. Insignia desbloqueada al cerrar el capítulo: Branch Master (parcial).

*"Un menú con `switch` no es solo código: es la puerta de entrada a un programa interactivo. El usuario decide qué hacer, y tu código responde."* — De la introducción de este manual.

Fin del Tema 2.2

📝 Quest · Cuestionario — 📝 Quest — Reactivos para autoevaluación

Las siguientes preguntas te sirven para autoevaluarte después de leer el tema. Responde en tu cuaderno o mentalmente, y luego revisa las Respuestas modelo (disponibles en libre acceso, sin iniciar sesión).

Sección A · Opción múltiple

Elige la opción correcta (A, B, C o D). Las respuestas están en la sección Respuestas modelo.

  1. ¿Para qué sirve switch?
    • Repetir
    • Seleccionar entre múltiples caminos según un valor
    • Definir función
    • Compilar
  2. ¿Qué hace break en un switch?
    • Termina el programa
    • Sale del switch después de un case
    • Salta al siguiente case
    • No tiene efecto
  3. ¿Qué pasa si olvidas break en un case?
    • Error
    • Fall-through: ejecuta los cases siguientes
    • Termina el switch
    • El case se ignora
  4. switch se puede usar con:
    • Solo enteros
    • En C++: enteros, char, enum; en JS/PHP también string
    • Solo strings
    • Solo floats
  5. ¿Cuál es la sintaxis correcta de switch?
    • switch (x) { case 1: ... break; }
    • switch x case 1: ...
    • switch { x case 1 }
    • switch (x) -> case 1
  6. ¿Cuándo es mejor if-else que switch?
    • Siempre
    • Para rangos o condiciones complejas
    • Solo con strings
    • Nunca
  7. ¿switch puede tener un case default?
    • No
    • Sí, es el caso por defecto si no hay match
    • Solo en Java
    • Solo en C++
  8. ¿Qué pasa si ningún case coincide y no hay default?
    • Error
    • No se ejecuta ningún bloque
    • Se ejecuta el último case
    • Se repite el switch
  9. switch con float: ¿es válido en C++?
    • Sí
    • No (en C++ clásico)
    • Solo en C++20
    • Solo con double
  10. ¿Cuántos cases puede tener un switch?
    • Máximo 10
    • Sin límite práctico
    • Máximo 255
    • Solo 1

Sección B · Preguntas abiertas

Desarrolla tu respuesta en al menos 3 líneas. Compara con la respuesta modelo después de escribir.

  1. ¿Cuándo es preferible switch sobre if-else? Da un ejemplo donde switch es claramente mejor.
    → Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
  2. Explica qué es "fall-through" en switch y por qué a veces se usa intencionalmente.
    → Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
  3. Diseña un switch que imprima el número de días de un mes (considerando año no bisiesto).
    → Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…

🟢 Cuando termines, revisa las Respuestas modelo y compáralas con las tuyas. La mejor forma de aprender es discutir cada respuesta contigo mismo o con un compañero.

← Volver a temas del capítulo 📚 Ver todos los temas 🔑 Inicia sesión para hacer el Test