Srand in void?

...komplette Frage anzeigen

3 Antworten

Dein Code ist leider komplett falsch.

Eine Funktion, mit dem Rückgabetyp void, gibt nichts zurück, aber wenn du das Ergebnis in der übergebenen Variablen speichern willst (warum auch immer), dann nimmt man bei C++ Referenzen. (Zeiger würde man nur bei C nehmen.)

Außerdem ist das Gespann von srand() und rand() sehr schlecht, da die rand() Funktion einen grauenvollen Algorithmus umsetzt, und dein Ergebnis deshalb nicht gleichmäßig verteilt sein wird.

Bei C++ benutzt man diese beiden alten und fehlerhaften C-Funktionen nicht mehr, sondern setzt auf eine Kombination aus Generator und Distribution aus dem <random> Header.

Die Zeile in der "cout << zufall;" steht ist zwar korrekt, aber sie gibt dir nur die Adresse der Funktion "zufall" aus, sprich einen Funktionszeiger! Deshalb erhältst du dabei Hex-Zahlen ... das ist einfach die Adresse der Funktion im Speicher. :)

Falls du doch bei srand() und rand() bleiben willst, solltest du srand() nur einmal initialisieren, bevor (!) du rand aufrufst, und nicht jedes mal davor, schon gar nicht, wenn du time() dafür nutzt ... denn damit wirst du eine ganze Reihe "identischer Zufallszahlen" erzeugen, Stichwort Timing-Window.

Außerdem solltest du dir C++artige Casts angewöhnen, wenn du in C++ programmierst, denn die C-Casts mit einfach Klammern haben unzählige nachteile. Das gleiche gilt für "nullptr" in C++ und "NULL" in C.

Lange Rede, kurzer Sinn, mit srand() und rand() sähe dein Code korrekterweise so aus:

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

void zufall_a(int &wahlcp) {
wahlcp = rand() % 3 + 1;
}

int zufall_b() {
return rand() % 3 + 1;
}

int main() {
srand(static_cast(time(nullptr)));

int i;
zufall_a(i);

using namespace std;
cout << "A: " << i << endl;
cout << "B: " << zufall_b() << endl;
}

Allerdings würde ich es in (richtigem) C++ so machen:

#include <chrono>
#include <iostream>
#include <random>

int main() {
using namespace std;

auto now = std::chrono::system_clock::now();
auto seed = now.time_since_epoch().count();

default_random_engine eng{seed};
uniform_int_distribution dist{1, 3};

int i = dist(eng);
cout << "A: " << i << endl;
cout << "B: " << dist(eng) << endl;
}

Diese "dist(eng)" Kombination kann man zwar noch schön mit bind() oder in ein Lambda verpacken, aber egal ...

Merke dir auf jeden Fall, dass C++ nicht C ist, und umgekehrt. Beide Sprachen unterscheiden sich gewaltig!

Naja, viel Spaß noch. :)

PS: Da ich befürchte, dass dich meine Antwort überfordert noch ein Tipp: Fang in aller Ruhe bei den Grundlagen an! Wenn du mitten drin anfängst zu lernen wird das nichts! :)

idinahuibljad 28.02.2017, 17:56

Danke für die ausführliche Antwort. Werde mich mal Zeile für Zeile durch deinen zweiten Code Googlen, 90% davon habe ich nämlich noch nie gehört. 

1

du machst in deiner main eine Variable die du später ausgibst und übergibst zufall den pointer zu der Variable

idinahuibljad 28.02.2017, 10:00

kannst du mir ein codebeispiel geben? ich verstehe deine aussage, bin allerdings zu blöd sie umzusetzen...

0
Snapstromegon 28.02.2017, 10:02
@idinahuibljad
void zufall(*int wahlcp){
*wahlcp = rand()%3+1; } int main(){ int x; zufall(&x); cout << x; }
0

Du weißt aber schon, dass "void" nichts zurückgibt, ja? Schon allein deshalb kann 

cout << zufall;

nicht funktionieren. Es gibt nichts für cout auszugeben, weil da nichts ist.

Du sagst "in einer void machen". Was genau ist denn eine "void"? "void" heißt genau das: Leerer Raum. "in einer void" kann man also genau gar nichts machen, weil da nichts ist. Was du meinst, ist eine Methode.

In etwa so:

int zufall(int wahlcp) {
srand((unsigned)time(NULL));
wahlcp = rand() % 3 + 1; return wahlcp; } int main(){ cout << zufall; return 0; }
ceevee 28.02.2017, 12:05

Das srand() ist bei dir (und beim Fragesteller auch) an der falschen Stelle. srand() sollte idealerweise nur einmal aufgerufen werden, also in der main-Methode. Ansonsten würdest du bei jedem Funktionsaufruf die gleiche Zufallszahl zurückbekommen, weil du den Zufallszahlengenerator jedes Mal neu initialisierst.

Ansonsten würde ich das aber genauso lösen. Vor allem würde ich auf die void-Methode und das Zeigergeschubse verzichten, wenn dazu kein Anlass besteht.

1
TraugottM 28.02.2017, 14:01
@ceevee

Ja, stimmt. Der Code ist nicht ganz sauber. Ich kann mich immerhin damit rausreden, dass ich kein C-Programmierer bin. :D

0

Was möchtest Du wissen?