Instrucción switch
Transfiere control a una de varias instrucciones, dependiendo del valor de una condición.
Contenido |
[editar] Sintaxis
atrib(opcional) switch ( instrucción-de-inicialización(opcional) condición ) instrucción
|
|||||||||
atrib(desde C++11) | - | Cualquier número de atributos | ||
instrucción- de-inicialización |
- | (desde C++17) O bien
| ||
condición | - | Cualquier expresión de tipo entero o enumeración, o de un tipo de clase contextualmente implícitamente convertible a un tipo entero o enumeración, o una declaración de una variable simple no array de tal tipo con un inicializador con llaves o el signo igual. | ||
instrucción | - | Cualquier instrucción (típicamente una instrucción compuesta). Las etiquetas case: y default: se permiten en la instrucción, y la instrucción break; tiene un significado especial.
|
atrib(opcional) case expresión_constante : instrucción
|
(1) | ||||||||
atrib(opcional) default : instrucción
|
(2) | ||||||||
expresión_constante | - | Una expresión constante del mismo tipo que el tipo de la condición después de las conversiones y promociones enteras. |
[editar] Explicación
El cuerpo de una instrucción switch
puede tener un número arbitrario de etiquetas case:
, siempre y cuando los valores de todas las expresiones_constantes sean únicas (después de conversiones o promociones). A lo sumo, puede estar presente una etiqueta default:
(aunque las etiquetas switch
anidadas pueden usar sus propias etiquetas default:
o tener etiquetas case:
cuyas constantes son idénticas a las utilizadas en la instrucción switch
circundante).
Si la condición se evalúa al valor que es igual al valor de una de las expresiones_constantes, entonces el control se transfiere a la instrucción que está etiquetada con esa expresión_constante.
Si la condición se evalúa al valor que no corresponde con ninguna de las etiquetas case:
, y está presente la etiqueta default:
, el control se transfiere a la instrucción etiquetada con la etiqueta default:
.
Si la condición se evalúa a un valor que no corresponde con ninguna de las etiquetas case:
, y no está presente la etiqueta default:
, entonces no se ejecuta ninguna instrucción del cuerpo del switch.
La instrucción break, cuando se encuentra en la instrucción sale de la instrucción switch
:
switch(1) { case 1 : cout << '1'; // imprime "1", case 2 : cout << '2'; // luego imprime "2" }
switch(1) { case 1 : cout << '1'; // imprime "1" break; // y abandona switch case 2 : cout << '2'; break; }
Los compiladores pueden emitir advertencias de caída (fallthrough) (al alcanzar la siguiente etiqueta Si se utiliza la instrucción-de-inicialización, la instrucción
Excepto que los nombres declarados por la instrucción-de-inicialización (si la instrucción-de-inicialización es una declaración) y los nombres declarados por la condición (si la condición es una declaración) se encuentran en el mismo ámbito, el cual también es el ámbito de la instrucción. |
(desde C++17) |
Como la transferencia de control no se permite que entre al ámbito de una variable, si se encuentra una instrucción de declaración dentro de la instrucción, tiene que ponerse dentro de un ámbito en su propia instrucción compuesta:
[editar] Palabras clave
[editar] Ejemplo
El siguiente código muestra varios usos de la instrucción switch
:
#include <iostream> int main() { const int i = 2; switch (i) { case 1: std::cout << "1"; case 2: std::cout << "2"; // ejecución comienza en esta etiqueta case case 3: std::cout << "3"; [[fallthrough]]; // atributo de C++17 para ignorar case 4: // el aviso de caída case 5: std::cout << "45"; break; // termina ejecución de instrucciones subsequentes case 6: std::cout << "6"; } std::cout << '\n'; switch (i) { case 4: std::cout << "a"; default: std::cout << "d"; // no hay expresiones_constantes aplicables // por lo tanto se ejecuta default } std::cout << '\n'; switch (i) { case 4: std::cout << "a"; // no se ejecuta nada } // cuando se usan enumeraciones en una instrucción switch, algunos compiladores // emiten advertencias si uno de los enumerados no se incluye enum color {ROJO, VERDE, AZUL}; switch(ROJO) { case ROJO: std::cout << "rojo\n"; break; case VERDE: std::cout << "verde\n"; break; case AZUL: std::cout << "azul\n"; break; } // La sintaxis de la instrucción-de-inicialización de C++17 puede ser útil cuando // no hay una conversión implícita a un tipo entero o de enumeración struct Dispositivo { enum { REPOSO, LISTO, MAL } estado_{}; /*...*/ auto estado() const { return estado_; } }; switch (auto disp = Dispositivo{}; disp.estado()) { case Dispositivo::REPOSO: /*...*/ break; case Dispositivo::LISTO: /*...*/ break; case Dispositivo::MAL: /*...*/ break; } // ejemplos patológicos // la instrucción no tiene que ser una instrucción compuesta switch(0) std::cout << "esto no hace nada\n"; // las etiquetas tampoco requieren una instrucción compuesta switch(int n = 1) case 0: case 1: std::cout << n << '\n'; // Dispositivo de Duff: https://es.wikipedia.org/wiki/Dispositivo_de_Duff // Más completa en inglés: https://en.wikipedia.org/wiki/Duff }
Salida:
2345 d rojo 1
[editar] Véase también
Loop unrolling using Duff's Device | |
Duff's device can be used to implement coroutines in C/C++ | |
Documentación de C para switch
|