随机数与简单模拟
概念说明
在实际编程中,我们经常需要生成随机数,例如掷骰子、随机抽样、洗牌、小游戏事件触发等。
在 C 语言里,最常见的入门接口是 <stdlib.h> 中的 rand() 和 srand()。
不过要先建立一个重要认识:
rand() 生成的通常不是“真正随机数”,而是伪随机数,也就是由某个初始种子按固定规则推导出来的数列。
这意味着两件事:
- 给定相同种子,通常会得到相同序列。
- 如果你从不设置种子,程序每次启动时往往会重复同一条序列。
语法/规则
rand()会返回一个位于0到RAND_MAX之间的整数。srand(seed)用来设置随机种子,常见写法是srand((unsigned)time(NULL));。- 种子通常只需要在程序启动时设置一次,不要在循环里反复重设。
rand() % n能快速得到0到n - 1之间的整数,但会存在一定偏差。- 对于入门练习和简单小游戏,
rand()足够用;对于密码学或安全用途,它远远不够。 - 如果要得到
1到6之间的整数,常见写法是rand() % 6 + 1。 - 写随机逻辑时,最好先验证结果是否落在预期范围内,再考虑分布是否均匀。
示例
| |
输出结果:
| |
这里使用固定种子 1,是为了让示例更稳定。
真正做随机模拟时,通常会改成基于时间的种子。
常见错误
- 每次生成随机数前都调用一次
srand,结果让序列反而变得更差。 - 忘记设置种子,导致程序每次启动都得到相同的随机序列。
- 以为
rand()适合做密码、令牌或安全随机用途,实际上它并不适合。 - 只会写
rand() % n,却没意识到这种映射在严格场景下可能有偏差。 - 只关注“看起来随机”,却没有先验证结果是否满足基本范围约束。