Espacios de nombres
Variantes
Acciones

Instrucción switch

De cppreference.com
< cpp‎ | language

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
(desde C++23)
Ten en cuenta que cualquier instrucción-de-inicialización debe terminar con un punto y coma ;, la razón por la cual frecuentemente se describe informalmente como una expresión o una declaración seguida por un punto y coma.
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)caseexpresió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 case sin break) a menos que el atributo atributo[[fallthrough]] aparezca inmediatamente antes de la etiqueta case para indicar que la caída es intencionada.

Si se utiliza la instrucción-de-inicialización, la instrucción switch es equivalente a

{
instrucción_de_inicialización
switch(condición)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:

switch(1){case1:int x =0;// inicializaciónstd::cout<< x <<'\n';break;default:// error de compilación: salto a default: // entraría al ámbito de 'x' sin inicializarlastd::cout<<"default\n";break;}
switch(1){case1:{int x =0;std::cout<< x <<'\n';break;}// aquí termina el ámbito de 'x'default:std::cout<<"default\n";// no hay errorbreak;}

[editar]Palabras clave

switch, case, default

[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++
close