Switch - Anweisung und Aufzählungen einbinden.



  • Hallo Com,
    ich bin so eben auf dieses Forum gestoßen und habe ein wenig mit der Suchmaschine vergebens versucht mir hier und im Netz Hilfe zu beschaffen.

    Ich muss eine Abgabe tätigen und komme aktuell nicht weiter bei folgender Aufgabe:

    Bewertung der Zimmertemperatur: Version mit switch-Anweisungen

    c) [...] fußgesteuerte Schleife, die genau dann abbricht, wenn die Aktivität gleich Ungueltig ist. Fordern Sie den Nutzer am Anfang dieser Schleife auf, eine ganzzahlige Temperatur im Bereich von 14 bis 27 Grad Celsius einzugeben und lesen Sie die Temperatur ein.

    d)Werten Sie die eingelesene Temperatur mittels einer switch-Anweisung aus. Ordnen Sie jeder Temperatur eine der Aktivitäten aus AKTION zu. Nutzen Sie dabei “fall-through“ möglichst optimal. Bei gültigen Temperaturen unter 19 °C soll geheizt werden und bei gültigen Temperaturen über 22 °C soll gekühlt werden.

    Ich weiß wie ich die Aktivitäten deklariere und initialisiere (?).
    Habe soweit auch Teilaufgabe c beendet (wenn ich es richtig verstanden habe).
    Für Aufgabe d habe ich meine switch Anweisungen erstellt, weiß jedoch nicht wie ich die elemente vom Aufzählungstyp den Temperaturen zuordne und habe keine Ahnung was "fall-through" ist.
    Desweiteren funktioniert meine Ausgabe bei der switch Anweisung nicht... Hoffe ihr könnt mir helfen.

    Mein bisheriger Code:

    #include <iostream>
    #include <istream>
    #include <stdio.h>
    
    using namespace std;
    
    
    int main()
    {
        enum AKTION{Heizen, Keine, Kuehlen, Ungueltig}; // Aufzählungstyp für die 4 Fälle angelegt
        AKTION aktion;                                  // Initialisiert
        int tem;                                        // Temperatur intialisiert
    
        do {
        cout << "Geben sie eine ganzzahlige Temperatur im Bereich von 14 - 27 Grad Celsius ein." << endl;
        cin >> tem; // Aufforderung zur Eingabe einer Temperatur
        switch (tem)
        {
            case '14' ... '19':
            cout << "Heizen" << endl;
            break;
            case '20' ... '21':
            cout << "Temperatur optimal" << endl;
            break;
            case '22' ... '27':
            cout << "Kühlen" << endl;
            break;
            return 0;
        }
        }
        while ((tem >= 14) && (tem <= 27)); // Doppeltes Kriterium
        cout << "Ungueltig" << endl; // Ausgabe falls Ungültig
        return 0;
    
    }
    
    

    Ich bedanke mich im voraus für jede Hilfe...
    Wichtig: ich bin neu in der Materie bitte seid geduldig mit meinem Verständnis zu euren Antworten.


  • Mod

    Ganz, ganz grauenhafte Aufgabenstellung, die dich völlig falsche Denk- und Programmiermuster lehrt 😞

    Der Lehrer will etwas in dieser Art sehen:

    switch (tem)
    {
      case 14:
      case 15:
      // ...
      case 19: heizen(); break;
      case 22:
      case 23:
      // ...
      case 27: kühlen(); break;
      default: alles_ok();
    }
    

    Das ist, wie schon gesagt, gleich aus mehreren Gründen ganz grauenhaft und solltest du niemals auch nur ansatzweise irgendwie ähnlich machen.

    Das kannst du halt jetzt so machen und dann ganz schnell wieder verlernen. Oder wir können versuchen, eine Semi-geschummelte Lösung zu machen, die halwegs brauchbar ist und dem Wortlaut der Aufgabe entspricht, aber nicht dem, was sich der Lehrer hier denkt. Oder wir können dir zeigen, wie man das "richtig" machen würde, wenn man sich ganz von den Vorgaben der Aufgabenstellung löst und nur auf das Ergebnis abzielt. In jedem Fall solltest du überdenken, weiter von diesem Lehrer zu lernen. Ernsthaft. Der bringt dir nur Sachen bei, die du später mühsam wieder verlernen musst.



  • @SeppJ

    Danke schonmal für deine Antwort.
    Leider ist das eine Aufgabe von meiner Übung aus der Uni. Der Übungsleiter selber sucht sich die Aufgaben nicht aus. Die sind jedes Jahr die selben.

    Wie ich jetzt aus deiner Antwort raus lese, muss ich jeden fall einzeln auflisten und dann die Schnittstellen weiter ausführen.
    Desweiteren verstehe ich nicht, was kühlen(); und alles_ok(); darstellen sollen bzw wie du auf die kommst. (Ich denke mal Funktionen?, wenn ja, warum?)

    Wie sieht mit dem fall-through aus ? und habe ich die Teilaufgabe c richtig verstanden?

    Danke im voraus

    EDIT:
    Falls es hilft. die Aufgabe geht weiter... vielleicht werden später "optimierungen" verlangt ? (Scheint eher weniger der Fall..)

    e) Testen Sie unmittelbar nach der switch-Anweisung, ob eine ungültige Temperatur eingegeben worden ist. Geben Sie in diesem Fall Eingabe ungueltig! aus und brechen Sie die Schleife sofort ab.
    f) Verwenden Sie eine zweite switch-Anweisung, um in Abhängigkeit von der Temperatur die folgenden Ausgaben auf dem Bildschirm zu erzeugen. Die Ausgabe von “Im Zimmer ist es “ soll dabei einmalig vor der switch-Anweisung erfolgen. Für den sich unmittelbar anschließenden Ausgabetext ist auch hier “fall-through“ möglichst optimal auszunutzen.


  • Mod

    Das mit dem kühlen(), heizen() etc. soll nur Platzhalter sein für das, was du da halt machen sollst. Ich wollte die Syntax von witch demonstrieren, insbesondere mit dem "durchfallen", wo halt in meinem Beispiel bei 14 Grad zu case 14 gesprungen wird, aber dann halt durchgerutscht wird, bis zum case 19, wo dann der Code zum Heizen und ein break kommen.

    Nein, dein Lehrer wird später garantiert nicht mit irgendwelchen Optimierungen zu einer besseren Lösung kommen. Ein guter Lehrer hätte gar nicht erst diese Aufgabe gestellt.



  • Naja, aber man kann mit dieser Aufgabe doch schon lernen, wie switch funktioniert.

    Dass es nicht sinnvoll ist, einen kontinuierlichen Bereich damit abzufragen, sollte aber spätestens klar sein, wenn man z.B. den Aggregatszustand von Wasser per switch auflisten sollte. Und die Temperatur ist selbstverständlich ganzzahlig, denn 20,5°C kann es nie geben 😉 Ich persönlich nutze switch nur sehr selten.



  • @SeppJ

    Alles klar, ich hab jetzt rausgefunden wieso ich keine Ausgabe erhalten habe. Habe meine "cases" falsch zusammengefasst.

    Meine Switch Befehle funktionieren jetzt und der "fall-through" / "durchfallen" ist also nur so zu verstehen, dass durch alle Fälle geschaut wird bis zum nächsten Break?

    Und wie binde ich jetzt meine Aufzählung mit ein? Ich habe sie zwar erstellt aber greife nie darauf zu.

    "Überarbeitet" hab ich jetzt das hier und alles funktioniert soweit Fehlerfrei.

       do {
        cout << "Geben sie eine ganzzahlige Temperatur im Bereich von 14 - 27 Grad Celsius ein." << endl;
        cin >> tem; // Aufforderung zur Eingabe einer Temperatur
        switch (tem)
        {
            case 14 ... 19:
            cout << "Heizen" << endl;
            break;
            case 20 ... 21:
            cout << "Die Temperatur ist optimal" << endl;
            break;
            case 22 ... 27:
            cout << "Kühlen" << endl;
            break;
            return 0;
        }
        }
        while ((tem >= 14) && (tem <= 27)); // Doppeltes Kriterium
        cout << "Ungueltig" << endl; // Ausgabe falls Ungültig
        return 0;
    

  • Mod

    Wo hast du denn das ... her? Das gibt es so nicht. Das ist einer der vielen Gründe, wieso das eine schrottige Aufgabe ist, denn es ist nicht so gut, wenn man eine lange Liste erlaubter Werte von Hand tippen muss.

    switch ist nur ein verkapptes goto. Ganz primitiv. Braucht man auch, wie wob schon sagte, praktisch nie außerhalb künstlich konstruierter Übungsaufgaben.

    An dem "fall-through" ist auch nichts magisches dran. Wie gesagt: Verkapptes goto. Das switch springt zu dem Label, z.B. zur 14, und von da wird dann stumpf weiter ausgeführt. Das heißt in meinem Beispiel geht es dann durch die weiteren Labels 15, 16, etc., die alle gar nichts machen, bis dann schließlich nach dem Label 19 endlich etwas passiert. Das break ist dann auch bloß wieder ein weiteres goto, das zum Ende springt.

    Ganz primitiv, keine höhere Logik.



  • @SeppJ sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Braucht man auch, wie wob schon sagte, praktisch nie außerhalb künstlich konstruierter Übungsaufgaben.

    Gut, also das sehe ich etwas anders. Ich brauche das häufiger. Und was daran so schlimm ist, weiß ich jetzt auch nicht...

    Beispiel 1: Messageempfang über Socket:

    switch ( msg_type )
    {
        case MSG_TYPE_START_PROCESS : ... break;
        case MSG_TYPE_END_PROCESS: .... break;
        default : throw ....
    }
    

    Beispiel 2: Object-Factories

    std::shared_ptr<BasisklassenTyp> createObjectByType( int objecttype )
    {
       switch ( objecttype )
       {
           case OBJECT_A : return std::make_shared<Spezialisierung_A> (... );
           default : return nullptr;
       }
    }
    

    Wenn ihr für einen der Anwendungsfälle eine bessere Lösung habt, immer raus damit 😉
    (ist ernst gemeint)



  • @SeppJ

    Das mit den Punkten "..." hab ich durch Recherche raus gefunden, dass es funktioniert. Erspart mir die ganzen weiteren case Zeilen. Es ist einfach ein Intervall von X bis Y.
    Ist für mich soweit auch nicht weiter wichtig. Mich interessiert ehrlich gesagt nur wie ich die Elemente aus meinem enum AKTION reinbekomme.



  • @It0101 inwiefern hilft mir das weiter?...


  • Mod

    @It0101 : Findest du das denn schön, programminterne Kommunikation mittels int-Codes? Bei dem Messageinterface wirst du da sicherlich von der C-Schnittstelle beglückt und musst es so machen, aber das ist dann ja auch eine C-Schnittstelle, die man in C++ so eigentlich nicht machen würde.

    Bei deinem zweiten Beispiel sehe ich nicht so ganz den Sinn, wieso du nicht direkt make_shared auf der korrekten Spezialisierung machst. Da kann ja niemand jemals eigene Spezialisierungen einführen, weil deine Liste fest und unveränderlich im Code verankert ist. Auch schlimm: Du selber musst stets aufpassen, dass du niemals vergisst, deine Codes an lauter verschiedenen Stellen im Programm aktuell und konsistent zu halten. Wenn schon solche Codes, wieso dann keine dynamische Liste statt hartcodierter Codes?



  • @eDEN sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Das mit den Punkten "..." hab ich durch Recherche raus gefunden

    g++ switch.cpp -o switch -Wall -pedantic -std=c++17

    switch.cpp:9:3: warning: range expressions in switch statements are non-standard [-Wpedantic]
    case 1 ... 3:
    ^~~~



  • @eDEN sagte in Switch - Anweisung und Aufzählungen einbinden.:

    @It0101 inwiefern hilft mir das weiter?...

    Das es trotz allen Übungsaufgaben immer noch einen Grund für switch geben kann 😉

    Ich benutze einen switch case zB hier und finde gar gar nicht 'falsch'? Oder doch?

    Char Console::mixedChar( const Char& chr_a,
                             const Char& chr_b,
                             const int char_mix_mode ) const
    {
        Char chr_out  = chr_a;
        switch ( char_mix_mode )
        {
        case NONE:
            break;
        case BACKGROUND:
            chr_out.bg_color = chr_b.bg_color;
            break;
        case FOREGROUND:
            chr_out.bg_color = chr_b.fg_color;
            break;
        case FOREGROUND_BACKGROUND:
            chr_out.fg_color = chr_b.bg_color;
            break;
        case FOREGROUND_FOREGROUND:
            chr_out.fg_color = chr_b.fg_color;
            break;
        default:
            std::cerr << "Console::mixedChar(): char mix mode warning\n";
            std::cerr << "char_mix_mode: " << char_mix_mode;
            ready();
        }
        return chr_out;
    }
    


  • Ich habe das Switch-Thema mal ausgelagert, damit hier ungestört die Probleme des Threaderstellers diskutiert werden können: Vermeidung von Switches

    @lemon03 :
    hau dein Beispiel ruhig mit in den neuen Thread rein. 😉



  • @manni66

    hmm... bei mir geht es problemfrei...
    Sollte auch bei meinem Übungsleiter der Fall sein, da wir das selbe Programm und die selbe Library nutzen. Spielt auch keine Rolle kann es andernfalls ja ändern :).

    Mich interessiert halt echt nur noch die Tatsache, wie ich es hinkriege meine Elemente aus dem enum als Antwort auszugeben.



  • @eDEN sagte in Switch - Anweisung und Aufzählungen einbinden.:

    @manni66

    hmm... bei mir geht es problemfrei...

    hast du denn als Compiler-Option noch "-Wpedantic" beim Buildprozess angegeben?

    Ohne Pedantic akzeptiert er das natürlich. Es ist halt tatsächlich weder im Standard so zulässig noch ist es üblich. Wenn man Ranges abtestet dann üblicherweise mit "if".



  • @eDEN sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Mich interessiert halt echt nur noch die Tatsache, wie ich es hinkriege meine Elemente aus dem enum als Antwort auszugeben.

    Warum Ausgabe?

    @eDEN sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Ordnen Sie jeder Temperatur eine der Aktivitäten aus AKTION zu

    Ist AKTION aktion; vorgegeben? Dann würde ich annehmen, dass aktion = Heizen; gemeint ist.



  • @manni66

    @manni66 sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Warum Ausgabe?

    Die Aufgabe verlangt es so. Es reicht kein einfacher cout << "Heizen" << endl;
    Oder hab ich das falsch verstanden ?

    @manni66 sagte in Switch - Anweisung und Aufzählungen einbinden.:

    Ist AKTION aktion; vorgegeben? Dann würde ich annehmen, dass aktion = Heizen; gemeint ist.

    Nein. Ich habe es mir ausgedacht. Vorgegeben ist nur AKTION und die Elemente die da drinne sind.
    Wenn ich aktion = Heizen nehme, dann wird die Ausgabe 0, da es das 0. Element ist..


Anmelden zum Antworten