# [C]Frage zur Funktion rand



## Cemil (9. März 2004)

Hallo zusammen,
ich lerne gerade C und hätte eine Frage zu der Funktion rand:

Das Programm sollte eine Zufallszahl zwischen 1 und 10 erzeugen, schön und gut, aber es erzeugt immer die gleiche Zahl (die Zahl 1). Das ist ja nicht der Sinn und Zweck der Sache.

Die Bedingung für das Spiel lautet:

1. Man hat max. 3 Versuche (count != 3), in denen man die Zahl erraten muss.

2. Solange die Variable von erraten auf dem Wert 0 UND den Zähler für die Versuche count noch nicht auf 3 stehen, beginnt der Anweisungsblock wieder von neuem.

3. Ist eine dieser Bedingungen unwahr, hat man entweder die Zahl erraten oder mehr als drei Versuche benötigt. Dies wird anschliessend nach dem Anweisungsblock ausgewertet.

Ich bin hier sicher nicht der einzige C-Neuling, deshalb habe ich das ganze Schritt für Schritt aufgeschrieben, damit man es besser nachvollziehen kann.

Hier das Listing (erstellt in MS Windows + Dev-C++ 4.9.8.7):
	
	
	



```
#include <stdio.h>
#include <stdlib.h>  /* für rand() */

int main()
{
 int ratezahl, count=0, erraten=0;
 int zufall=rand()%10; /* Pseudo-Zufallszahl von 1-10*/

 do{  /* Start der do while Schleife */
      printf("Zahleingabe bitte (1-10): ");
      scanf("%d", &ratezahl);
      if(ratezahl==zufall) /*Zahl richtig geraten? */
        {
         erraten=1; /* Ja die Zahl ist richtig */
         count++;
        }
      else
        {
         (ratezahl>zufall) ? printf("kleiner\n") : printf("grösser\n");
         count++;
        }
  }while( (erraten != 1) && (count != 3) );

  if(erraten == 0)
    {
      printf("Sie haben 3 Chancen vertan ;) \n");
      printf("Die Zahl wäre %d gewesen: \n", zufall);
    }
  else
    printf("Mit %d Versuchen erraten!\n",count);
  system("pause");
  return 0;
}
```

Was ist an diesem Listing falsch?

Für eure Hilfe bedanke ich mich im voraus.

Schönen Abend noch...


----------



## Cemil (9. März 2004)

Hi,
nach langem rumwursteln habe ich die Lösung gefunden:


```
#include <stdio.h>
#include <stdlib.h>  /* für rand() */
#include <time.h>    /* für time() */

int main()
{
   srand( time(NULL) );      /* Initialisiert Zufallszahl Generator */
   int ratezahl, count=0, erraten=0; 
   int zufall=rand()%10+1;   /* Pseudo-Zufallszahl von 1-10*/

   do{  /* Start der do while Schleife */
      printf("Zahleingabe bitte (1-10): ");
      scanf("%d", &ratezahl);
      if(ratezahl==zufall) /*Zahl richtig geraten? */
        {
         erraten=1; /* Ja die Zahl ist richtig */
         count++;
        }
      else
        {
         (ratezahl>zufall) ? printf("kleiner\n") : printf("grösser\n");
         count++;
        }
   }while( (erraten != 1) && (count != 3) );

   if(erraten == 0)
    {
      printf("Sie haben 3 Chancen vertan ;) \n");
      printf("Die Zahl wäre %d gewesen: \n", zufall);
    }
   else
      printf("Mit %d Versuchen erraten!\n",count);
   system("pause");
   return 0;
}
```

Der Zufallszahl Generator für rand war nicht gesetzt und deshalb lief das ganze nicht.

Grüsse...


----------



## swiedre (7. Januar 2005)

Hi,

hab da auch noch eine Frage.

also ich habe das jetzt mit allen Varianten probiert, die es im Internet zu finden gibt, aber es funktioniert einfach nicht. Immer habe ich nur Pseudo zufallszahlen.

Woran kann das liegen.

Hier einmal mein Zufallszahlen testprogramm:


> #include <iostream>
> #include <stdlib.h>
> #include <time.h>
> int main()
> ...


 
eigentlich soll das so gehen, es tut es aber leider nicht.

Ideen ?


----------



## mopele (7. Januar 2005)

