0

0

c++中如何生成随机数_c++ rand与srand用法【指南】

尼克

尼克

发布时间:2026-01-26 09:19:34

|

993人浏览过

|

来源于php中文网

原创

rand()和srand()不推荐用于现代C++,因生成伪随机数、分布不均、可预测且线程不安全;应优先使用头文件中的std::mt19937与std::uniform_int_distribution等设施。

c++中如何生成随机数_c++ rand与srand用法【指南】

直接说结论:rand()srand() 在现代 C++ 中不推荐用于生成真正随机的数,它们生成的是伪随机序列,且分布不均、可预测、线程不安全;真正需要随机性时,应优先用 头文件里的设施。

为什么 rand() 生成的数“看起来不随机”

常见现象:连续调用 rand() % 10 得到大量重复数字,或在小范围内(如 0–9)频次严重偏离均匀分布。根本原因不是种子问题,而是 rand() 实现质量差 —— 标准只要求它返回至少 15 位有效比特,高位变化慢,低位周期短;% 运算还会放大低位缺陷,导致模小数时严重偏差。

  • rand() % N(尤其 N 不是 2 的幂)会引入偏置,例如 RAND_MAX == 32767 时,rand() % 10 中数字 0 出现概率比 9 高约 0.03%
  • 即使调用 srand(time(nullptr)),若程序启动间隔短(如循环快速重启),种子相同,整个序列完全重复
  • rand() 是全局状态,多线程下未加锁调用会导致未定义行为

如何正确使用 srand()(仅限遗留代码兼容)

如果必须用 rand()(比如维护老项目),srand() 只需且只能调用一次,通常放在 main() 开头。重复调用反而破坏序列统计特性。

  • 绝对不要在循环里反复调用 srand(time(nullptr)) —— 这会让每次 rand() 都从“新序列第一个数”开始,结果反而更像常量
  • 避免用 clock() 或固定值做种子,time(nullptr) 是最简可用选择(但注意精度只有秒级)
  • Windows 下若用 VS,RAND_MAX 是 32767;GCC/Clang 下通常是 2147483647,但不可移植依赖

现代 C++ 推荐方案: 替代 rand()

std::mt19937(梅森旋转)配 std::uniform_int_distribution,能真正控制范围、保证均匀性、支持多线程独立实例。

GemDesign
GemDesign

AI高保真原型设计工具

下载

立即学习C++免费学习笔记(深入)”;

#include 
#include 

int main() {
    std::random_device rd;                     // 真随机种子源(硬件支持时)
    std::mt19937 gen(rd());                    // 伪随机引擎
    std::uniform_int_distribution dis(1, 100); // [1, 100] 均匀分布

    for (int i = 0; i < 5; ++i) {
        std::cout << dis(gen) << '\n';  // 每次调用都安全、均匀、可复现
    }
}
  • std::random_device 不一定真随机(某些平台回退为伪随机),但比 time(nullptr) 更难预测
  • gendis 定义在函数外或作为类成员,避免频繁构造引擎(开销大)
  • 需要可复现结果(如测试)?传入确定种子:std::mt19937 gen(12345);

容易被忽略的关键细节

很多人以为换掉 rand() 就万事大吉,但实际踩坑常发生在边界和类型上:

  • std::uniform_real_distribution 默认生成 [0.0, 1.0),不是 [0.0, 1.0] —— 上界不可达,若需闭区间得手动调整
  • std::mt19937_64 替代 std::mt19937 时,random_device 返回的 32 位值可能不足以填满 64 位状态,建议用 rd.entropy() > 0 判断是否真随机,否则 fallback 到哈希时间+PID等组合种子
  • 在嵌入式或无 /dev/urandom 环境中,std::random_device 可能抛出 std::runtime_error,必须捕获处理

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1496

2023.10.24

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

53

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

101

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

144

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

709

2023.07.26

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.8万人学习

Excel 教程
Excel 教程

共162课时 | 13.4万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号