C++
Control de flujo: if, for, while y switch
Cómo hacer que un programa tome decisiones y repita trabajo con if/else, bucles y switch.
De dónde venimos
En Variables, tipos de datos y operadores apareció una línea curiosa:
std::cout << "¿Aprobado? " << (promedio >= 4.0) << "\n";Esa comparación produce un bool, pero el programa lo único que hacía era imprimirlo. Un bool sirve para mucho más: es el material con el que se construyen las decisiones. Esta página usa exactamente esos operadores de comparación (==, <, >=) y lógicos (&&, ||, !) que ya conoces, y les da el uso para el que existen: cambiar qué líneas se ejecutan y cuántas veces.
Los ejemplos siguen usando std::cin y std::cout tal como se explicaron en la página de la Standard Library, así que no hay nada nuevo en la entrada/salida: lo nuevo es solo la estructura alrededor.
Bloques y ámbito
Antes de las estructuras en sí, un detalle que las atraviesa todas: las llaves { } delimitan un bloque, y una variable declarada dentro de un bloque solo existe dentro de ese bloque. A eso se le llama ámbito (scope).
{
int temporal = 5;
// aquí temporal existe
}
// aquí temporal ya NO existe: usarla es error de compilaciónEsto no es un tecnicismo: es la base del modelo de recursos de C++. Cuando una variable sale de su ámbito, C++ libera automáticamente lo que ocupaba. Ese comportamiento tiene nombre (RAII) y es tema de una sección más avanzada, pero conviene que la idea te suene desde ya.
Tomar decisiones con if
if ejecuta un bloque solo si una condición es verdadera. else if encadena condiciones alternativas y else cubre todo lo demás.
#include <iostream>
int main() {
double nota = 0.0;
std::cout << "Ingresa tu nota (1.0 a 7.0): ";
std::cin >> nota;
if (nota < 1.0 || nota > 7.0) {
std::cout << "Nota fuera de rango.\n";
} else if (nota >= 6.0) {
std::cout << "Excelente.\n";
} else if (nota >= 4.0) {
std::cout << "Aprobado.\n";
} else {
std::cout << "Reprobado.\n";
}
return 0;
}g++ -std=c++17 -Wall -o notas notas.cpp
./notasIngresa tu nota (1.0 a 7.0): 6.5
Excelente.El orden de las ramas importa: se evalúan de arriba a abajo y la primera que sea verdadera gana; el resto ni se mira. Por eso >= 6.0 va antes que >= 4.0: al revés, un 6.5 entraría por “Aprobado” y nunca llegaría a “Excelente”.
Las llaves son opcionales cuando el cuerpo del if es una sola línea, pero omitirlas es una fuente conocida de bugs: si más adelante alguien agrega una segunda línea creyendo que está dentro del if, esa línea se ejecutará siempre. Este error tiene incluso un nombre propio en la historia del software (el bug goto fail de Apple en 2014, que rompió la validación de certificados SSL). Pon siempre las llaves, aunque sobren.
if con condiciones combinadas
&& exige que ambas condiciones se cumplan, || que se cumpla al menos una:
if (edad >= 18 && tieneCarnet) {
std::cout << "Puede conducir\n";
}C++ evalúa estos operadores en cortocircuito: si el lado izquierdo de && ya es falso, el derecho ni se evalúa. Esto no es solo una optimización, es una garantía del lenguaje que se usa a propósito para escribir comprobaciones seguras, como verificar que un puntero no sea nulo antes de usarlo — algo que verás en Punteros.
El bucle for
for repite un bloque un número conocido de veces. Sus tres partes, separadas por ;, son: inicialización, condición de continuación e incremento.
#include <iostream>
int main() {
for (int i = 1; i <= 10; ++i) {
if (i % 2 == 0) { // el operador % de la página anterior
std::cout << i << " ";
}
}
std::cout << "\n";
return 0;
}2 4 6 8 10La variable i se declara dentro del for, así que su ámbito es el bucle: fuera de él no existe. Eso es intencional y deseable — evita que un contador temporal contamine el resto de la función.
Este for “clásico” con contador es el que necesitas entender primero porque es el que verás en código C, en ejemplos antiguos y al recorrer arrays, pero no es lo más idiomático en C++ moderno. Para recorrer una colección completa, hoy se prefiere el for basado en rango (for (int n : numeros)), que no usa índices y elimina de raíz los errores de “me pasé por uno”. Lo verás en acción en la página de arrays.
El bucle while y do-while
while repite mientras la condición sea verdadera, y a diferencia de for no impone un contador: se usa cuando no sabes de antemano cuántas vueltas harás.
#include <iostream>
int main() {
int edad = -1;
while (edad < 0 || edad > 120) {
std::cout << "Ingresa una edad válida (0-120): ";
std::cin >> edad;
}
std::cout << "Edad registrada: " << edad << "\n";
return 0;
}do { ... } while (condicion); es la variante que ejecuta el cuerpo al menos una vez antes de comprobar la condición. Es útil justo para casos como el anterior, donde la primera pregunta siempre hay que hacerla, y evita tener que inicializar edad con un valor falso como -1.
El error clásico de while es el bucle infinito: si nada dentro del cuerpo cambia la variable de la condición, el programa se cuelga para siempre. Antes de escribir el cuerpo, pregúntate: “¿qué línea de aquí adentro hará que esta condición llegue a ser falsa?”. Si no hay respuesta, ya tienes el bug. (Si te pasa mientras pruebas, corta el programa con Ctrl+C.)
break y continue
breaksale inmediatamente del bucle.continuesalta el resto del cuerpo y pasa a la siguiente vuelta.
Ambos funcionan en for, while y do-while. Úsalos con moderación: un bucle con cuatro break repartidos es difícil de seguir.
Elegir entre muchas opciones con switch
switch compara una expresión entera o de tipo carácter contra varios valores constantes. Es más legible que una cadena larga de else if cuando todas las comparaciones son de igualdad contra el mismo valor.
#include <iostream>
int main() {
std::cout << "1) Saludar 2) Despedir 3) Salir\n";
std::cout << "Opción: ";
int opcion = 0;
std::cin >> opcion;
switch (opcion) {
case 1:
std::cout << "¡Hola!\n";
break;
case 2:
std::cout << "¡Adiós!\n";
break;
case 3:
std::cout << "Saliendo...\n";
break;
default:
std::cout << "Opción no reconocida.\n";
break;
}
return 0;
}g++ -std=c++17 -Wall -o menu menu.cpp
./menu1) Saludar 2) Despedir 3) Salir
Opción: 2
¡Adiós!
Si olvidas el break al final de un case, la ejecución continúa hacia el siguiente case en lugar de salir del switch. Esto se llama fall-through y es la trampa número uno de switch. A veces se hace a propósito (para que varios case compartan el mismo código), y en ese caso conviene dejarlo escrito con un comentario // fall-through o, desde C++17, con el atributo [[fallthrough]];, para que quede claro que no es un olvido.
switch no funciona con std::string ni con double: solo acepta tipos enteros, char y enumeraciones. Para comparar cadenas de texto, necesitas if/else if con ==. Es una limitación heredada de C que sorprende a quien viene de Java o C#, donde el switch con strings sí es posible.
Siguiente paso
Ya puedes escribir programas que deciden y repiten, pero todo el código sigue viviendo dentro de un único main() que crece sin control. La forma de partirlo en piezas reutilizables con nombre son las funciones: continúa con Funciones.