Variablen einsparen, Quelltext kürzen



  • Hallo zusammen,
    Ich bin ein absoluter C++-Newbie und habe eine für mich recht grosse Herausforderung:

    1. Grundproblem
    Ich habe 3 Sensoren(a,b,c) für ein Objekt, welche mir bool-Werte geben.
    Anhand der Kombination der Boolwerte (z.Bsp. 101, 110, 010 etc.) werden bestimmte Aktionen ausgelöst.

    Mein Lösungsansatz dafür ist, dass ich die Boolvariablen in int überführe und dann folgendermassen addiere: d=a*100+b*10+c. Mithilfe von d kann ich dann in eine Switch-Anweisung gehen, welche die gewünschten Aktionen ausführt.
    Soweit bin ich mit meinem Ansatz auch ganz zufrieden.

    Jetzt die Herausforderung:

    Ich habe nicht nur ein Objekt mit den 3 Sensoren sondern 4 (in Zukunft vielleicht noch mehr)und die Aktionen sollen getrennt voneinander an den 4 Objekten ablaufen können. Würde ich jedem der insgesamt 12 Sensoren eine Variable zuweisen, wird das meines Erachtens nach Zuviel bzw. bin ich überzeugt, dass es eine einfachere Möglichkeit gibt.
    Leider fällt mir keine ein und somit hoffe ich auf einen Anstoss von euch.

    Danke schon mal


  • Mod

    MathiasS schrieb:

    Mein Lösungsansatz dafür ist, dass ich die Boolvariablen in int überführe und dann folgendermassen addiere: d=a*100+b*10+c.

    Die Koeffizienten können auch Potenzen von 2 sein. Nimm einfach 101b etc., C++14 hat Binary Literals.

    Zum Rest: Ich habe das Problem noch nicht völlig erfassen können, aber Du kennst Arrays und Schleifen, ja?



  • hi

    entweder wie Arcoth die arrays vorgeschlagen hat oder du nimmst halt z.b. einen int. in dem kannst du bis zu 32 sensoren abbilden.
    den steckst du in eine klasse. dann machst noch 2 methoden zum setzen bzw lesen der sensoren. in einem enum kannst du dann z.b. seine sensoren definieren.
    koennte dann ungefaehr so ausschauen:

    enum class sensor
    {
       sensor1 = 1,
       sensor2 = 2,
       sensor3 = 4,
       sensor4 = 8
    };
    
    class object
    {
       public:
          object(void) noexcept : m_value(0) { }
    
          auto set_sensor(sensor s, bool b) noexcept -> object&
          {
             m_value = b ? (m_value |= static_cast<int>(s)) : (m_value & (~static_cast<int>(s)));
             return *this;
          }
    
          auto get_sensor(sensor s) const noexcept -> bool
          {
             return m_value & static_cast<int>(s);
          }
    
          auto raw_data(void) const noexcept -> int
          {
             return m_value;
          }
    
       private:
          int m_value;
    };
    

    in deiner main funktion kannst es dann so nutzen:

    object obj:
    obj.set_sensor(sensor::sensor2, true).set_sensor(sensor::sensor4, true);
    
    switch(obj.raw())
    {
       case 0b0000: tu_das(); break;
       case 0b0001: tu_das(); break;
       case 0b0010: tu_das(); break;
       default: tu_was_anderes(); break;
    }
    

    Meep Meep



  • Hallo,

    Danke schon mal für die schnellen Antworten. Arrays haben mir bis vorhin noch nicht viel gesagt, Schleifen schon.
    Das Beispiel was ich angegeben habe war glaub ich ein wenig zu abstrakt, und orientierte sich nur am tatsächlichen Sachverhalt.
    Ich versuche das mal etwas präziser auszudrücken:

    Ich habe eine Tür, die besteht aus Tür (a), oberer Riegel(b), unterer Riegel(c) und Alarmanlage(d). Für jedes der 4 Elemente gibt es die Zustände offen / geschlossen (also 0 und 1) bzw. für die Alarmanlage nicht scharf und scharf (auch 0 und 1).
    Mein Programm soll ausgeben, in welchem Zustand("Zustand") sich die Tür befindet (alle möglichen Kombinationen).
    Für eine Tür hab ich das Prog fertig, wie in meinem ersten Post beschrieben.
    Wenn ich mehr als eine Tür überwachen will, sollte ich also eurer Meinung nach Arrays verwenden.

    P.S. Falls im Code Syntaxfehler sind, bitte ich darum, diese zu ignorieren
    also für 4 Türen:

    int a[4]
    int b[4]
    .
    .
    .
    int zustand[4]
    

    und für die Verarbeitung dann:

    for (i=0; i=4;i++)
    {
    zustand(i)=a(i)*1000+b(i)*100+c(i)*10+d; // Ich find die Methode für mich besser nachzuvollziehen
    Switch (zustand)
    {
    case 1001:
    {
    mach was;
    break;
    }
    case 1101:
    {
    mach was anderes;
    break;
    }
    .
    .
    .
    }
    }
    

    Oder ist es sinnvoller für jede Tür ein Array anzulegen in der dann die Werte für jede Tür abgelegt werden?



  • Dann könntest du eine Klasse Tuer erzeugen, die die entsprechenden Variablen enthält:

    struct Tuer {
      bool geschlossen;
      bool obererRiegelGeschlossen;
      bool untererRiegelGeschlossen;
      bool alarmScharf;
      // irgendwelche Funktionen zum "was machen"
      void machWas();
    };
    
    ...
    
    std::vector<Tuer> meineTueren(4);
    ...
    for (auto &tuer : meineTueren)
      tuer.machWas();
    

    Mir ist noch nicht klar, wozu du diese bools dann in eine einzige Zahl wandeln willst.
    Und "wer" soll hier überhaupt etwas machen? Die Tür selbst oder doch irgendein anderer Akteur?



  • @ wob
    zu deiner ersten Frage:
    Ich will die 4 Sensorergebnisse in eine Zahl umwandeln um die Switch Anweisung für alle Kombinationen der 4 Sensoren übersichtlich (für mich) zu gestalten:

    **a b c d
    **0 1 0 0
    0 1 1 0
    0 1 1 1
    1 0 0 0
    1 1 0 0

    zur zweiten
    Im Moment nur eine Ausgabe, zum Bsp für
    "1100" - Tür geschlossen, oberer Riegel geschlossen, unterer Riegel offen, Alarmanlage unscharf.

    In einer späteren und modifizierten Version soll eine Anzeige auf einem Display für bis zu 8 Türen gleichzeitig stattfinden.



  • std::string s;
    
    s += (geschlossen ? '1' : '0');
    s += (obererRiegelGeschlossen ? '1' : '0');
    s += (untererRiegelGeschlossen ? '1' : '0');
    s += (alarmScharf ? '1' : '0');
    
    if (s == "1001") {
      // ...
    }
    
    std::cout << s << "\n";
    

    Nicht schön, aber noch immer keine Ahnung, was jetzt konkret dein Problem ist... Eine andere Idee wäre es eine weitere Klasse DoorState o.ä. einzuführen:

    // Example program
    #include <iostream>
    #include <string>
    #include <list>
    
    class TuerZustand
    {
        std::string name;
    
        bool zustand;
    
        public:
            TuerZustand(const std::string& zustandName, bool zustand_) : name(zustandName), zustand(zustand_) { }
    
            void SetzeZustand(bool neuerZustand) { zustand = neuerZustand; }
            bool Zustand() const { return zustand; }
    
            const std::string& Name() const { return name; }
    };
    
    class Tuer
    {
        std::list<TuerZustand> zustaende;
    
        public:
        void ZustandHinzufuegen(TuerZustand neuerZustand) { zustaende.push_back(neuerZustand); }
    
        void Ausgabe() {
            for (std::list<TuerZustand>::iterator it = zustaende.begin(); it != zustaende.end(); ++it)
                std::cout << it->Name() << " " << it->Zustand() << "\n";
        }
    
        bool SetzeZustand(const std::string& s, bool neuerWert) {
    
            for (std::list<TuerZustand>::iterator it = zustaende.begin(); it != zustaende.end(); ++it) {
                 if (it->Name() == s)
                 {
                     it->SetzeZustand(neuerWert);
    
                     return true;
                 }
            }
    
            return false;
        }
    };
    
    int main()
    {
        Tuer tuer;
    
        tuer.ZustandHinzufuegen(TuerZustand("verriegelung", false));
        tuer.ZustandHinzufuegen(TuerZustand("obererRiegelGeschlossen", false));
        tuer.ZustandHinzufuegen(TuerZustand("untererRiegelGeschlossen", false));
        tuer.ZustandHinzufuegen(TuerZustand("alarmScharf", false));
    
        tuer.Ausgabe();
    
        tuer.SetzeZustand("verriegelung", true);
    
        tuer.Ausgabe();
    
    }
    

    🙄


Log in to reply