Inhalt von Variablen als Name benutzen?



  • Hi

    Ein ganz einfaches Programm, es geht nur um die Zeile mit dem -->

    struct automarke{
      string name;
    };
    
    int main()
    { automarke marke1;
      automarke marke2;
      marke1.name="tiefer und breiter";
      marke2.name="hoeher und schneller";
      for(int i = 0;i<2;i++){
    -->    cout << "marke %i heisst: " << marke%i.name << endl;
      }
    }
    

    Meine Frage: Wie sage ich c++ das er sowohl im string, als auch beim marke"i".name das i durch den Inhalt von i ersetzt und nicht als einen Buchstaben behandelt? Ich bin mir ziemlich sicher das es geht, aber ich finde einfach nicht wie. Google hat mich zu 100 Hello World Programmen geschickt, aber da ich mir nicht einmal sicher bin wie das was ich suche heisst...

    Die Ausgabe sollte grob lauten:
    Marke 0 heisst tiefer und breiter
    Marke 1 heisst hoeher und schneller

    Danke für alle Antworten schonmal

    Gruss



  • int main() 
    { 
    automarke[2] marke; 
      marke[0].name="tiefer und breiter"; 
      marke[1].name="hoeher und schneller"; 
      for(int i = 0;i<2;i++){ 
        cout << "marke %i heisst: " << marke[i].name << endl; 
      } 
    }
    

    Arrays heisst das magische Wort. (siehe aber auch std::vector oder boost::array).



  • drakon schrieb:

    int main() 
    
        cout << "marke " << i << "heisst: " << marke[i].name << endl;
    


  • Kessl schrieb:

    ...

    Nur zur Ergänzung: Grundsätzlich gibt es zur Laufzeit keine Variablennamen mehr.



  • Kessl schrieb:

    Ein ganz einfaches Programm, es geht nur um die Zeile mit dem -->

    struct automarke{
      string name;
    };
    
    int main()
    { automarke marke1;
      automarke marke2;
      marke1.name="tiefer und breiter";
      marke2.name="hoeher und schneller";
      for(int i = 0;i<2;i++){
    -->    cout << "marke %i heisst: " << marke%i.name << endl;
      }
    }
    

    Meine Frage: Wie sage ich c++ das er sowohl im string, als auch beim marke"i".name das i durch den Inhalt von i ersetzt und nicht als einen Buchstaben behandelt?

    Namen sind Schall und Rauch. Wenn Du Dein Programm übersetzt, ist typischerweise nichts mehr von den Variablennamen "marke1" und "marke2" übrig. Damit das so klappt, wie Du es haben willst, müsste der Compiler ein Programm erzeugen, was irgendwo eine Tabelle automatisch anlegt, welche einen Variablennamen mit der Adresse eines Objekts verknüpft. Das ist allerdings Overhead, den man nicht immer gebrauchen kann. Das C++ Motto ist aber "Don't pay for things you don't need". Wenn Du so eine Tabelle brauchst, erzeug sie dir selbst. In diesem Fall wäre ein Array (wie schon gezeigt) oder ein std::vector<> angebracht. In beiden Ansätzen kannst Du eines von mehreren Objekten über einen Index auswählen.

    #include <cstdlib>  // EXIT_SUCCESS Makro-Definition
    #include <iostream> // std::cout
    #include <ostream>  // std::endl
    #include <string>   // std::string
    #include <vector>   // std::vector<>
    
    using namespace std;
    
    int main()
    {
      vector<string> automarken;
      automarken.push_back("tiefer und breiter");
      automarken.push_back("hoeher und schneller");
      const int anzahl = automarken.size();
      for(int i=0; i<anzahl; ++i) {
        cout << "marke " << i << " heisst: " << automarken[i] << endl;
      }
      return EXIT_SUCCESS;
    }
    

    kk



  • Eigentlich wäre in dem Fall eine Map angebrachter.

    std::map<std::string, std::string> automarken;
    
    automarken["marke1"] = "tiefer und breiter";
    automarken["marke2"] = "hoeher und schneller"
    
    for (int i = 1; i < automarken.size(); ++i)
    {
        std::string name("marke");
        name += i + '0';
        std::cout << name << " = " << automarken[name] << std::endl;
    }
    

    Den Namen kann man sicherlich auch eleganter zusammen basteln. Es ist mir dazu nur keine fixe Lösung eingefallen. Nur ein stringstream, den man dann sinnvollerweise in einer Funktion nutzen sollte.



  • Nick Unbekannt schrieb:

    Eigentlich wäre in dem Fall eine Map angebrachter.

    Warum?

    Nachteile:
    - Es ist deutlich langsamer.
    - Es ist umständlicher, die Namen nach dem immer gleichen Schema zusammenzusetzen.

    Vorteile:
    ?



  • Michael E. schrieb:

    Nachteile:
    - Es ist deutlich langsamer.

    Nicht in dem Maße, dass es ins Gewicht fallen würde. Bei einem heftigen Gebrauch der Variablen sieht es wieder anders aus.

    Michael E. schrieb:

    - Es ist umständlicher, die Namen nach dem immer gleichen Schema zusammenzusetzen.

    Nicht mehr, wenn man die von mir angesprochene extra Funktion hat.

    Michael E. schrieb:

    Vorteile:
    ?

    Es war nach einer Möglichkeit gefragt, Bezeichner zur Laufzeit festlegen zu können. Und da kommt man an einer Map nur schwer vorbei.

    Es kommt letztendlich auf den Verwendungszweck an. Um ein paar Automarken zu verwalten ist es okay und die Dynamik gewünscht. Bei einem Videodecoder eher unpassend und die Dynamik auch nicht notwendig.



  • Nick Unbekannt schrieb:

    Michael E. schrieb:

    - Es ist umständlicher, die Namen nach dem immer gleichen Schema zusammenzusetzen.

    Nicht mehr, wenn man die von mir angesprochene extra Funktion hat.

    Wenn man nur weit genug abstrahiert, ist alles einfach 😉

    Es war nach einer Möglichkeit gefragt, Bezeichner zur Laufzeit festlegen zu können. Und da kommt man an einer Map nur schwer vorbei.

    Natürlich kommt man an ner Map vorbei, wenn wie hier nur auf Grund einer Ganzzahl unterschieden werden soll. Man sollte wissen, dass man für allgemeinere Fälle Maps benutzen kann, aber da du dich konkret auf "diesen Fall" beziehst, kann ich nicht nachvollziehen, warum du eine Map für "angebrachter" hälst als die genannten Lösungen.



  • Michael E. schrieb:

    Natürlich kommt man an ner Map vorbei, wenn wie hier nur auf Grund einer Ganzzahl unterschieden werden soll. Man sollte wissen, dass man für allgemeinere Fälle Maps benutzen kann, aber da du dich konkret auf "diesen Fall" beziehst, kann ich nicht nachvollziehen, warum du eine Map für "angebrachter" hälst als die genannten Lösungen.

    Titel des Themas war allerdings "Inhalt von Variablen als Name benutzen?". Da ein klassisches Array als Lösung anzubieten, finde ich dann schon etwas zu speziell. Auch wenn man es für das konkrete Problem passend ist.
    Ich finde es nur ungünstig, wenn der Titel nicht zum Thema passt. Weil viele Leute als Standardantwort "nutze die Suchfunktion" oder Google geben.



  • Hi

    Erstmal danke für alle Antworten.

    @drakon: Das [2] muss hinter die marke, nicht hinter die automarke. Evtl. schaut ja irgendwer, irgendwann nochmal in den Thread rein.

    Ansonsten kommt Map dem was ich machen will wohl am nächsten und da ich noch nie etwas damit gemacht habe wird das wohl das Mittel der Wahl werden. Auf Effizienz kommt es mir nicht wirklich an und arrays funktionieren zwar in dem schnell zusammengebauten Beispiel, aber wohl eher nicht in meinem Progrämmchen wo ich das ganze eigentlich nutzen wollte. Naja, ich habe viel Zeit daran rumzuspielen, ist ja alles nur zum Spass.

    Gruss



  • Ich glaube sowas wie

    #define BOOST_PP_LOCAL_MACRO(n) cout << "marke "#n" heisst: " << marke##i.name << endl; 
    int main()
    {
      ...
    #include BOOST_PP_LOCAL_ITERATE(1, 5)
    }
    

    expandiert zu

    int main()
    {
      ...
      cout << "marke 1 heisst" << marke1.name << endl;
      cout << "marke 2 heisst" << marke2.name << endl;
      cout << "marke 3 heisst" << marke3.name << endl;
      cout << "marke 4 heisst" << marke4.name << endl;
      cout << "marke 5 heisst" << marke5.name << endl;
    }
    

    (wo wir gerade alle Möglichkeiten auflisten)

    Vorteile:
    - Implizites Loop unrolling.
    - Der Compiler die Reihenfolge ändern und häufig genutze Variablen an den Anfang nehmen.
    - Es ist (etwas?) schneller.
    - Er kann den Code so belassen und marke1 heisst immer noch marke1.
    - Wenn er immer nur auf einzelne Variablen zugreift, spart er sich ev. die beiden Klammern.

    Nachteile:
    - Es ist viel umständlicher.
    - Es verwendet Makros.
    - Es verursacht Kopfschmerzen.


Log in to reply