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){case1: cout <<'1';// imprime "1",case2: cout <<'2';// luego imprime "2"}
switch(1){case1: cout <<'1';// imprime "1"break;// y abandona switchcase2: 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(){constint i =2;switch(i){case1:std::cout<<"1";case2:std::cout<<"2";// ejecución comienza en esta etiqueta casecase3:std::cout<<"3";[[fallthrough]];// atributo de C++17 para ignorarcase4:// el aviso de caídacase5:std::cout<<"45";break;// termina ejecución de instrucciones subsequentescase6:std::cout<<"6";} std::cout<<'\n'; switch(i){case4:std::cout<<"a";default:std::cout<<"d";// no hay expresiones_constantes aplicables// por lo tanto se ejecuta default} std::cout<<'\n'; switch(i){case4: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 incluyeenum 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ónstruct 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 compuestaswitch(0)std::cout<<"esto no hace nada\n"; // las etiquetas tampoco requieren una instrucción compuestaswitch(int n =1)case0:case1: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 |