《嵌入式工程师自我修养/C语言》系列—— 生成的随机数序列每次都一样?rand和srand解析!
快速学习嵌入式开发其他基础知识?>>>>>>>>> 返回专栏总目录 《嵌入式工程师自我修养/C语言》<<<<<<<<<
首先要知道的是 rand()
和 srand()
都是C语言标准库中的函数,因此在使用前需要包含头文件 #include <stdlib.h>。
一、int rand(void);——随机数发生器
该函数可以产生随机数,但是不是真正意义上的随机数,而是一个伪随机数,其返回值是0至RAND_MAX 间的某个数值,RAND_MAX的范围最少是在0~32767之间(int),用unsigned int 双字节就是65535。
该函数的作用原理可以简单理解为以某个数为基准(我们称这个数为种子: seed),然后根据某个递推公式推算出来的一系列数,当这一系列数足够多的时候,就符合正态分布,即相当于产生了随机数。但是,计算机正常开机后,seed的值是确定了的(若用户没有设定seed的值,则系统默认赋值为1)。这就导致,每次运行该段代码时产生的随机数序列是相同的,如下所示:
//循环产生5个随机数并打印
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int i;
for(i=0; i<5; i++)
{
cout<<rand()<<"\t";
}
cout<<endl;
return 0;
}
两次运行产生的结果如下所示:
可见程序产生的五个数确实是随机数,但是实际上每次运行产生的都是一样的随机数序列。为解决该问题,srand()
函数登场。
二、void srand(unsigned int seed);——初始化随机数发生器
关于该函数,需要注意的是:
- 参数seed必须是个整数,通常可以用
time(0)
的返回值来当作seed; - 如果每次seed都设置相同的值,rand每次所产生的随机数的值就会一样。
基于以上信息,我们在调用随机数生成器rand()
之前,调用一次 srand(time(NULL))
。需要注意的两点:
- 包含头文件
time.h
; - 调用语句需要放到循环的外面,不然每次产生的几个随机数都是一样的,因为时间一样。
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main()
{
int i;
srand((unsigned)time(NULL));//初始化随机数种子
for(i=0; i<5; i++)
{
cout<<rand()<<"\t";
}
cout<<endl;
return 0;
}
两次运行产生的结果如下所示:
综上:rand()
和srand()
要一起使用,其中srand()
用来初始化随机数种子,rand()
用来产生随机数。
因为默认情况下随机数种子为1,而相同的随机数种子产生的随机数是一样的,失去了随机性的意义,所以为使每次得到的随机数不一样,用函数srand()
初始化随机数种子。srand()
的参数,用time
函数值(即当前时间),因为两次调用rand()
函数的时间通常是不同的,这样就可以保证随机性了。
三、如何产生给定范围内的随机数?
目前遇到的有以下几种情况,如遇到其他情况不在下列范围内,欢迎补充!
- 取 [ a,b ) 间的随机数:
( rand() % (b-a) ) + a
; - 取 [ a,b ] 间的随机数:
( rand() % (b-a+1) ) + a
; - 取 ( a,b ] 间的随机数:
( rand() % (b-a) )+ a+1
; - 取 0~1 间的浮点数:
rand() / double(RAND_MAX)
。