所以我一直在用c ++构建一个简单的控制台游戏,在这里我使用来自stdlib.h的rand()函数。我已经意识到,如果我在调试模式下执行程序或未进行调试,则可以从rand函数获得不同的结果。
这是我使用rand函数的代码:
void Game::SelectHiddenWord(Fstring &word) {
std::vector<Fstring> WordList{ "plan","planet","planes","radios","gamers","images",
"amigos","micros","macros","frogs","raids","roads","paris","smog","cars","macs","scam","some","farm","fair",
"jam","rat","map","zig","zag","isogram","amorist","roaming","mirages","soaring","cargos","disarm","isobar"
};
int32 Length = WordList.size();
int32 randomNumber = std::rand()%Length;
word = WordList.at(randomNumber);
}
因此,基本上,我有一个带有等距图的单词表,并且我正在使用rand函数生成一个整数,当从单词表中选择一个单词时,它将用作索引。我发现每次执行程序时,randomNumber整数始终为14,这将使我从单词表中看到单词“ smog”。首先,我认为这可能是一个错误,因为我已经阅读过rand()函数并不是生成随机数的最佳方法。所以我以调试模式启动程序,发现我的randomNumber整数现在是32,这将使我从单词表中获得“撤防”一词。每次我使用debugmode时都会发生这种情况。
因此,在没有调试的情况下启动时,我总是得到“烟雾”一词,在有调试的情况下启动时,总是得到“撤防”一词,所以我真的可以只玩两个单词。
那么这是rand()函数的某种错误,当它在调试模式下和没有调试模式下执行程序时,其行为会有所不同吗?
我正在尝试学习c ++,但是找不到有关rand函数的任何信息,因此我不知道该如何解决此问题。因此,如果你们中有人知道如何解决此问题,那么在我使用调试模式或不进行调试的情况下,rand()函数将表现相同并独立生成相同的数字。还是我需要使用另一个函数来生成我的随机数?
任何帮助将不胜感激!
编辑:
我不想知道为什么rand()函数每次都会生成相同的值。 当我在不调试的情况下启动程序时,rand()总是生成数字14,我希望这种情况发生。但是,如果我以调试模式启动程序,则rand()始终生成数字32。但是,如果我以调试模式执行程序或不进行调试,则我希望rand函数始终生成数字14。
所以问题在于,为什么在执行有或没有调试的情况下,rand()函数的行为会有所不同并生成不同的数字。我什至不知道是否有可能回答这个问题,也许这可能与我的机器有关。
我的测试代码:
void Game::Print() {
Fstring HIDDEN_WORD{}; //This MUST be an isogram
SelectHiddenWord(HIDDEN_WORD);
MyHiddenWord= HIDDEN_WORD;
std::cout << MyHiddenWord << std::endl; //This prints "smog" to the screen if I start the program without debugging,
//and if I debug the program it prints "disarm" to the screen
我的主要方法:
Game MyGame;
int main() {
MyGame.Print();
}
我正在使用Microsoft Visual C ++编译器。
答案 0 :(得分:0)
要解决为什么rand()
在调试模式下行为不同的问题,这是编译器供应商的问题。它在内部的工作方式由实现定义(即取决于编译器的创建者)。来自cppreference:
不能保证随机序列的质量 生产的。 [...] 对于严重的随机数生成需求,不建议使用
rand()
。 建议使用C ++ 11的random number generation工具 替换rand()
。
显然rand()
有点过时,我将在答案结尾处解决。至于为什么在每次运行程序时都看到相同的值,这不是rand()
的错误。 rand()
是一个伪随机数生成器,可以生成貌似的随机数,但以完全确定的方式生成。为了在每次运行中获得不同的结果,您需要使用某种不可预测的东西(例如当前时间)来种子。这样做如下。
#include <cstdlib>
#include <ctime>
int main(){
srand(time(0));
// rand() will now behave differently on each run of the program
}
here也对此进行了说明。同样重要的是要注意,您应仅在程序开始时调用一次srand
。如here所述,在同一秒内多次调用srand
会得到相同的种子,从而产生来自rand
的相同随机序列。
如果您想最正确,C ++ 11现在提供了一个不错的random number generation library,您应该考虑使用。用法示例如下:
#include <random>
std::random_device rd; // reliable random seed generator
std::default_random_engine randengine { rd() }; // global rng, seeded with random device
...
void Game::SelectHiddenWord(Fstring &word) {
// NOTE: this vector can be static const if it never changes, to avoid
// constructing and destructing it every function call
static const std::vector<Fstring> WordList{ "plan","planet","planes","radios","gamers","images", "amigos","micros","macros","frogs","raids","roads","paris","smog","cars","macs","scam","some","farm","fair","jam","rat","map","zig","zag","isogram","amorist","roaming","mirages","soaring","cargos","disarm","isobar"};
// define distribution as [ 0, WordList.size() )
std::uniform_int_distribution<size_t> dist { 0, WordList.size() - 1 };
word = WordList.at(dist(randengine));
}
我仍然对您提到的一件事感到困惑:
但是我希望rand函数始终生成数字14 [...]
如果这确实是您想要的,您可以将每个rand()
替换为14
:-)