versuch es mal mit  

zufall = rand()*10;

%ist die modulo-Funktion


----------



## swiedre (8. Januar 2005)

Leider nicht,


da bekomme ich 6 stellige Zahlen bei raus ...


----------



## mopele (8. Januar 2005)

Versuch es mal mit einem double oder float für zufall. Zahlen zwischen 0 und 1 sind meißtens keine ints


----------



## swiedre (8. Januar 2005)

hmm,

nein. Auch nicht.

Langsam wird das hier zum Ratespiel.

Vielleicht sollten wir lieber in die Richtung gehen was ansonsten nicht richtig sein kann.


----------



## Shaijan (8. Januar 2005)

Versuch den Generator mal mit GetTickCount zu initialiseren. Also:

```
srand(GetTickCount());
```

Gruß
Shai


----------



## basd (8. Januar 2005)

Rand liefert eine Zahl zwischen 0 und RAND_MAX, ergo musst du den Wert den du erhälst entsprechend skalieren. Alternativ kannst du wie erwähnt den Modulo verwenden (Dann hast du aber deine Verteilung ganz leicht verschlechtert)



> Zahlen zwischen 0 und 1 sind meißtens keine ints


LOL, das ist das geilste was ich je gelesen habe *g*, ich lach mich tot

@swiedre 
Was hat den nicht funktioniert an deinem letzten Beispiel  Ich musste noch using namespace std; eingeben damit es linkt und compiliert, aber ansonsten hat das ding schön brav Zufallszahlen generiert.


----------



## swiedre (8. Januar 2005)

Aber immer die selben, also immer einem bestimmten Muster folgend.

Auch wenn ich das aus einem meinem compiler beiligenden Beispiel stumpf rauskopierte funktionierte das nicht. Das ist sooo mysteriös.


----------



## basd (9. Januar 2005)

also wenn ich dass programm neu starte kommt bei mir so gut wie immer eine neue Zahl zwischen 0...10

DIe Zahlen werden nach einem Muster erstellt aber die Laufzeit ist sehr hoch, d.h. die wiederholung der Periode erfolgt so ziemlich alle 2^x Werte


----------



## monger (9. März 2005)

Falls es noch jemanden interessiert:

  #include <ctime>
  #include <cstdlib>

  long sek;
  time(&sek);
  srand((unsigned)sek);
  zahl = rand() % gewünschtesIntervall + gewünschterMinimalwert

  So funktioniert das unter C++. Unter c dürfte das auch nicht anders sein. Das einzige was abweichen könnte, ist: 
  #include <time.h>
  #include <stdlib.h>

  Ansonsten viel Vergnügen.


----------



## MoNchHiChii (1. Dezember 2008)

hi zusammen,

ich möchte das thema kurz wieder aufgreifen, da ich eine ähnliche aufgabe hab. auch wenn das nun monate/jahre nach seiner aufgabe ist 

ich habe das problem, das ich die größtmögliche Ratezahl selbst eingeben muss. von diesem berreich soll dann eine ratezahl generiert werden. ich bin absoluter neuling, daher bitte nicht lachen um meine änderungen zum vorhandenen code 


```
i#include <stdio.h>
#include <stdlib.h>

int main()      {

        srand(time(NULL));      /*Initialisiert Zufallszahl*/
        int Zufall=rand(); /*Zufallszahl*/ <---- Muss ich hier mit GRatezahl verknüpfen? wenn ja, wie?
        int GRatezahl, Ratezahl, count=0, erraten=0; /*Variablen*/

        /*Ausgabe*/
        printf("Bitte geben Sie die groestmoegliche Ratezahl ein: ", GRatezahl);
        scanf("%i", &GRatezahl);

                /*do while Schleife beginnt*/
                do      {
                printf("Geben Sie nun bitte Ihren Tipp ab: ", Ratezahl);
                scanf("%i", &Ratezahl);

                /*Wenn, Zahl richtig geraten*/
                if(Ratezahl==Zufall)    {
                erraten=1;
                count++;
                }

                /*Wenn, Zahl falsch geraten*/
                else    {
                (Ratezahl>Zufall) ? printf("Die Zahl ist zu gross\n") : printf("Die Zahl ist zu klein\n");
                count++;
                }
        }
        while((erraten != 1) && (count != 0));

        if (erraten == 1)
        {
        printf("Mit %i Versuchen erraten!\n", count);
        }
}
```

