Freigeben über


switch-Anweisung (C++)

Ermöglicht die Auswahl von mehreren Codeabschnitten, abhängig vom Wert eines ganzzahligen Ausdrucks.

Syntax

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

Hinweise

Eine switch -Anweisung bewirkt, dass die Steuerung abhängig vom Wert auf eine conditionlabeled-statement im Anweisungstext übertragen wird.

condition muss einen Ganzzahltyp haben oder ein Klassentyp mit einer eindeutigen Konvertierung in einen Ganzzahltyp sein. Die Ganzzahlerweiterung erfolgt wie unter Standardkonvertierungen beschrieben.

Der Text der switch-Anweisung besteht aus einer Reihe von case-Bezeichnungen und einer optionalen default-Bezeichnung. Bei labeled-statement handelt es sich um eine dieser Bezeichnungen und die nachfolgenden Anweisungen. Die bezeichneten Anweisungen sind für die Syntax nicht erforderlich, aber die switch-Anweisung ist ohne sie bedeutungslos. In case-Anweisungen dürfen keine zwei constant-expression-Werte zum gleichen Wert ausgewertet werden. Die default-Bezeichnung darf nur einmal vorkommen. Die default-Anweisung wird häufig am Ende platziert, kann aber überall im Text der switch-Anweisung vorkommen. Eine case - oder default -Bezeichnung kann nur innerhalb einer switch -Anweisung erscheinen.

constant-expression in der jeweiligen case-Bezeichnung wird in einen konstanten Wert konvertiert, dessen Typ dem Typ von condition entspricht. Anschließend folgt eine Überprüfung auf Gleichheit mit condition. Die Steuerung wird an die erste Anweisung nach dem case constant-expression-Wert übergeben, der dem Wert von condition entspricht. Der resultierende Verhalten wird in der folgenden Tabelle gezeigt.

Verhalten der switch-Anweisung

Bedingung Aktion
Der konvertierte Wert stimmt mit dem des hochgestuften steuernden Ausdrucks überein. Die Steuerung wird an die Anweisung übertragen, die auf die Bezeichnug folgt.
Keine der Konstanten entspricht den Konstanten in den case-Bezeichnungen. Eine default-Bezeichnung ist vorhanden. Die Steuerung geht auf die default-Bezeichnung über.
Keine der Konstanten entspricht den Konstanten in den case-Bezeichnungen. Es ist keine default-Bezeichnung vorhanden. Die Steuerung geht auf die Anweisung über, die auf die switch-Bezeichnung folgt.

Wird ein übereinstimmender Ausdruck gefunden, kann die Ausführung über spätere Bezeichnungen vom Typ case oder default fortgesetzt werden. Die break-Anweisung wird verwendet, um die Ausführung der Anweisung zu beenden und die Steuerung auf die Anweisung nach der switch-Anweisung zu übertragen. Ohne break-Anweisung wird jede Anweisung aus der entsprechenden case-Bezeichnung bis zum Ende von switch ausgeführt (einschließlich default). Zum Beispiel:

// 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) );
}

Im obigen Beispiel wird uppercase_A inkrementiert, wenn c ein groß geschriebenescase'A' ist. Die break-Anweisung nach uppercase_A++ beendet die Ausführung des Texts der switch-Anweisung, und die Steuerung geht auf die while-Schleife über. Ohne die break-Anweisung würde die Ausführung auf die nächste bezeichnete Anweisung übergehen, sodass lowercase_a und other ebenfalls inkrementiert werden würden. Einen ähnlichen Zweck erfüllt die break-Anweisung für case 'a'. Wenn c ein klein geschriebenescase'a' ist, wird lowercase_a erhöht, und die break-Anweisung beendet den Text der switch-Anweisung. Wenn es sich bei c weder um ein 'a' noch um ein 'A' handelt, wird die default-Anweisung ausgeführt.

Visual Studio 2017 und höher (verfügbar ab dem Modus /std:c++17): Das [[fallthrough]]-Attribut wird im C++17-Standard angegeben. Es kann in einer switch-Anweisung verwendet werden. Dadurch werden der Compiler sowie alle, die den Code lesen, darauf hingewiesen, dass das Fall-Through-Verhalten beabsichtigt ist. Der Microsoft C++-Compiler gibt derzeit keine Warnung Fall-Through-Verhalten aus. Daher hat dieses Attribut keine Auswirkungen auf das Compilerverhalten. In dem Beispiel wird das Attribut auf eine leere Anweisung innerhalb der nicht abgeschlossenen bezeichneten Anweisung angewendet. Das Semikolon ist also erforderlich.

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, ab Version 15.3 (verfügbar ab dem Modus /std:c++17): Eine switch-Anweisung kann über eine init-statement-Klausel verfügen, die mit einem Semikolon endet. Sie führt eine Variable ein, deren Bereich auf den Block der switch-Anweisung beschränkt ist, und initialisiert diese Variable:

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

Ein innerer Block einer switch-Anweisung kann Definitionen mit Initialisierern enthalten, solange sie erreichbar sind (also nicht von allen möglichen Ausführungspfaden umgangen werden). Namen, die mit diesen Deklarationen eingeführt werden, weisen einen lokalen Gültigkeitsbereich auf. Zum Beispiel:

// 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;
    }
}

Eine switch-Anweisung kann geschachtelt sein. Ist dies der Fall, werden die case- oder default-Bezeichnungen der nächstgelegenen switch-Anweisung zugeordnet, die sie umschließt.

Microsoft-spezifisches Verhalten

In Microsoft C++ ist die Anzahl von case-Werten in einer switch-Anweisung nicht beschränkt. Die Anzahl wird nur durch den verfügbaren Speicher beschränkt.

Weitere Informationen

Auswahlanweisungen
Schlüsselwörter