2016-05-21 13 views
2
int i; 
i = 2; 
switch(i) 
{ 
    case 1: 
     int k; 
     break; 
    case 2: 
     k = 1; 
     cout<<k<<endl; 
     break; 
} 

deklarieren Ich weiß nicht, warum der Code oben funktioniert.
C++: Warum können wir eine Variable im Fall des Schalters

Hier können wir nie in Fall 1 gehen, aber warum können wir k in Fall 2 verwenden?

+3

Sie denken, das ist schlecht? schau dir [Duff's Device] an (https://en.wikipedia.org/wiki/Duff%27s_device) –

+1

Schalter sind eher komisch; Wenn du nach einem Bereich suchst, {} bist dein Freund. – chris

+1

@TemplateRex In dieser Frage geht es darum, warum Sie nicht können. In dieser Frage geht es darum, warum Sie können. – Barry

Antwort

2

Es gibt eigentlich zwei Fragen:

1. Warum kann ich eine Variable nach case Label deklarieren?

Es ist, weil in C++ Etikett in Form sein:

N3337 6,1/1

markierte Anweisung:

...

  • Attribut- specifier-seqoptcaseconstant-expression: statement

...

Und in C++Deklarationsanweisung auch als Aussage (im Gegensatz zu C) betrachtet wird:

N3337 6/1:

Erklärung:

...

  • Erklärung-Anweisung

...

2. Warum kann ich über Variablendeklaration springen und dann verwenden?

Denn: N3337 6,7/3

Es ist möglich, in einen Block zu übertragen, aber nicht in einer Weise, die Erklärungen mit Initialisierung umgeht. Ein Programm, das springt (Die Übertragung von der Zustand einer Switch-Anweisung auf ein Gehäuse-Etikett gilt als ein Sprung in dieser Hinsicht.

)

von einem Punkt, wo eine Variable mit automatischer Speicherdauer bis zu einem Punkt in ihrem Umfang nicht ist, wo sie in ihrem Umfang sind schlecht gebildetist es sei denn, die Variable skalare Typen, Klassentyp mit einem trivialen Standard Konstruktor und ein trivialer Destruktor, eine cv-qualifizierte Version eines dieser Typen oder ein Array eines der vorhergehenden Typen und ohne einen Initialisierer (8.5) deklariert ist.

Da k ist von skalaren Typ, und nicht an dem Punkt der Erklärung Springen initialisiert darüber Erklärung möglich ist. Dies ist semantisch äquivalent:

goto label; 

int x; 

label: 
cout << x << endl; 

Dies würde jedoch nicht funktionieren, wenn x am Punkt der Deklaration initialisiert wurde:

goto label; 

    int x = 58; //error, jumping over declaration with initialization 

    label: 
    cout << x << endl;