老代码里srand配rand的写法到处都是,能跑,但真要写新项目,建议直接用C++的random头文件:范围可控、分布均匀,还不用自己取模。

rand的老毛病

rand配srand(time(0))能用,毛病不少:范围上限是RAND_MAX,部分平台只有32767,要大范围就得自己拼凑;用rand取模n,结果分布不均匀,数越大偏差越明显;随机质量也一般,模拟、抽奖这类场景不够看。

random库的标准写法

#include <random>
std::random_device rd;  std::mt19937 gen(rd());  std::uniform_int_distribution<int> dist(1, 100);  int n = dist(gen);

几行各司其职:random_device给真随机种子,mt19937是引擎,distribution把引擎输出映射成指定范围的整数,每次调dist(gen)取一个数。想要小数,把distribution换成uniform_real_distribution,范围写0.0到1.0,生成的就是0到1之间的浮点数。

两个常见的坑

一是引擎对象要放在循环外建一次,写在循环里每次都重新播种,常见症状是每次生成的数都一样。二是调试时想复现同样的序列,把种子从rd()换成一个固定数字,比如42,每次运行的序列就完全一致,定位问题方便。

洗牌这类现成轮子

把容器打乱成随机顺序,别手写交换逻辑,标准库有现成的:

std::shuffle(v.begin(), v.end(), gen);

头文件是algorithm,传同一个引擎进去就行。

取舍很简单:随手玩玩、要求低,rand凑合没问题;上规模的模拟、抽奖、游戏掉率,直接mt19937配distribution,分布正确还不踩坑。