case-label



  • Ich hab in meinem Buch gerade den Abschnitt über "switch/case label" durchgemacht, verstehe aber nicht, warum es ausgeführt wird, wenn ich kein break hinschreibe:

    int x = 20;
         short counter = 0;
    
            switch (x)
            {
                case 5: //5 wird komischerweise nicht ausgeführt!?
                ++counter;
                case 20:  //x ist doch nur 20
                ++counter;
                case 15: //nicht 15!? Warum wirds ausgeführt?
                ++counter;
                case 12: //Und auch nicht 12?! warum wirds trotzdem ausgeführt?
                ++counter;
                case 13: //.....ich kann da überhaupt keine Logik entdecken...
                ++counter;
            }
    
        cout << counter << endl;
    

    Ich weiß schon dass man fast immer break am ende eines case-Labels nehmen soll, aber ich verstehe den Sinn nicht. Hat jemand vll. früher auch mal diesen Denkfehler und kanns mir jetzt erklären?

    MfG
    Stromberg



  • Ohne break fällt man durch.



  • Oftmals will man so etwas machen:

    switch (x)
            {
                case 5:
                case 20: 
                case 15: 
                   ++counter;
                break;
    
                case 12: 
                case 13:
                  --counter;
                break;
            }
    


  • Ich fände es aber sinnvoller, stattdessen ein anderes Schlüsselwort zu nehmen (also "break" weg und stattdessen z.B. "continue" oder so)



  • eigentlich sollte das in deinem Buch/Tutorial auch drin stehn: da x = 20 fängt die Ausführung beim entsprechenden case-Label an und hört erst beim nächsten break auf oder wenn der Block zu Ende ist. Den kursiven Teil hast du im Buch/Tutorial vermutlich überlesen, noch nicht gelesen, oder du solltest dir ein anderes suchen 😉



  • @Stromberg:
    Einige Dinge bezüglich switch() in C++ versteht man am besten, wenn man sich denkt "switch() ist im Prinzip genau wie goto"...
    z.B. Duff's Device bereitet mir ohne dem Vergleich mit goto ziemliche Kopfschmerzen:
    http://en.wikipedia.org/wiki/Duff%27s_device

    //switch (x)
    do { // damit break funktioniert, und für den scope
    if (x == 5) goto case_5;
    else if (x == 10) goto case_10;
    else goto default_;
    
    // *** so wird z.B. auch klar wieso HIER (=vor dem ersten case) überhaupt code stehen kann ***
    // EDIT: die einzige Möglichkeit hierherzukommen ist natürlich über einen Loop,
    //       wie im Beispiel unten -- nur damit sich keiner wundert wieso man
    //       hier Code herschreiben sollte /EDIT
    
    //case 5:
    case_5:
        foo();
    
    //case 10:
    case_10:
        bar();
    
    //default:
    default_:
        baz();
    
    } while (0); // für das "do" oben :)
    

    Beispiel (total plem, aber erlaubt):

    #include <iostream>
    
    int main()
    {
    	bool foo = true;
    	switch (1)
    	{
    		do { 
    			foo = false;
    			std::cout << "VOR case 0!!!\n";
    		case 0:
    			std::cout << "case 0\n";
    		case 1:
    			std::cout << "case 1\n";
    		case 2:
    			std::cout << "case 2\n";
    		}
    		while (foo);
    	}
    
    	std::cin.get();
    }
    

    Ausgabe:

    case 1
    case 2
    VOR case 0!!!
    case 0
    case 1
    case 2
    


  • Dann definier ich dass einfach so, wenn kein "break" vorhanden ist, und switch auf ein case-Label "anspringt", dann werden die weiteren case-Label nicht mehr beachtet, aber ihre Ausdrücke werden trotzdem ausgeführt.

    z.B.

    int i = 16
    switch(i) 
    {
        case 12: //springt nicht auf 12 an
        cout << "12" << endl; //keine Ausführung
        case 14: //springt nicht auf 14 an
        cout << "14" << endl; //keine Ausführung
        case 16: //springt auf 16 an
        cout << "16" << endl;
        case 18: // wird nicht mehr beachtet
        cout << "18" << endl; //wird trotzdem ausgeführt
        case 20: //wird nicht mehr beachtet
        cout << "20" << endl; //wird trotzdem ausgeführt
    }
    

    Stimmt meine Definition von switch so? Oder würdet ihr noch was hinzufügen?

    MfG
    Stromberg



  • Das stimmt soweit, aber ich finde Du machst es Dir unnötig schwer. "Die Ausführung läuft ab der angesprungenen Case-Marke bis zum break oder Ende des switch-Blocks" reicht doch aus, um eine klare Aussage zu treffen. (Ergänzend "...ohne weitere case-Marken zu beachten" wäre nur zur Klarstellung)


Anmelden zum Antworten