在 c++ 中,rand() 在执行有调试和不带调试的程序时生成不同的结果
In c++ the rand() is generating different result when executing the program with and without debugging
所以我一直在用 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((函数不是用于生成随机数的最佳方法。所以我在调试模式下启动了程序,我发现我现在的随机数整数是 32,这将使我从单词列表中获得"解除武装"一词。每次我使用调试模式时都会发生这种情况。
因此,在没有调试的启动时,我总是得到"烟雾"这个词,而在调试启动时,我总是得到"撤防"这个词,所以我真的可以玩两个词。
那么这是 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++编译器。
解决rand()
在调试模式下的行为不同的原因是编译器供应商的问题。它在内部的工作方式是实现定义的(即由编译器的创建者决定(。从 cpp 首选项:
无法保证随机序列的质量 产生。[...] 不建议将
rand()
用于严重的随机数生成需求。 建议使用 C++11 的随机数生成工具 以替换rand()
.
显然rand()
有点过时,我将在回答的最后解决。至于为什么您在每次运行程序时都会看到相同的值,这不是rand()
的错误。rand()
是一个伪随机数生成器,可以生成看似随机的数字,但以完全确定的方式。为了在每次运行时获得不同的结果,您需要在随机数生成器中植入一些不可预测的东西,例如当前时间。此操作如下。
#include <cstdlib>
#include <ctime>
int main(){
srand(time(0));
// rand() will now behave differently on each run of the program
}
这里也对此进行了解释。同样重要的是要注意,您应该只在程序开始时调用srand
一次。在同一秒内多次调用srand
将导致相同的种子,从而从rand
中产生相同的随机序列,如此处所述。
如果你想最正确,C++11 现在提供了一个很好的随机数生成库,你应该考虑使用。示例用法可能如下所示:
#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 [...]
如果这真的是您想要的,您可以用14
替换每个rand()
:-(
- 如何在添加文件的情况下在VSCode中调试C++程序
- 如何在 VsCode 上调试 C++/C 程序
- 调试C++程序时遇到问题
- 如何模拟时间的流逝来调试程序?
- 如何在main()之前调试程序崩溃
- 当Visual Studio停止调试程序时会自动清理内存
- VS 代码C++:无法启动调试 - 程序路径丢失或无效
- 如何在 arm 平台中调试 c 程序中的全局变量损坏
- 如何调试 C++ 程序
- 如何使用数组调试C++程序
- 使用Valgrind调试程序-检测分段故障
- 调试程序时奇怪的GDB消息C++
- 使用gdb在MS VC++2010 Express中编译的调试程序
- 调试C程序的断言错误
- CRT参数验证使多线程调试程序崩溃
- 在Linux下捕获SIGKILL的调试程序
- 在c++中调试程序时,我得到一个空白屏幕
- 在GDB中调试程序时如何获取程序的环境
- 尝试调试c++程序在Eclipse Mars上的MAC Pro视网膜与OS X Yosemite版本10.10.5
- 使用容器调试 C++ 程序<set>