eine zweite frage, wir haben eine datei zum einbinden bereitgestellt bekommen die unsere Zufallszahlen erzeugen soll. also anderes als in diesem code. ich weiß jedoch nicht wie ich das einbinden kann.

die funktion heißt

zuf(unsigned int max) 

ich hab nichtmal eine idee wo ich das einbauen könnte. 

lg und dank im voraus.
M


----------



## devDevil (1. Dezember 2008)

Na räumen wir hier mal kurz die falschen Aussagen auf und dann sehen wa mal weiter:


> versuch es mal mit
> 
> zufall = rand()*10;
> 
> %ist die modulo-Funktion


Ja ich denke mal das war auch so gewollt, denn dadurch kann man den Wert einer Variable in einem Bereich halten (da modulo Rest bei Teilvorgang ist, Rest niemals größer als Divisor). Durch die Multiplikation erreichst du nur, dass die Zufallszahlen nicht eine von  0, 1, 2, 3 ..., RAND_MAX ist, sondern das sie eine von 0, 10, 20, 30, ..., RAND_MAX * 10 ist.




> Versuch es mal mit einem double oder float für zufall. Zahlen zwischen 0 und 1 sind meißtens keine ints


Das ist in sofern nicht falsch, das Fließkommazahlen auch Zahlen zwischen 0 u. 1 umfassen, aber da die Funktion rand generell nur integer zurückgibt, hat das nicht's mit dem Thema zu tun. Wenn man Allerdings Zahlen im Kommabereich haben will, muss man das Ergebnis durch 10^n, wobei n die Nachkommastellen sind, teilen.


```
#include <iostream>
#include <stdlib.h>
#include <time.h>
int main()
{
srand( time (NULL) );
int zufall;

zufall = rand()%10+1;

cout << zufall << endl;

system("PAUSE");
return 0;
}
```
Na gut anfangs war von C zwar die Rede, C++ ist das nicht, C aber auch nicht. Ka was das darstellen soll 

```
#include <iostream>
#include <ctime>
#include <cstdlib>

int main()
{
    std::srand(static_cast<unsigned>(std::time(NULL)));
    std::cout << std::rand() << std::endl;
    std::cin.ignore();
}
```
 So wäre wohl ein gültiges C++-Beispiel.



> #include <ctime>
> #include <cstdlib>
> 
> long sek;
> ...


Soweit korrekt, nur sind die Funktionen time, srand u. rand im Namensraum std, es sei denn du hast die selber implementiert. Dann solltest du bite auch C++-Style-Cast nutzen und evtl. solltest du dir mal Artikel darüber durchlesen warum Module-Op nicht geeignet ist (für sowas).

@MoNchHiChii:
Also zu deiner Frage ... einfach rand() durch zuf(32767) ersetzen. Dann sollte es wohl gleich sein.

Weiterführende Links:
http://cplus.kompf.de/artikel/random.html
http://cplus.kompf.de/artikel/random_shuffle.html


----------



## MoNchHiChii (1. Dezember 2008)

hi,

erstmal danke für deine antwort und die erläuterungen.

jedoch kappt dein vorschlag nicht.


```
ld: 0711-317 ERROR: Undefined symbol: .zuf
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: ld returned 8 exit status
```

diesen fehler erhalte ich dann.

ich frag mal was anderes, bzw etwas anders. ich denke ich muss in diesem programm bezug auf die datei von unseren prof nehmen, die er uns bereitgestellt hat.

zuf.c

liegt vielleicht da der fehler?! das ich diese datei nicht richtig einbinde? bzw gar nicht einbinde? ich weiß halt nicht wie.

und das problem, das meine zahl die ich nach ausgabe eintippe, nicht die maximale zu generierende zahl ist, bleibt weiterhin bestehen.


----------



## deepthroat (1. Dezember 2008)

Hi.





MoNchHiChii hat gesagt.:


> eine zweite frage


Wieso zweite Frage? Wo war denn die erste? Evlt. wäre es einfacher, wenn du Satzzeichen verwenden würdest... Bitte halte dich an die Netiquette!


MoNchHiChii hat gesagt.:


