Menu

Sentencia switch en C++: casos, fall-through y break

La sentencia switch de C++ explicada: etiquetas case, break y fall-through, la rama default, agrupar casos, hacer switch sobre enums y los problemas con las declaraciones dentro de los casos.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Para qué sirve switch

Un switch compara un valor contra una lista de opciones fijas y ejecuta la rama que coincide. Cuando te encuentras escribiendo una larga cadena de if/else if que sigue comprobando la misma variable contra distintas constantes, un switch expresa esa intención con más claridad, y a menudo compila a una tabla de saltos más rápida.

Solo hace comprobaciones de igualdad contra constantes en tiempo de compilación sobre un valor de tipo entero. No puede comprobar rangos, comparar cadenas ni combinar condiciones. Para cualquiera de esos casos, quédate con if/else.

El switch básico

Le das a switch un valor y luego enumeras etiquetas case para los valores que te importan. Cada rama termina con break:

El valor 3 coincide con case 3:, así que se imprime "Wednesday" y break salta fuera del switch. La rama default es el caso general: se ejecuta cuando ningún case coincide. Es opcional, pero inclúyela a menos que estés seguro de que todos los valores están contemplados.

Fíjate en que las etiquetas case son constantes sueltas seguidas de dos puntos, no condiciones. Escribes case 3:, nunca case day == 3:.

break y fall-through

Este es el problema más importante de switch en C++. Después de que un case coincide, la ejecución no se detiene en el siguiente case: sigue corriendo de largo hasta encontrar un break o la llave de cierre. Mira lo que ocurre cuando faltan las sentencias break:

Podrías esperar solo "one". En cambio se imprimen las cuatro líneas: al coincidir con case 1: se entra al switch ahí y luego se cae a través de todas las etiquetas que hay debajo. Añade un break; después de cada rama y obtendrás la única línea que querías. Olvidar un break es la fuente clásica de los errores del tipo "¿por qué mi switch ejecuta demasiado código?".

Fall-through intencional para agrupar casos

El fall-through no siempre es un error: es la forma idiomática de hacer que varios casos compartan un mismo cuerpo. Deja los casos vacíos (sin sentencias, sin break) y todos fluyen al siguiente bloque:

'A', 'B' y 'C' aterrizan todos en la misma línea "Pass" porque los dos primeros casos están vacíos y caen a través hacia el tercero. Esto es limpio e intencionado. Cuando quieres caer a través después de ejecutar algo de código, documéntalo con un comentario, o en C++17 y posteriores, con el atributo [[fallthrough]];, que le dice al compilador "sí, esto fue a propósito" y silencia las advertencias de fall-through.

switch sobre enums

switch combina de forma natural con los enums, ya que un enum es exactamente "uno de un conjunto fijo de valores". Los compiladores también pueden advertirte si olvidas tratar uno de los enumeradores:

Con un enum class con alcance debes calificar cada etiqueta (Direction::East). Como todos los enumeradores están cubiertos, no hace falta default, y muchos compiladores te advertirán si más adelante añades una quinta dirección y olvidas añadir su caso. Esa ayuda del compilador es una gran razón para preferir switch sobre las cadenas de if/else con enums.

Un problema: declaraciones dentro de un case

No puedes declarar una variable con un inicializador en un case y que sea visible en los demás casos sin darle su propio alcance. Este es un error de compilación común:

switch (x) {
    case 1:
        int n = 10;   // error: el salto a case 2 omite esta inicialización
        cout << n;
        break;
    case 2:
        cout << "two";
        break;
}

El compilador lo rechaza porque caer dentro de case 2: saltaría por encima de la inicialización de n mientras n sigue en alcance. La solución es envolver el cuerpo del case en sus propias llaves, dándole a la variable un bloque propio:

Siempre que un case necesite su propia variable local, dale llaves. Además evita que la variable se filtre a los casos de abajo.

Siguiente: bucle for

switch e if permiten que tu programa elija qué código ejecutar una vez. Pero mucho trabajo implica hacer lo mismo muchas veces: contar, recorrer una lista, repetir hasta que una condición cambie. El bucle for es el caballo de batalla para eso, y es la siguiente página.

Preguntas frecuentes

¿Cuándo debería usar switch en lugar de if-else en C++?

Usa switch cuando comparas un único valor de tipo entero contra muchas opciones fijas y constantes, como una opción de menú, un número de día o un enum. Se lee con más claridad que una larga escalera de if/else if y permite que el compilador optimice el salto. Quédate con if/else cuando tus condiciones involucran rangos (x > 10), valores de coma flotante, cadenas o varias variables: switch no puede hacer nada de eso.

¿Por qué necesito break en una sentencia switch de C++?

Una vez que un case coincide, C++ sigue ejecutando los casos siguientes hasta encontrar un break o el final del switch. Esto se llama fall-through. break lo detiene. Olvidar el break es un error clásico: coincides con case 1: y por accidente también ejecutas el código de case 2, case 3 y el default.

¿Sobre qué tipos se puede hacer switch en C++?

Solo tipos integrales o de enumeración: int, char, short, long, bool, enum con o sin alcance, y cualquier cosa que se convierta a uno de ellos. No puedes hacer switch sobre un double, float o std::string: para eso usa if/else. Cada etiqueta case debe ser una constante en tiempo de compilación.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR