Zufällige Zufallszahlen?



  • Hi Leute!

    Ich hab hier einen Quellcode, den ich größtenteils selber geschrieben hab. Größtenteils bedeutet, dass ich alles bis auf zwei Zeilen selbst geschrieben und auch verstanden habe. Hier der Code:

    #include<iostream>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    
    bool doppelte_eintraege(const int zahlen[], const int max)
    {
    	//Zufallszahlen auf doppelte Einträge vergleichen
    	for(int i=0; i<max; i=i+1)
    	{
    		if(zahlen[i] == zahlen[max])
    		{
    			return true;
    		}
    	}
    
    return false;
    }
    
    int main()
    {
    	time_t t;
    	srand((unsigned) time(&t));
    	const int LOTTOZAHLEN = 6;
    	int zahlen[LOTTOZAHLEN];
    
    	//erste Zahl kann ohne Probleme gezogen werden
    	zahlen[0] = (rand() % 49) + 1;
    
    	for(int i=1; i<LOTTOZAHLEN; i=i+1)
    	{
    		do
    		{
    			zahlen[i] = (rand() % 49) + 1;
    		}while(doppelte_eintraege(zahlen, i));
    	}
    
    	cout << endl;
    	cout << "Ihre persoenlichen Lottozahlen: " << endl;
    
    	//Ausgabe
    	for(int i=0; i<LOTTOZAHLEN; i=i+1)
    	{
    		cout << zahlen[i] << endl;
    	}
    
    	cout << endl;
    	cout << endl << endl;
    
    return 0;
    }
    

    Probleme hab ich nun mit diesen Code-Zeilen:

    time_t t;
    srand((unsigned) time(&t));
    

    Was srand macht ist mir soweit klar, denke ich. Was ich aber nicht verstehe, warum man srand nur am Anfang des Quelltextes deklarieren muss und weshalb mir dann (nur durch die alleinige Deklaration der Funktion srad()) die Funktion rand() dann von der Prozessorzeit abhängige "Zufallszahlen" ausspuckt.

    Warum muss man dann nicht einfach srand() zur Erzeugung dieser Zufallszahlen benutzen? Könnt ihr mir das mal erklären?



  • srand() wird (wie auch rand) in der cstdlib deklariert, in Zeile 27 wird die Funktion bloß aufgerufen. Wozu das gut ist?
    http://en.wikipedia.org/wiki/Random_seed
    http://www.cplusplus.com/reference/clibrary/cstdlib/srand/

    Und im Magazin gab es auch mal was dazu 😉

    Warum muss man dann nicht einfach srand() zur Erzeugung dieser Zufallszahlen benutzen? Könnt ihr mir das mal erklären?

    srand() setzt den "Samen" für alle danach erzeugten Zufallszahlen. rand() gibt eine Zufallszahl zurück. Was genau verstehst du dabei nicht 😕



  • Diese Zufallsgeneratoren spucken keine echten Zufallszahlen aus. Sie spucken bloss möglichst zufällig erscheinende Zahlen aus basierend auf einem Startwert.
    Damit nun die Reihenfolge nicht immer die selbe ist musst du das seed mit einem Startwert initialisieren. Man nimmt dafür meistens die Zeit. Du musst nun genau ein mal das Seed initialisieren.
    Mit der Funktion srand(..) kannst du das Seed initialisieren. Du rufst eine Funktion auf, du deklarierst srand(..) nicht!



  • Das heißt, also ich rufe srand() in meinem Quelltext nur genau einmal auf, was zur Folge hat, dass mit dem &t im Argument als Startwert ein immer unterschiedlicher Startwert angenommen wird.

    Das nachfolgende rand() greift dann auf den (immer) unterscheidlichen Startwert von srand() zu.

    Hab ich das jetzt richtig verstanden?



  • vip@r schrieb:

    Das heißt, also ich rufe srand() in meinem Quelltext nur genau einmal auf, was zur Folge hat, dass mit dem &t im Argument als Startwert ein immer unterschiedlicher Startwert angenommen wird.

    Das nachfolgende rand() greift dann auf den (immer) unterscheidlichen Startwert von srand() zu.

    Hab ich das jetzt richtig verstanden?

    Ja, der Algorithmus braucht einen Initialwert (Startwert), damit er nicht immer die gleichen "Zufallszahlen" generiert. Dieser Initialwert darf aber natürlich nur einmal gesetzt werden im Programm.
    Die Funktion rand() gibt die dann Zahlen zurück, die der Algorithmus berechnet hat, basierend auf dem Startwert.



  • Ok. Ich denke ich hab das dann jetzt verstanden mit dem srand()...

    Danke!


  • Mod

    vip@r schrieb:

    Das heißt, also ich rufe srand() in meinem Quelltext nur genau einmal auf, was zur Folge hat, dass mit dem &t im Argument als Startwert ein immer unterschiedlicher Startwert angenommen wird.

    Bloß, dass bei dir &t immer das gleiche ist, da es nicht die aktuelle Zeit sondern die Adresse einer Variable ist, die die Zeit enthält.



  • SeppJ schrieb:

    vip@r schrieb:

    Das heißt, also ich rufe srand() in meinem Quelltext nur genau einmal auf, was zur Folge hat, dass mit dem &t im Argument als Startwert ein immer unterschiedlicher Startwert angenommen wird.

    Bloß, dass bei dir &t immer das gleiche ist, da es nicht die aktuelle Zeit sondern die Adresse einer Variable ist, die die Zeit enthält.

    Ist &t immer das gleiche? Die Variable kann ja bei jedem Programmstart eine unterschiedliche Adresse haben, nicht?

    @ vip@r
    Kannst das seed mit srand( time(0) ) initialisieren. Ich denke dafür musst du noch <ctime> includen.


  • Mod

    icarus2 schrieb:

    Ist &t immer das gleiche? Die Variable kann ja bei jedem Programmstart eine unterschiedliche Adresse haben, nicht?

    Mit address space randomization und solchen Scherzchen mag das möglich sein, ansonsten nicht. Fakt ist jedenfalls, dass es nicht das tut, was gemeint ist.



  • icarus2 schrieb:

    Ist &t immer das gleiche? Die Variable kann ja bei jedem Programmstart eine unterschiedliche Adresse haben, nicht?

    Wenn Du mit &t arbeitest, geht das natürlich auch, solange es bei Dir klappt. Aber beim Kunden klappt's dann nicht. Kommt recht peinlich.



  • Alles klar. Ich würds ja nie so machen. Hat mich bloss interessiert, ob es theoretisch funktioniert.


Log in to reply