Was ist der Sinn bei der Verwendung {
und }
in einer case
Anweisung? Normalerweise werden case
alle Zeilen ausgeführt , unabhängig davon, wie viele Zeilen in einer Anweisung enthalten sind. Ist dies nur eine Regel für ältere / neuere Compiler oder steckt etwas dahinter?
int a = 0;
switch (a) {
case 0:{
std::cout << "line1\n";
std::cout << "line2\n";
break;
}
}
und
int a = 0;
switch (a) {
case 0:
std::cout << "line1\n";
std::cout << "line2\n";
break;
}
c++
switch-statement
Mahmood
quelle
quelle
switch
Schlüsselwort übereinstimmen, und im zweiten Beispiel werden die eingeschlossenen Anweisungen nur einmal eingerückt. Beachten Sie, wie Sie nach dem einen unangenehmen Einzug von vier Leerzeichen habenbreak;
.statement
. In C ++ können Sie (eine Komponente der syntaktischen Kategoriestatement
istdeclaration statement
).Antworten:
Das
{}
bezeichnet einen neuen Bereichsblock .Betrachten Sie das folgende sehr konstruierte Beispiel:
Sie erhalten einen Compilerfehler, da dieser
x
bereits im Bereich definiert ist.Wenn Sie diese in ihren eigenen Teilbereich trennen, müssen Sie sie nicht mehr
x
außerhalb der switch-Anweisung deklarieren .quelle
TL; DR
Die einzige Möglichkeit, eine Variable mit einem Intializer oder einem nicht trivialen Objekt in einem Fall zu deklarieren, besteht darin, einen Blockbereich mithilfe einer
{}
anderen Steuerungsstruktur einzuführen, die einen eigenen Bereich wie eine Schleife oder eine if-Anweisung hat .Gory Details
Wir können sehen, dass Fälle nur beschriftete Anweisungen sind, wie die Beschriftungen, die mit einer goto- Anweisung verwendet werden ( dies wird im C ++ - Entwurf des Standardabschnitts 6.1 Beschriftete Anweisung behandelt ), und wir können aus Abschnitt
6.7
Absatz 3 ersehen, dass das Überspringen einer Deklaration in vielen Fällen nicht zulässig ist , einschließlich solcher mit einer Initialisierung:und bietet dieses Beispiel:
Beachten Sie, dass es hier einige Feinheiten gibt. Sie können an einer Skalardeklaration vorbei springen , die keine Initialisierung hat, zum Beispiel:
ist vollkommen gültig ( Live-Beispiel ). Wenn Sie in jedem Fall dieselbe Variable deklarieren möchten, benötigen sie natürlich jeweils einen eigenen Gültigkeitsbereich, aber dies funktioniert auch außerhalb von switch- Anweisungen auf dieselbe Weise. Dies sollte also keine große Überraschung sein.
In Bezug auf die Gründe, warum ein Sprung nach der Initialisierung nicht zulässig ist, liefert der Fehlerbericht 467, obwohl er ein etwas anderes Problem abdeckt, einen vernünftigen Fall für automatische Variablen :
Es ist wahrscheinlich interessanter, den Fall zu betrachten, in dem Sie einen Bereich innerhalb eines Switches auf mehrere Fälle erweitern. Das bekannteste Beispiel hierfür ist wahrscheinlich Duffs Gerät, das ungefähr so aussehen würde:
quelle
Es ist eine Gewohnheit, mit der Sie Variablendeklarationen mit dem resultierenden Destruktor (oder Bereichskonflikten) in
case
Klauseln einfügen können. Eine andere Sichtweise ist, dass sie für die Sprache schreiben, die sie sich gewünscht haben, wobei die gesamte Flusskontrolle aus Blöcken und nicht aus Folgen von Anweisungen besteht.quelle
Überprüfen Sie, ob dies eine grundlegende Einschränkung des Compilers ist, und Sie werden sich fragen, was passiert:
Dies gibt Ihnen einen Fehler:
Während dieser nicht wird:
quelle
Die Verwendung von Klammern im Schalter kennzeichnet einen neuen Bereichsblock, wie von Rotem angegeben.
Aber es kann auch zur Klarheit beim Lesen sein. Zu wissen, wo der Fall aufhört, da Sie möglicherweise eine bedingte Unterbrechung haben.
quelle
Die Gründe könnten sein:
quelle