Instrucción switch (C++)

Permite la selección entre varias secciones de código, dependiendo del valor de una expresión entera.

Sintaxis

selection-statement:
switch(init-statementoptC++17condition)statement

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator brace-or-equal-initializer

labeled-statement:
case constant-expression : statement
default : statement

Comentarios

Una instrucción switch hace que el control se transfiera a una instrucción labeled-statement en el cuerpo de la instrucción, en función del valor de condition .

condition debe tener un tipo entero o ser de un tipo de clase que tiene una conversión no ambigua a un tipo entero. La promoción integral tiene lugar como se describe en Conversiones estándar.

El cuerpo de la instrucción switch consta de una serie de etiquetas case y una etiqueta optional default. labeled-statement es una de estas etiquetas y las instrucciones que siguen. Las instrucciones con etiquetas no son requisitos sintácticos, pero la instrucción switch no tiene sentido sin ellas. No puede haber dos valores constant-expression en las instrucciones case que se evalúen en el mismo valor. La etiqueta default puede aparecer solo una vez. La instrucción default se coloca a menudo al final, pero puede aparecer en cualquier parte del cuerpo de la instrucción switch. Una etiqueta case o default solo puede aparecer en una instrucción switch .

El elemento constant-expression de cada etiqueta case se convierte en un valor constante que tiene el mismo tipo que condition. Después, se compara con condition para ver si son iguales. El control pasa a la primera instrucción después del valor constant-expression de case que coincida con el valor de condition. El comportamiento resultante se muestra en la siguiente tabla.

Comportamiento de la instrucción switch

Condición Acción
El valor convertido coincide con el de la expresión de control promovida. El control se transfiere a la instrucción que sigue a esa etiqueta.
Ninguna de las constantes coincide con las constantes de las etiquetas case; hay una etiqueta default. El control se transfiere a la etiqueta default.
Ninguna de las constantes coincide con las constantes de las etiquetas case; no hay una etiqueta default. El control se transfiere a la instrucción situada detrás de la instrucción switch.

Si se encuentra una expresión coincidente, la ejecución puede continuar por etiquetas case o default posteriores. La instrucción break se usa para detener la ejecución y transferir el control a la instrucción situada detrás de la instrucción switch. Sin una instrucción break, se ejecutan todas las instrucciones que hay desde la etiqueta case coincidente hasta el final de la instrucción switch, incluida la etiqueta default. Por ejemplo:

// switch_statement1.cpp
#include <stdio.h>

int main() {
   const char *buffer = "Any character stream";
   int uppercase_A, lowercase_a, other;
   char c;
   uppercase_A = lowercase_a = other = 0;

   while ( c = *buffer++ )   // Walks buffer until NULL
   {
      switch ( c )
      {
         case 'A':
            uppercase_A++;
            break;
         case 'a':
            lowercase_a++;
            break;
         default:
            other++;
      }
   }
   printf_s( "\nUppercase A: %d\nLowercase a: %d\nTotal: %d\n",
      uppercase_A, lowercase_a, (uppercase_A + lowercase_a + other) );
}

En el ejemplo anterior, uppercase_A se incrementa si c es una mayúsculacase'A'. La instrucción break detrás de uppercase_A++ finaliza la ejecución del cuerpo de la instrucción switch y el control pasa al bucle while. Sin la instrucción break, la ejecución pasaría a la siguiente instrucción con etiqueta, de modo que lowercase_a y other también se incrementarían. La instrucción break para case 'a' tiene un propósito similar. Si c es una minúscula case'a', lowercase_a se incrementa y la break instrucción finaliza switch el cuerpo de la instrucción. Si c no es 'a' ni 'A', se ejecuta la instrucción default.

Visual Studio 2017 y versiones posteriores (disponible en el modo /std:c++17 y versiones posteriores): el atributo [[fallthrough]] se especifica en el estándar de C++17. Puede usarse en una instrucción switch. Es una sugerencia para el compilador (o para cualquier persona que lea el código) de que el comportamiento de paso explícito es intencionado. Actualmente, el compilador de Microsoft C++ no advierte sobre el comportamiento de paso explícito, por lo que este atributo no tiene ningún efecto sobre el comportamiento del compilador. En el ejemplo, el atributo se aplica a una instrucción vacía dentro de la instrucción etiquetada sin terminar. En otras palabras, el punto y coma es necesario.

int main()
{
    int n = 5;
    switch (n)
    {

    case 1:
        a();
        break;
    case 2:
        b();
        d();
        [[fallthrough]]; // I meant to do this!
    case 3:
        c();
        break;
    default:
        d();
        break;
    }

    return 0;
}

Visual Studio 2017, versión 15.3 y posteriores (disponible en el modo /std:c++17 y posteriores): una instrucción switch puede tener una cláusula init-statement, que termina con un punto y coma. Introduce e inicializa una variable cuyo ámbito está limitado al bloque de la instrucción switch:

    switch (Gadget gadget(args); auto s = gadget.get_status())
    {
    case status::good:
        gadget.zip();
        break;
    case status::bad:
        throw BadGadget();
    };

Un bloque interno de una instrucción switch puede contener definiciones con inicializadores siempre que sean accesibles, es decir, siempre que las rutas de ejecución posibles no las omitan. Los nombres proporcionados mediante estas declaraciones tienen ámbito local. Por ejemplo:

// switch_statement2.cpp
// C2360 expected
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    switch( tolower( *argv[1] ) )
    {
        // Error. Unreachable declaration.
        char szChEntered[] = "Character entered was: ";

    case 'a' :
        {
        // Declaration of szChEntered OK. Local scope.
        char szChEntered[] = "Character entered was: ";
        cout << szChEntered << "a\n";
        }
        break;

    case 'b' :
        // Value of szChEntered undefined.
        cout << szChEntered << "b\n";
        break;

    default:
        // Value of szChEntered undefined.
        cout << szChEntered << "neither a nor b\n";
        break;
    }
}

Una instrucción switch puede estar anidada. Cuando está anidada, las etiquetas case o default se asocian con la instrucción switch más cercana que las contenga.

Comportamiento específico de Microsoft

Microsoft C++ no limita el número de valores case de una instrucción switch. El número solo está limitado por la memoria disponible.

Consulte también

Instrucciones de selección
Palabras clave