C++随机数的产生和使用

电脑的随机数都是伪随机,也就是通过一定的算法得出一个数列,然后每 rand()一次就取一个数。而srand()的功能就是就是设置产生随机数的公式的参数(随机数种子),如果使用相同的种子,那么得到的随机数也就是相同的。自然,如果使用不同的种子,得出的随机数序列也是不同的。不同的种子会得到固定的不同的随机数序列。

一、随机数的产生

需要包含这两个头文件

#include <stdlib.h>
#include <time.h>

这个函数可以产生在最大值和最小值之间的随机数

int GetRandomValue(int min, int max)
{
	int randValue;
	srand(unsigned(time(NULL)));  //产生随机数种子
	randValue = min + rand()%(max - min + 1) ;  //生成随机数
	return randValue;
}

二、srand和rand的解释

srand函数是随机数发生器的初始化函数。

原型:void srand(unsigned seed);

用法:

它需要提供一个种子,这个种子会对应一个随机数,如果使用相同的种子后面的rand()函数会出现一样的随机数。如: srand(1); 直接使用1来初始化种子。不过为了防止随机数每次重复常常使用系统时间来初始化,即使用 time函数来获得系统时间,它的返回值为从 00:00:00 GMT, January 1, 1970 到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型再传给srand函数,即: srand((unsigned) time(&t)); 

还有一个经常用法,不需要定义time_t型t变量,即: srand((unsigned) time(NULL)); 直接传入一个空指针,因为你的程序中往往并不需要经过参数获得的t数据。srand((int)getpid()); 使用程序的ID(getpid())来作为初始化种子,在同一个程序中这个种子是固定的。


rand则是通过srand的初始化和内部算法获得随机数

用法是rand()%num

三、反例

电脑的随机数都是伪随机,也就是通过一定的算法得出一个数列,然后每 rand()一次就取一个数。

而srand()的功能就是就是设置产生随机数的公式的参数(随机数种子),如果使用相同的种子,那么得到的随机数也就是相同的。自然,如果使用不同的种子,得出的随机数序列也是不同的。

不同的种子会得到 固定 的 不同的随机数序列。


例如:

void main()
{
srand(1);
cout<<rand()<<endl;
cout<<rand()<<endl;
srand(1);
cout<<rand()<<endl;
cout<<rand()<<endl;
srand(2);
cout<<rand()<<endl;
cout<<rand()<<endl;
srand(2);
cout<<rand()<<endl;
cout<<rand()<<endl;
}

输出结果:

41

18467

41

18467

45

29216

45

29216

由于通过srand(1)和srand(2)设置了不同的随机数种子

所以产生了两组不同的随机数,这组数与种子相对应。


那么怎么利用rand产生真正的“随机数”呢?

答案是通过srand(time(NULL))使得随机数种子随时间的变化而变化。

PS:time函数可以获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。

而如果是循环获取呢,那就应该这样写,应该把种子写外面,然后获取随机数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, const char * argv[]) {
    srand((unsigned)time(NULL));
    for (int i=0; i<5; i++) {
        int kk=rand()%10;
        printf("%d",kk);
    }
    return 0;
}

那为什么不写在循环体里面呢?

比如写成这样

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, const char * argv[]) {
    for (int i=0; i<5; i++) {
        srand((unsigned)time(NULL));
        int kk=rand()%10;
        printf("%d",kk);
    }
    return 0;
}

time(NULL)返回的是系统的时间(从1970.1.1午夜算起),单位:秒,而那个循环运行起来耗时连0.000001秒都不到! 也就是说,srand(time(NULL)) 连着4次的种子是一样的,种子一样,生产的随机数当然是一样了。

如果你在把srand()放循环里面,在中间加个sleep函数,消耗一点时间(间隔大于1秒),那么生成的rand 就不一样了.但是这样做很不好,连着两次用srand生成的种子,间隔一样,生产的随机数间隔有会有规律性。

另:因为两次运行同一程序的时间肯定是不一样的,所以把srand放在循环前面可以得不同的种子,这样才能得到你想要的。

Last modification:January 1st, 1970 at 08:00 am
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment