引子

相信大家对于rand()函数并不陌生,我们常用它来生成伪随机数,但是为什么有时候我们生成的随机数并不符合预期呢?或者说,为什么有时候我们生成的随机数并不随机?如何有效地生成伪随机数呢?

rand()

rand()函数是使用线性同余法做的,它并不是真的随机数,因为其周期特别长,所以在一定范围内可以看成随机的。
        rand()函数不需要参数,它将会返回0到RAND_MAX之间的任意的整数。如果我们想要生成一个在区间[0, 1]之内的数,那么我们可以写出如下代码:

rand_num = rand()/RAND_MAX;

现在我们之内运行如下代码来生成10个随机数:

for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

多次运行结果如图:

通常来说,这并不是我们所期望的结果,下面我们来看看如何使用srand()函数正确地实现伪随机数生成。

srand()

srand()为初始化随机数发生器,用于设置rand()产生随机数时的种子。传入的参数seed为unsigned int类型,通常我们会使用time(0)或time(NULL)的返回值作为seed。下面我们来进行实验,从而对它进行更深入的感知。

srand(1);
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

此时我们得到的结果为:

从图中来看,这与我们前面不使用srand()设置随机种子时结果一致,因此我们可以看出,如果我们不显示调用srand()的话,将默认为srand(1)。此外,从这次实验中可以看出,如果我们设置某个固定的seed,那么虽然在同一次运行时,会有不同的随机数产生,但是对于这段程序的多次运行所得到的结果是不变的。
        那我们如何引入变化的种子呢?一般来说,我们会使用time(NULL)或time(0)来表示变化的种子,time(0)的返回的是从1970 UTC Jan 1 00:00到当前时刻的秒数,为unsigned int类型。当我们在不同时刻运行程序时,就会有不同的随机数种子,因此就可以得到不同的结果:

srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

这段代码的运行结果为:

值得注意的是,如果,我们两次程序运行之间的间隔小于1s,那么会出现下面这种情形(我们通过在代码中两次调用srand(time(0))来模仿这种情形):

srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}
cout << "--------------" << endl;
srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

运行结果:

从图中来看,两次运行结果一致,这是为什么呢?因为我们两次调用srand()函数设置随机数种子之间的时间间隔不超过1s,这会导致我们重置随机数种子,从而等价于使用了一个固定的随机数种子。我们可以用下面的代码来进行验证:

srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}
cout << "--------------" << endl;
sleep(1.0);
srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

此时我们得到的结果为:

为什么要特意指出这一点?这是为了防止我们不小心将srand(time(0))放入了随机数生成循环中:

for(int i = 0; i < 10; i++)
{srand(time(0));cout << rand() << endl;
}

我们得到的结果为:

如果,我们在其中引入sleep(1.0),那么将没有问题:

for(int i = 0; i < 10; i++)
{srand(time(0));cout << rand() << endl;sleep(1.0);
}

输出结果为:

总结

综上所述,正确的用法是:

srand(time(0));
for(int i = 0; i < 10; i++)
{cout << rand() << endl;
}

而且,两次程序执行的时间间隔要大于1s,如果我们是要在某个类中定义随机数生成函数,那么可以将srand()放在构造函数中。

