Zufallszahl | switch case | Variable | Fehler



  • GESCHAFFT 😉

    also erstmal die Frage : wenn ich die Funktion in Header als static deklariert hätte, dann hätte es also geklappt?

    so habe ich die zugehörige Klasse hinzugefügt, bzw. den Scope davor gesetzt (bestimmt falsche Ausdrucksweise)
    int CommonPartSublayerScheduling::zufall(int a) {
    ....

    gibt es eigentlich Vorteile wenn ich static benutzt hätte?



  • Michi8080 schrieb:

    wenn ich die Funktion in Header als static deklariert hätte, dann hätte es also geklappt? [...] gibt es eigentlich Vorteile wenn ich static benutzt hätte?

    Das kann ich so nicht sagen, weil ich dein Problem immer noch nicht genau kenne.

    Beispielsweise sehe ich immer noch nicht ein, warum zufall() jetzt eine Memberfunktion ist. Greift sie auf private Membervariablen der Klasse zu? Gehört sie zu einem Objekt und reagiert je nach Objekt anders?

    Ansonsten kannst du eine statische Klassenfunktion machen, wenn du findest, die Funktion gehöre logisch zur Klasse (zum Beispiel weil sie auf statische Member zugreift), sei aber unabhängig von deren Instanzen. Wenn sie nichts direkt mit der Klasse zu tun, machst du am besten eine freie, globale Funktion.



  • alles klar!

    Also ich bin wie gesagt, kein Experte 🙂 ...
    aber ich sehe den Code ... & im Code waren in dieser .cc alle Funktionen, Methoden der Klasse und wurden mit Scope-Operator benutzt.
    Logisch gehört für mich zufall() natürlich nicht zu der Klasse, da ich ja nur Zufallszahlen erzeugen will und diese dann für meine case´s nutzen will.

    Aber naja...es läuft & ich bin HAPPY 🙂

    nun zu dem Thema mit srand()...das mann es nur 1 mal aufrufen sollte und nicht jedesmal wenn ein von fünf case´s genommen wird.

    D.h. ich muss diese Zeile

    srand( (unsigned) time(NULL) ) ;
    

    aus der Methode zufall() herausnehmen?
    Und Global z.b. direkt in

    void CommonPartSublayerScheduling::initialize() {
    ......
    ......
      srand( (unsigned) time(NULL) );
    .....
    .....
    

    reinnehmen?
    Ich habe noch nie mit srand() gearbeitet. Ich weis nur dass wenn man Zufallszahlen erzeugen will, dann kommen immer wieder die gleichen raus. Und srand mit Time , erzeugt die Zufallszahlen in Abhängigkeit von der aktuellen Zeit. Also besser randomisiert. Allerdings hört hier schon mein WISSEN über srand() auf 🙂



  • srand machst du am besten bereits in der main rein. Funktionen können ja mehrmals aufgerufen werden und eigenen sich daher nicht.

    srand initialisiert den Zufallsgenerator mit einem seed, den du übergeben musst, damit auch "zufällige" Zahlen rauskommen. Wenn man z.B einen festen Wert eingibt, kann man seine "zufällige" Applikation testen und immer mit den gleichen Werten rechenen. (also der gleichen Abfolge). Für Debuggen Gold Wert.



  • Michi8080 schrieb:

    Logisch gehört für mich zufall() natürlich nicht zu der Klasse, da ich ja nur Zufallszahlen erzeugen will und diese dann für meine case´s nutzen will.

    Aber naja...es läuft & ich bin HAPPY 🙂

    Hm. Wenn es jetzt eine Memberfunktion ist, solltest du es unbedingt global machen. Sonst kommt irgendwann der Zeitpunkt, wo du nicht mehr HAPPY bist. 😉

    Michi8080 schrieb:

    Ich habe noch nie mit srand() gearbeitet. Ich weis nur dass wenn man Zufallszahlen erzeugen will, dann kommen immer wieder die gleichen raus. Und srand mit Time , erzeugt die Zufallszahlen in Abhängigkeit von der aktuellen Zeit. Also besser randomisiert. Allerdings hört hier schon mein WISSEN über srand() auf 🙂

    Also, etwas weiter ausgeholt. In der C++-Standardbibliothek (genauer gesagt dem C-Teil) gibt eine Funktion, um Zufallszahlen erzeugen. Die erzeugten Zahlen sind jedoch nicht wirklich zufällig, sondern werden deterministisch durch Algorithmen erzeugt. Mit der Funktion rand() forderst du eine solche Pseudozufallszahl an.

    Weil der Zufallsgenerator eben deterministisch verläuft, liefert er bei jedem Programmstart die gleichen Zahlen. Um wenigstens da ein bisschen Zufälligkeit reinzubringen, gibt es srand() - eine Funktion, die den Startwert setzt, von dem die nachfolgenden Zufallszahlen abhängen.

    Nun zum Grund, warum man srand() nur einmal aufrufen sollte: Der erwähnte Algorithmus basiert auf dem Konzept des linearen Kongruenzgenerators (halt einfach eine Art von Zufallsgeneratoren). Dessen erzeugte Zahlenfolgen erfüllen gewisse Kriterien, die als "Zufälligkeit" interpretiert werden können (darunter Gleichverteilung, nicht zu starke Korrelation aufeinanderfolgender Werte). Diese Forderungen können nur unter der Bedingung erfüllt werden, dass der Algorithmus wie geplant abläuft. Das tut er, solange man immer brav rand() aufruft. Er benutzt dann nämlich die neu erzeugten Zahlen wiederum als Startwert und arbeitet so rekursiv. Mit srand() stört man diesen Ablauf, indem man den momentanen Wert neu setzt. Damit kann die erwartete Zufälligkeit nicht mehr gewährleistet werden.



  • ok! jetzt verstehe ich den GRUND!

    jetzt muss ich nur wissen WIE ich es mache und wohin ich den srand() setze?

    in die Initialisierung wie oben schon angegeben? oder woanders?

    ich meine wenn srand() nur 1mal aufgerufen werden soll, dann soll er NICHT innerhalb der Methode zufall() stehen, richtig?



  • Michi8080 schrieb:

    in die Initialisierung wie oben schon angegeben? oder woanders?

    Hauptsache, es wird nur einmal aufgerufen. Wird es das bei der Init() -Methode? Vielleicht besser, du schreibst es an den Anfang von main() - ich hoffe schwer, dass es da nicht mehrmals aufgerufen wird. 😉

    Michi8080 schrieb:

    ich meine wenn srand() nur 1mal aufgerufen werden soll, dann soll er NICHT innerhalb der Methode zufall() stehen, richtig?

    Richtig. 🙂

    P.S. Ist zufall() jetzt endlich als freie Funktion implementiert? :p



  • Michi8080 schrieb:

    ich meine wenn srand() nur 1mal aufgerufen werden soll, dann soll er NICHT innerhalb der Methode zufall() stehen, richtig?

    Das habe ich doch bereits geschrieben.. 🙄



  • also stell ich mir bis jetzt zwei FRAGEN :
    1. wie ändere ich zufall() in freie Funktion?
    Also eine freie Funktion stelle ich mir ohne Scope-Operator einfach mit

    int zufall(int);
    

    vor.
    Die Methode wird dann zu Funktion und kann somit auch nicht unter private in der Klasse im Header bleiben. richtig? D.h. ich muss sie noch VOR der Deklaration der Klasse hinschreiben, oder?

    2. wohin verschiebe ich srand() ?
    -> also soll ich echt nach main() suchen? Ich bin mir zu 99% sicher das die initialisierung von der Klasse an der ich arbeite nur 1 mal durchgeführt wird.

    DAAAAAAAAAAANKE fürs lesen 🙂



  • Michi8080 schrieb:

    Also eine freie Funktion stelle ich mir ohne Scope-Operator einfach mit

    int zufall(int);
    

    vor.

    Genau.

    Michi8080 schrieb:

    Die Methode wird dann zu Funktion und kann somit auch nicht unter private in der Klasse im Header bleiben. richtig? D.h. ich muss sie noch VOR der Deklaration der Klasse hinschreiben, oder?

    Nicht unbedingt davor, einfach im Header. Wenn sie nur lokal in der Implementierungsdatei (.cc) verwendet wird, kannst du sie auch erst da deklarieren. Aber definieren auf jeden Fall erst da.

    Michi8080 schrieb:

    2. wohin verschiebe ich srand() ?
    -> also soll ich echt nach main() suchen? Ich bin mir zu 99% sicher das die initialisierung von der Klasse an der ich arbeite nur 1 mal durchgeführt wird.

    Wenn du dir fast sicher bist, kannst du srand() auch dort aufrufen. Du kannst ja mit Standardausgaben prüfen, ob der Teil mehr als einmal aufgerufen wird...



  • versteh ich es richtig das ich aus aktuell :

    int CommonPartSublayerScheduling::zufall(int a) {
    
            int r = 0;
            srand( (unsigned) time(NULL) ) ;
            for (int i=0; i<10; i++) {
            r = 1 + rand() % 100;
    
            return (r);
            }
    

    die Funktion so reduzieren muss :

    int zufall(int a) {
    
            int r = 0;
            for (int i=0; i<10; i++) {
            r = 1 + rand() % 100;
    
            return (r);
            }
    

    und dann noch :

    srand( (unsigned) time(NULL) ) ;
    

    in die .cc direkt in die Initialisierung kopieren

    und

    in .h statt :

    int zufall(int WERT);
    

    innerhalb der Klasse steht, diese Funktion außerhalb der Klasse platzieren.

    richtig?



  • Ja. Du weisst aber schon, dass ein return die Funktion unmittelbar beendet, oder?

    Einrückung wäre übrigens immer noch keine schlechte Idee...



  • also mit beenden war es mir jetzt nicht primär bewusst.
    Aber ich will ja nur in die Funktion rein, WERT zuweisen und diesen zurückgeben, FERTIG!
    Ob die Funktion dann Beendet ist oder nicht, wo ist da der Unterscheid wenn ich immer neue Werte erzeugen werde und kein "Memory" Effekt brauche? Oder sehe ich es falsch?



  • Dann lass die Schleife weg. Die wird ja so eh nur einmal ausgeführt..



  • also ich habe alles genau so gemacht ..

    jetzt wird immer eine 0 ausgeworfen???

    hmm??



  • int zufall() 
    {
     return (rand()%100);
    }
    

    Ansonsten sag mal, was du willst.. 🙄



  • ja ich glaube genau das. das ich immer eine neue Zufallszahl zwischen 0 und 100 zurückgebe

    DANKE! ich versuch es mal.....



  • SUPER! 😉 es läuft wunderbar!!!! :)))))

    Daaaaaaaaaaaaaaaaaaaaaaaaanke!



  • Und dafür haben wir jetzt 4 Seiten gebraucht?!.. 😉



  • // ...
    if ( 0 < WERT < 60 )
    // ...
    

    Nur falls es noch nicht erwähnt wurde: das ist natürlich Blödsinn, so kann man das in C++ nicht schreiben.
    Wenn dann so:

    if ( 0 < WERT && WERT < 60 )
    

    Wobei der "0 < WERT"-Teil IMO sowieso unnötig ist.


Anmelden zum Antworten