目录
一、rand函数
二、srand函数
三、time函数
四、生成指定范围内的随机数
一、rand函数
我们想要生成一个随机数,可以使用rand函数(随机数生成器),rand函数定义在<stdlib.h>头文件中。它的函数原型如下:
int rand(void);
它能返回一个 0~RAND_MAX 之间的整数,RAND_MAX的大小由编译器厂商设定,但一般是32767。可以设置多个随机数试一下:
重复运行上面的程序,会发现每次的执行结果都一样,这样就失去了随机数的意义。实际上rand生成的是伪随机数,这种随机数是按照规定的算法以设置的“种子”值为基准计算出来的,所以本质上是不随机(按照某种规则生成)的。因为rand默认种子值是1,所以算法计算的结果都是一样的。如果想让每次运行的结果都不同,那么需要让种子值变化起来。
二、srand函数
srand函数就能用于设置rand函数的种子值(初始化随机数生成器),它也定义在头文件<stdlib.h>中,其函数原型如下:
void srand(unsigned int seed);
现在又有一个问题,如果我们需要让种子值随机,但是我们想解决的就是rand生成随机数的问题,那不就矛盾了吗?我们不能得到随机的种子值,但是能得到变化的种子值,比如根据时间而变化。
三、time函数
time函数能获得当前的时间戳,时间戳就是当前的时间与计算机的初始时间1970年1月1日0时0分0秒之间的差值,以秒为单位。它定义在<time.h>头文件中,其函数原型如下:
time_t time(time_t *timer);
可以看看VS2019 的 time_t的定义:
#ifndef _CRT_NO_TIME_T #ifdef _USE_32BIT_TIME_T typedef __time32_t time_t; #else typedef __time64_t time_t; #endif#endiftypedef long __time32_t;typedef __int64 __time64_t;
本质上 time_t 是32位或64位整型。当time的参数非NULL时,time函数不仅会返回时间戳,还会把返回的时间戳存储在timer指向的内存空间里;当参数为NULL时,time函数只返回时间戳。
现在有了rand函数、srand函数和time函数,就能生成每次运行都不一样的随机数了,如下:
第一次运行
第二次运行
最后我们要注意的是,程序中随机数种子只需要设置一次就行了,不要把它放在循环里面,比如这样:
这样会导致每一轮循环生成的随机数都是一样的,因为程序执行得很快,很多轮循环都会发生在同1秒内,导致时间戳没变,设置的种子值也就不变了。可以看看我把循环次数改为1000后(时间延长),首尾的循环轮次生成的随机数是有变化的:
前面的循环生成的随机数
最后面的循环生成的随机数
四、生成指定范围内的随机数
//生成1~100之间的随机数rand() % 100 // 0~99rand() % 100 + 1 // 1~100//生成100~200之间的随机数100 + rand() % (200 - 100 + 1)//生成a~b之间的随机数a + rand() % (b - a + 1)
五、更正
更正一下,上面的要写成srand((unsigned int) time(NULL))更规范,因为time函数返回值是time_t类型,srand函数参数是unsigned int类型的。如果不强制转换VS上也会有警告。为了代码的可移植性和正确性,还是加上比较好。