Globale Variablen verhindern, Ideen gesucht



  • Folgende Problematik:

    Ich habe eine recht komplexe Rechnung durchzuführen.

    Dabei wollte ich zunächst die ca 40-50 Variablen definieren und dann eben rechnen.

    Durch viele notwendige Iterationen mit großen Anzahlen der Variablen stecke ich nun fest. Mein Problem ist, dass ich die Rechnung auf Funktionen splitten will aber auch muss. Nun will ich nicht jedesmal ein array mit 15-20 Einträgen übergeben. Ich will aber auch auf keinen Fall mit globalen Variablen Rechnen.

    Klar ich könnte eine Klasse schreiben und für jede Variable get und set Funktionen, aber das würde den Code ins unendliche aufblähen 😕

    Ihr merkt schon ich stecke fest. Leider sehe ich ausser dem array keine geeignte Möglichkeit und hoffe daher, dass ihr mir helfen könnt.

    Gruß

    Alex



  • Hey Alex,
    kraul dir einfach am Sack und machs mit Arrays 😉
    Lg
    Bruce



  • Also gibt es keine bessere Möglichkeit?

    Ich habe halt kein Bock auf die Fehlersuche danach 😉



  • 40-50 globale Variabeln? 😮 Was moechtest du denn berechnen? Du verwendest schon auch lokale Variabeln oder?

    Und wieso willst du nicht jedes mal ein Array uebergeben? Was spricht dagegen?



  • Nein ich vermeide immer globala Variablen!

    Nunja array übergeben und dann bearbeiten geht natürlich, aber ich hatte irgendwie so das Gefühl, dass ein "echter" Coder kurz lacht und mir die Idee liefert wie es schöner geht 😉



  • 40-50 Variablen hmm....

    Gibt es was dagegen zu sagen ?

    struct Variablen
    {
        Variablen(int _a, int _b, int _c) : a(_a), b(_b), c(_c) {}
        int a;
        int b;
        int c;
    };
    
    void foo(Variablen& v)
    {
        v.a = 12;
    }
    


  • Necrofighter schrieb:

    Nun will ich nicht jedesmal ein array mit 15-20 Einträgen übergeben.

    Warum nicht? Du musst das Array ja nicht kopieren sondern kannst eine Referenz darauf übergeben. Wenn du im Code dann etwas sprechendere Namen haben möchtest, mach dir ein enum mit Bezeichnern für die einzelnen Stellen:

    enum ValueNames
    {
      ZINSEN = 0,
      WIRKUNGSQUERSCHNITT,
      GESCHWINDIGKEIT,
      XY,
    
      COUNT_VALUE_NAMES
    };
    typedef std::array<double, COUNT_VALUE_NAMES> ValueArray;
    
    void foo(ValueArray& values)
    {
      values[ZINSEN] = values[XY]/values[GESCHWINDIGKEIT]; //egal, ob das Sinnmacht...
    }
    
    void berechnung()
    {
      ValueArray values;
      foo(values);
    }
    


  • Oha das kommt ganz gut 😉 Danke



  • Das mit dem enum ist zwar bissl bauernhafter als das Struct, wird aber gleich mal ausprobiert, da es doch im Endeffect die gleiche Wirkung hat.



  • Necrofighter schrieb:

    Das mit dem enum ist zwar bissl bauernhafter als das Struct,

    Da hast du vollkommen recht - entschuldige bitte, bin etwas daneben heute. Machs mit dem struct, kommt besser 😉



  • Ja ok Struct ist einfach doch genau das was ich suchte!

    Schön, noch einfach und für jeden lesbar!

    Vielen vielen Dank!!!!! Wie immer schnell geholfen 😉

    EDIT:

    Ganz dumme Frage:

    Wenn ich nun mein Struct erstellt habe:

    struct Variablen
    {
        Variablen(double _Ee,double _syo,double _syi,double _ny,double _Dnom, double _tnom,
                  double _kk,double _hw,double _tw,double _oval,double _allow, double _gap,
                  double _pk,double _E,double _k,double _ew,double _ft, double _r,double t,
                  double _J,double _ho,double _hi,double _epsilon,double _alpha,double _beta,
                  double _gamma,double _omega,double _qq,double _pcj,double _ri, double _so1,
                  double _so2,double _so3,double _si1,double _si2,double _si3, double _b1,
                  double _b2,double _h1,double _h2,double _e1,double _e2, double _f1,double f2,
                  double _s1,double _s2,double _j1,double _j2,double _ro, double _l,double s,
                  double _a,double _aa,double _sigmao,double _sigmai,double _sigma, double _sigmary,
                  double _wert,double _prec,double _count,double _u)
        /*******************************/
            :
        /*******************************/
              Ee(_Ee),syo(_syo),syi(_syi)
    
        {}
    
        /*******************************/
        double Ee,syo,syi,ny,Dnom,tnom,kk,hw,tw,oval,allow,gap,pk,E,k,ew,ft,r,t,
        J,ho,hi,epsilon,alpha,beta,gamma,omega,qq,pcj,ri,so1,so2,so3,si1,si2,si3,
        b1,b2,h1,h2,e1,e2,f1,f2,s1,s2,j1,j2,ro,s,a,aa,sigmao,sigmai,sigma,sigmary,
        wert,prec,count,u;
    };
    

    nun will ich die ersten drei Variablen mal testweise benutzen und in ein paar Funktionen bearbeiten.

    void Jacobsen(){
         Variablen V(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
         double Ee=210000,syo=355,syi=420;
         V.Ee=Ee;
         V.syo=syo;
         V.syi=syi;
    
         iteration1(V);
         iteration2(V);
    
    }
    

    Muss ich dann in jeder Rechnung diese Eskalation an "V." betreiben? 😉

    In jeder Funktion Variablen zu erstellen, über V. zu setzen und dann wieder in V zu speichern erscheint mir wieder zu bauernhaft ^^



  • also auf gut Deutsch wie mache ich das folgende schner, ohne alles doppelt zu machen?

    void SteelLining::Jacobsen_inertia(Variablen &v){
        v.j1=v.b1*v.h1*pow(v.h1/12,2);
        v.j2=v.j2+v.j1;
        v.f1=v.b1*v.h1;
        v.f2=v.f2+v.f1;
        v.h2=v.h2+v.h1;
        v.e1=v.h2-v.h1/2;
        v.s1=v.f1*v.e1;
        v.s2=v.s2+v.s1;
        v.j1=v.s1*v.e1;
        v.j2=v.j2+v.j1;
    }
    


  • -- Kannst du deine Variablen nicht zu kleineren Gruppen zusammenfassen?



  • Und wo liegt hier jetzt noch gleich der Vorteil zu den globalen Variablen 🙄?

    Das Stichwort heißt Abstraktion. Keine deiner Rechenschritte braucht alle 40-50 Variablen. Falls doch dann musst du die Schritte weiter zerlegen 💡



  • Warum machst du nicht alles in eine Klasse ?
    Dann hast du alle Variablen in deinen Funktionen zur verfügung ....



  • Jan++ schrieb:

    Warum machst du nicht alles in eine Klasse ?
    Dann hast du alle Variablen in deinen Funktionen zur verfügung ....

    Inwiefern macht das den Code besser?

    So wie der Stand jetzt ist kannst du getrost bei den globalen Variablen bleiben. Die vorgeschlagenen Alternativen machen den Code kein Stück besser.



  • Ich würde statt Globalen Variablen ein Singelton Objekt benutzen. Ist meiner Meinung nach eine Spur gekapselter 😉
    http://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Entwurfsmuster:_Singleton



  • Welchen Vorteil sollte ein Singleton haben? Erläutere das "gekapselter" bitte.



  • Was ist jetzt das Problem?

    Wenn du die 50 Variablen brauchst, dann musst du die auch hinschreiben, egal ob nun in einem Array, in einer Klasse, in einem struct, als globale Variablen, oder sonst wo.

    Was nun davon am sinnvollsten ist, kannst nur du wissen, da du ja keine Info's raus gibst was du genau machen willst.

    Wenn es dir zu viel Tipparbeit ist, hol dir ne Sekretärin.



  • 2 DInge, wnen ich die Variablen sos ehe:

    1. Lokalitätsprinzip: deklariere Variablen erst da wo du sie brauchst. Mache schon gar nichts global, was du nicht über mehrere Funktionen hinweg brauchst. Mache nie etwas global, was du genausogut als Funktionsparameter übergeben könntest.

    2. Bitte, Bitte, Bitte: nimm sprechende Variablennamen. Kleiner Test: sag mir aus dem Stand, ohne auf den Code zu schauen, was hi,qq und wert speichern.



  • @all erstmal ja die Schritte oben müssen so sein, es gehrt zu einer Iteration, die ein Gleichungssystem über das Newtonverfahren killt. Das ist nur ein Mini-Ausschnitt, da das Grundproblem den Ramen hier vollständig sprengen würde.

    Auf dem Blatt Papier ist es alles mathematisch richtig gelöst und bedarf wirklich jeder Variable.

    @otze Sprechende Variablennamen sind natürlich sinnvoll, aber ich habe mich an die Vorlage des Gleichungssystems gehalten, um bei der Rechenseite auf keinen Fall Flüchtigkeitsfehler zu provozieren.

    Frage bezgl. Variablen einfach in die Klasse der Funktion werfen:

    Kann ich einfach die 50 Teile als pulic reinwerfen? Ohne ein Objekt mit get,set geht das doch gar nicht, oder?

    Wenn ich mal wieder doof bin würde mich ein kleines Beispiel sehr freuen!

    Gruß

    Alex


Anmelden zum Antworten