关于rand()和srand()相关推荐

  1. 【C++】random随机数与【C++11】/rand()和srand()的用法

    文章目录 随机数 1. c++ 11 random随机数的使用(推荐使用) 1.1 1.2 1.3 1.4 2.1 C++中随机函数rand()和srand()的用法(老本版) 2.2 限制随机数的范 ...

  2. rand()和srand()关系很简单——一看就明白(通过一个可移植的源码)

    1 函数rand和srand实现及描述 #include <stdlib.h> //供rand()使用的种子数,初值为1 unsigned long int next = 1; /* * ...

  3. rand和srand

    rand()和srand()函数我们应该接触的比较多了,之前就遇到过,弄懂了,但是现在又忘了.再次遇见写篇文章记录一下. srand()用来设定一个随机数种子,其参数必须是整数,不同的随机数种子使ra ...

  4. C++中随机函数rand()和srand()的用法

    一.rand() 函数名:   rand      功   能:   随机数发生器    用   法:   int rand(void); 所在头文件: stdlib.h 函数说明 : rand()的 ...

  5. C语言之rand()和srand()函数

    1.rand().srand()函数介绍 srand 初始化随机种子,rand 产生随机数 定义函数:int rand(void) 函数功能:产生随机数 函数说明:rand的内部实现是用线性同余法做的 ...

  6. C语言随机数:rand()和srand(time(NULL))的使用

    C语言随机数 rand()简介 srand()简介 使用 rand()简介 使用该函数首先应在开头包含头文件<stdlib.h> #include<stdlib.h> //(C ...

  7. 【C语言】随机数函数rand和srand

    文章目录 一.随机数函数 1.rand().srand() 2.time() 二.案例实现 1.案例描述 2.代码实现 一.随机数函数 1.rand().srand() C语言产生随机数要用到的函数是 ...

  8. rand和srand的用法(转载)

    首先我们要对rand&srand有个总体的看法:srand初始化随机种子,rand产生随机数,下面将详细说明. rand(产生随机数) 表头文件: #include<stdlib.h&g ...

  9. rand()和srand()函数的用法

    一.rand() rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的. rand()会返回一个范围在0到RAN ...

  10. C 语言 rand() 和 srand() 使用方法

    前言 有时我们想用 rand() 生成一组随机数,虽然我们调用了 srand(),但是生成的还是相同值.为什么会产生这种情况?又该如何解决?下面将用第一视角一起探究这其中的奥秘. 问题出现 场景描述: ...

最新文章

  1. 哈希(Hash)算法是一种单向密码体制(它是一个从明文到密文的不可逆的映射只有加密过程没有解密过程)
  2. linux系统管理工具sar(一)
  3. eclipse.ini内存设置(转)
  4. 数据库建模模板、菜单显示出问题解决方案
  5. Android 程序适应多种多分辨率
  6. 风口上的储能,光伏要飞起来?
  7. java ssm 多租户_(十一)java B2B2C 源码 多级分销springmvc mybatis多租户电子商城系统- SSO单点登录之OAuth2.0登录流程(2)...
  8. 官方:Angular 5 推迟到10月底发布
  9. linux libz-dev,Linux-based Development
  10. 第4章 旋转蛇(《C和C++游戏趣味编程》配套教学视频)
  11. 字符串怎样实例化成对象
  12. The partial sum problem
  13. 单片机中的冒泡排序(汇编语言)
  14. 怎么在计算机网络上添加文件,教你win7如何设置网络共享文件夹
  15. 触摸识别,智能分拣……看AI如何为垃圾分类赋能
  16. Unity烘焙基础操作
  17. 论文阅读:RICAP: Random Image Cropping and Patching Data Augmentation for Deep CNNs
  18. sigmoid的通俗理解
  19. sessionStorage储存对象的方式
  20. 金山文档手机app服务器异常,为什么我的手机看不了金山文档 看不了金山文档怎么办...

热门文章

  1. 年龄识别之AgeNet
  2. Excel2007无法卸载:安装程序包的语言不受系统支持。微软的卸载程序也不行。——只能手工删除
  3. tableview中cell折叠的功能
  4. 启动计算机按住del不放,电脑黑屏bios界面都进不去怎么办
  5. 解读:【阿里热线小蜜】实时语音对话场景下的算法实践
  6. 中国十六烷基磷酸钾行业市场供需与战略研究报告
  7. Redhat 7.9安装db2 11.1.4.6 DBT3514错误
  8. 十进制转换为三进制数_python3实现
  9. redis unlink
  10. 阿里云网络和安全配置实验(云计算)