> , wir haben eine datei zum einbinden bereitgestellt bekommen die unsere Zufallszahlen erzeugen soll. also anderes als in diesem code. ich weiß jedoch nicht wie ich das einbinden kann.
> 
> die funktion heißt
> 
> ...


Statt rand() rufst du eben zuf(GRandmax) auf.

Gruß


----------



## MoNchHiChii (1. Dezember 2008)

Hi,

sry für meine Rechtsschreibschwäche. Ich komme aus Spanien und bin noch nicht so lange in Deutschlad. Es ist nicht ganz so einfach.

Auch nach deinem Tipp, kommt dieser Fehler.

MfG
M

*edit*

```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()      {
         unsigned int zuf(unsigned int max)
        {
        /* Erzeugung von Zufallszahlen im Bereich 0 < n <= max     */
        static int init=0;
        unsigned int wert=RAND_MAX+1;

        /* Damit nicht immer mit der gleichen Zahlenfolge begonnen wird,
           wird der Zufallszahlengenerator mit der Anzahl der Sekunden,
           die seit dem 1.1.1970 0 Uhr vergangen sind, initialisiert.
        */

        if(init == 0)
           {
           srand(time(NULL));
           init = 1;
           }

        while (wert > max)
        /* rand erzeugt Zahlen im Bereich von 0 --> RAND_MAX.
           RAND_MAX ist auf der IBM = 32767.
        */
           wert=rand();
        return wert;
        }

        int Zufall = unsigned int zuf(unsigned int max);        /*Zufallszahl*/
        int GRatezahl, Ratezahl, count=0, erraten=0;            /*Variablen*/

        /*Ausgabe*/
        printf("Bitte geben Sie die groestmoegliche Ratezahl ein: ", GRatezahl);
        scanf("%i", &GRatezahl);

                /*do while Schleife beginnt*/
                do      {
                printf("Geben Sie nun bitte Ihren Tipp ab: ", Ratezahl);
                scanf("%i", &Ratezahl);

                /*Wenn, Zahl richtig geraten*/
                if(Ratezahl==Zufall)    {
                erraten=1;
                count++;
                }
         }
        while((erraten != 1) && (count != 0));

        if (erraten == 1)
        {
        printf("Mit %i Versuchen erraten!\n", count);
        }
}
```

der erste Teil des Programms ist meine zuf.c datei, die ich so nun eingebunden hab. Jedoch scheine ich bei der Zuweisung von Zufall einen Fehler zu machen, denn das klappt nicht. Er gibt mir auch hier immer einen Fehler aus.



> Zahlen.c: In function 'main':
> Zahlen.c:39: error: expected expression before 'unsigned'



Ich verstehe diesen Fehler nicht. Denn ich dachte durch die Datei zuf.c die ich eingebunden hab, sollte alles klar sein.

Wo ist mein Denkfehler?!

Danke wiedermal im Voraus. 

PS:
Ich hoffe meine Texte sind nun Leselicher, ich gebe mir wirkliche mühe.

*edit*

so die Einbindung der Datei habe ich nun geschaft.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "zuf.c"

bleibt also nun nur noch das Problem mit dem Größtenratezahl als vorgabe zum Generieren.

*edit2*

Falls jmd die Lösung interessiert oder verbesserungs Vorschläge hat, poste ich nun mal das Ergebniss wie es zumindest ausreichend Funktioniert.


```
#include <stdio.h>
#include <stdlib.h>
#include "zuf.c"

int main()      {

        srand(time(NULL));                              /*Zufallsgenerator*/
        int GRatezahl, Ratezahl, count=0, erraten=0;    /*Variablen*/

        /*Ausgabe*/
        printf("Bitte geben Sie die groestmoegliche Ratezahl ein: ", GRatezahl);
        scanf("%i", &GRatezahl);

        int Zufall = rand()&GRatezahl;                /*Zufallszahl*/


                /*do while Schleife beginnt*/
                do      {
                printf("Geben Sie nun bitte Ihren Tipp ab: ", Ratezahl);
                scanf("%i", &Ratezahl);

                /*Wenn, Zahl richtig geraten*/
                if(Ratezahl==Zufall)    {
                erraten=1;
                count++;
                }

                /*Wenn, Zahl falsch geraten*/
                else    {
                (Ratezahl>Zufall) ? printf("Die Zahl ist zu gross\n") : printf("Die Zahl ist zu klein\n");
                count++;
                }
        }
        while((erraten != 1) && (count != 0));

        if (erraten == 1)
        {
        printf("Mit %i Versuchen erraten!\n", count);
        }
}
```


