目录
1.rand函数 2.time(0)3.srand(time(0))
1.rand函数
(1)由下表我们可知rand()函数是用来生成随机数的。
我们不需要向它传入任何参数,直接能用,而且我们用的就是它的返回值。
库函数 | 在标头 <stdlib.h> 定义 |
int rand(); | 1.返回 0 与 RAND_MAX 间的随机整数值(包含 0 与 RAND_MAX ) 2.RAND_MAX展开成等于函数 rand() 最大返回值的整数常量表达式。此值为实现定义。标准保证此值至少为 32767 。 |
(2)例如下面这个例子,我们用它来随机生成5个整数
// 1.利用&&进行格式控制,i == 0是逻辑短路,后一句不执行
// 2.printf的返回值是输出字符的个数,因此前一句只要正确,printf必会执行
运行结果:
test.c
从这视频可以看出两个问题:
(1)生成的数值太大,我想让它在某一特定的数值范围内生随机数
(2)每一次运行的结果一样,rand()函数好像不随机(这个问题很fatal(致命))
如何解决这两个问题呢 ?
a.我们先看第一个问题,这个问题很简单,我们只需要两个运算符:+ 和 %(取余数运算符)
int val = rand() % 100 + 20;
如上面这段代码,我们先用了%,这让生成随机数对100取余,余数是不能大于除数,所以余数的上限被卡在99,
也就是任何一个生成的随机数它对100取余最大也就99,后面+20是吧下限从0提至20,但是由于+20对上限也起作用,故上限变为119(原理:我们是对取余的结果加20),最终我们将随机数范围限制到20~119之间(包含20和119)
summary:我们对一个整数x取余,取余结果一共有x个数(min = 0 , max = x-1),我们对取余结果进行加减同时改变了上下限,但加减不改变随机数总个数,%才改变随机数总个数(因为不同的数作除数,余数范围是不一样的)。
b.对于第二问题我们先弄清楚它产生的原因:
rand函数生成的数字被称为伪随机数,因为它们实际上是通过确定性算法生成的,而不是真正的随机数。计算机程序无法直接获得真正的随机数,因为它们是基于确定性逻辑的。计算机程序的运行是由输入、状态和算法组成的,因此对于给定的输入和状态,程序将产生相同的输出。这种确定性性质意味着如果使用相同的种子(即初始状态),rand函数将生成相同的序列。
随机数种子(random seed)是在生成伪随机数时使用的起始值或者初始状态。使用相同的种子将导致生成相同的随机数序列。rand()
函数的随机数种子默认为1。这意味着如果你只使用rand()
函数生成随机数,每次程序运行时都会得到相同的随机数序列。
上面两段话总结一下就是:随机种子数不变,生成的随机数不变
我们知道原因后如何解决呢?很简单:我们要不断改变随机数种子(同样种子开同样的花,不同的种子开不同的花)
2.time(0)
正如我在一中所说的,我们要不断改变随机数种子,time(0)就是一个很好的种子,因为它不断改变
在C语言中,time(0)
函数用于获取当前时间,以自Unix纪元(1970年1月1日00:00:00 UTC)以来的秒数表示。
3.srand(time(0))
我们下载已经有了种子,我们缺什么呢?答案很明显:我们却缺少播种的方法,而srand()函数就是播种机,专门来播种的。
在标头 | ||
void srand( unsigned seed ); | ||
srand以值 seed
播种 rand() 所用的随机数生成器。
这里srand以time(0)播种,由于种子数time(0)不断变化,rand()所用的随机数生成器的起始输入也不断变化,“随机数”终于“随机”。(同样种子开同样的花,不同的种子开不同的花)
补充:
-
随机数种子是一个起始输入,它用于初始化随机数生成器。它可以是任何值,通常是一个整数。相同的种子将生成相同的随机数序列。这是因为随机数生成器使用种子作为起点,并根据特定算法生成一系列随机数。如果种子相同,随机数生成器将按照相同的顺序生成相同的数字序列。因此,种子决定了随机数序列的起点。
-
随机数生成器(Random Number Generator,RNG):随机数生成器是一个算法或程序,用于生成随机数。它接收一个种子作为输入,并根据预定义的计算规则生成随机数序列。常见的随机数生成器包括伪随机数生成器(PRNG)和真随机数生成器(TRNG)。PRNG使用确定性算法生成伪随机数序列,而TRNG使用物理过程来获取真正的随机性。
注意:time()函数在<time.h>头文件下
最后总结:rand()函数不随机是因为随机种子数不变,我们选取一个变化的种子time(0),用播种机srand()播种,最终不同的的种子就会开不同的花,我们也就得到不同的随机数序列
改动后的代码和视频
test_Upgrade.c