使用C/C++及DLL时,断点与直接运行结果不一致问题求助
问题分析与解决方案
这问题我太熟了!核心原因是你每次调用get_powerup()都重新初始化随机数种子,而time(nullptr)返回的是秒级时间戳——你的循环执行速度极快,10次调用全在同一秒钟内完成,所以每次rand()生成的随机序列完全一致,自然返回相同的道具。加断点后,程序暂停导致循环跨了不同的秒,种子不一样,结果就正常随机了。
具体修复步骤
1. 把随机数种子初始化移到程序入口,只执行一次
rand()的种子只需要在程序启动时设置一次,重复设置会导致随机序列重复(尤其是短时间内多次调用时)。修改你的主函数,把srand(time(nullptr))放在循环之前:
int _tmain(int argc, TCHAR *argv[]) { #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); _setmode(_fileno(stderr), _O_WTEXT); #endif // 只初始化一次随机数种子! srand(time(nullptr)); for (int i = 0; i < 10; i++) { const struct powerup ajux = get_powerup(); _tprintf(TEXT("power up: %hs\n"), powerup_type_string[ajux.type]); } system("Pause"); return 0; }
然后修改get_powerup(),移除里面的srand(time(nullptr))行:
struct powerup get_powerup() { struct powerup aux {}; int r = rand() % 100 + 1; // random number between 1 and 100 if (r <= 60) //common aux.occurrence = common; else if (r > 60 && r < 90) //rare aux.occurrence = uncommon; else if (r >= 90) //very rare aux.occurrence = rare; switch (aux.occurrence) { case common: r = rand() % 2 + 1; if (r == 1) aux = set_powerup(shield); else if (r == 2) aux = set_powerup(enemy_boost); // 改成else if避免冗余判断 break; case uncommon: r = rand() % 3 + 1; if (r == 1) aux = set_powerup(ice); else if (r == 2) aux = set_powerup(battery); else if (r == 3) aux = set_powerup(alchool); break; case rare: r = rand() % 2 + 1; if (r == 1) aux = set_powerup(life); else if (r == 2) aux = set_powerup(noclip); // 同样优化判断逻辑 break; } return aux; }
2. 额外小优化(可选)
我注意到你在switch分支里的条件判断用了连续的if,改成else if可以避免不必要的重复判断(比如r=1时不会再检查r=2),虽然不影响功能,但代码逻辑更严谨。
修复后效果
修改完成后,直接运行程序就能得到和断点调试时一样的随机道具结果,不会再出现连续10次都是Enemy Boost的情况了。
内容的提问来源于stack exchange,提问作者Tony Mendes
相关产品推荐
相关产品推荐