----------



## Mizi Mace (1. Dezember 2008)

Einen wunderschönen guten Tag,

Bei der Verwendung der Funktion _zuf(unsigned int max)_ sollte es mit der größten Ratezahl kein Problem geben. Die größte Ratezahl wird als Parameter für die Funktion _zuf(unsigned int max)_ übergeben. Als Rückgabe erhälst du dann eine Zufallszahl zwischen 0 und den eingegebenen Maximum. Der Code könnte dann wie folgt aussehen:


```
printf("Bitte geben Sie die groestmoegliche Ratezahl ein: ");
scanf("%i", &GRatezahl);
Zufall = zuf(GRatezahl);
printf("Geben Sie nun bitte Ihren Tipp ab: ");
scanf("%i", &Ratezahl);
if(Ratezahl == Zufall) {
  printf("richtig");
else {
  printf("leider falsch");
}
```

Was fehlt ist noch die Schleife für das dreimalige Abfragen.

Wenn du den Pseudozufallszahlengenerator selbst implementieren willst, dann musst du zunächst einmal initialisieren:


```
srand(time(NULL));
```

Dadurch wird verhindert, dass immer die gleiche Zahlenfolge ausgegeben wird. Die erzeugten Zufallszahlen kannst du mittels dem Modulo-Operator auf ein Maximum beschränken, da das Ergebnis einer Modulo-Operation stets der Rest bei Division ist. Also für Division durch 10 kann der Rest die Zahlen 0 bis 9 annehmen, bei 100 dann 0 bis 99 und bei 389 ist der Rest im Bereich von 0 bis 388. Natürlich kannst du die maximale Zhal zur Laufzeit auch erst durch das Programm ermitteln lassen und in eine Variable speichern: bei dir GRatezahl. Das ganze sieht dann folgendermaßen aus:


```
srand(time(NULL));
Zufall = rand()%GRatezahl + 1;
```

Das kannst du dann anstelle der Funktion _zuf(unsigned integer max)_ schreiben.

Gruss
Mizi


----------



## MoNchHiChii (1. Dezember 2008)

@Mizi Mace

Danke schön. Habe ca 10 sec vor dir meine Lösung die quasi deine Änderung hat, gepostet  Hehe.

Mit zuf(unsigned int max) möchte einfach nicht funktionieren, ich erhalte immer einen Fehler. Daher reicht auch diese Variante erstmal aus. Hoffe ich 

Vielen Dank an Alle

*edit*
eine Schleife für 3mal Abfrage benötige ich nicht. Es soll solange getestet werden, bis man das Ergebniss erlangt hat. Das klappt auch.

*edit2*
nach deinem bsp klappt nun auch zuf. auch hier vielen dank.

*edit3*

```
#include <stdio.h>
#include <stdlib.h>
#include "zuf.c"

int main()      {

        int GRatezahl, Ratezahl, versuche=1, count=0, erraten=0;        /*Variablen*/

        /*Ausgabe*/
        printf("Bitte geben Sie die groestmoegliche Ratezahl ein: ");
        scanf("%i", &GRatezahl);

        int Zufall = zuf(GRatezahl);                    /*Zufallszahl*/


                /*do while Schleife beginnt*/
                do      {
                printf("Das ist Ihr %i er Versuch\n", versuche);
                printf("Geben Sie nun bitte Ihren Tipp ab: ");
                scanf("%i", &Ratezahl);
                versuche++;

                /*Wenn, Zahl richtig geraten*/
                if(Ratezahl==Zufall)    {
                erraten=1;
                count++;
                }

                /*Wenn, Zahl falsch geraten*/
                else    {
                (Ratezahl>Zufall) ? printf("Die Zahl ist zu gross\n") : printf("Die Zahl ist zu klein\n");
                count++;
                }
        }
        while((erraten != 1) && (count != 0));

        if (erraten == 1)
        {
        printf("Mit %i Versuchen erraten!\n", count);
		}
}
```

so mit diesem Code ist die ganze Aufgabe komplett gelöst. 

Bin euch SEHR dankbar für die Hilfe.


----------

