先明白一点:计算机的真随机不存在,只有伪随机
为了方便理解,我们先介绍一个生活中实现伪随机的方式之一:
随机数表
随机数表大概在中学阶段学过;
大概内容是一个写满数字的表格,上面的内容是看起来随机的数字;
下面展示下随机数表的样子:
那么随机数表怎么用呢?
比如张三的骰子丢了,现在需要随机数表来模拟骰子的功能,进行五次掷骰子操作,以下为具体步骤:
1. 随便找一个起点,比如确定起点为第二行第六个数字;
因为我们需要五次骰子的结果,所以我们取五个数字,从第二行第六个数字到第二行第10个数字: 24 02 94 08 63;
问题来了:骰子只有1,2,3,4,5,6一共6个结果,但表里的数字是俩位数,所以我们需要一个转化操作;
2.将随机数转化为需要的值
将取到的数字除以6可以得到一个余数 ,余数可能的结果为0 1 2 3 4 5,再将余数+1,便可以得到1,2,3,4,5,6六种扔骰子结果;
以上便是通过随机数表得到随机数的方式。
c语言实现随机数
这里我们再来将c语言的随机数生成办法,实现原理和利用随机数表相似;
例如我们需要1~100之间的随机数,我们分三步来讲:
1.找到“随机数表”
2.给“随机数表”一个“起点”
3.转化随机值为我们需要的范围
1.找到“随机数表”
我们需要一个生成随机数的函数:rand() 他可以为我们随机生成0~32767之间的随机数;
这个函数是别人创造的,我们要用的时候要申明一下,声明rand()的头文件为#include<stdlib.h>;
这个函数就像随机数表,如果不设置一个种子(起点),那么每次执行产生的随机数都是固定的,下面是代码举例:
#include<stdio.h>//包含printf()
#include<stdlib.h>//包含rand()
int main()
{
int ret = 0;
ret = rand();
printf("%d", ret);
return 0;
}
每次运行输出结果都是一样的41,运行效果如下
所以下一步我们需要安排一个起点解决每次运行都一样的问题
2.给“随机数表”一个“起点”
有一个函数专门用来设置“起点”:srand(),这位函数同样来自stdlib.h,括号内需要填入的内容是无符号整数,也就是正整数,在c语言表示为unsigned int;
那么问题来了,我们要实现每次运行都是不一样的起点,那如何让起点每次都不一样呢?
首先我们排除随机数,不然这是个先有蛋还是先有鸡的问题了;
我们不需要里面的“起点”每次是随机的,只需要保证每次都不一样就行了;
那么这样的变量哪里去找呢?现实里有没有这样的东西呢?还真有,那就是时间,每一刻的时间都是独一无二的,我们可以用时间作为“起点”
这里我们引入另一个东西------时间戳:
时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒;
为什么是从1970年开始算起?因为这某种意义上算是计算机的生日;
我们需要一个函数来生成这个随时都在变化的时戳放在srand()里,生成时间戳的函数长这样: time(),由于这个函数也是别人创造的,我们要用的时候还是要申明一下,在代码里加上#include<time.h>就可以用了
看起来我们只需要在代码里加上srand(time());就解决了随机数种子(起点)的问题
这里还有个小问题,time()产生的数不是无符号整数类型,所以我们还需要进行一步强制类型转化,让他俩能对的上;
具体做法是 time()前面加上类型:(unsigned int)time() ,把这个参数放在srand()里:
srand((unsigned int)time(NULL));
ok我们直接用上面的代码改一改试试效果:
#include<stdio.h>//包含printf()
#include<stdlib.h>//包含rand()
#include<time.h>//包含time函数
int main()
{
srand((unsigned int)time(NULL));
int ret = 0;
ret = rand();
printf("%d", ret);
return 0;
}
这下我们可以每次都启动程序都有不一样的随机值了 ,运行效果:
3.转化随机值为我们需要的范围
现在只剩一个简单问题了,我们已经实现了生成0~0~32767的随机数;现在我们需要把这个随机数转化为我们需要的数值范围,比如我们需要随机生成101到200的数字:
#include<stdio.h>//包含printf()
#include<stdlib.h>//包含rand()
#include<time.h>//包含time函数
int main()
{
srand((unsigned int)time(NULL));
int ret = 0;
ret = rand()%100+101;//取余数操作
printf("%d", ret);
return 0;
}
加一个取余数操作(除以100获得余数),余数范围是0~99,再加上100就实现了产生101到200随机数的功能