计算机的运行是通过代码来进行的,而代码的执行需要确定的数字,即计算机的运行过程是一个确定的过程,计算机的运行过程是一个确定的过程,所以不可能产生一个真正有意义的数字,即计算机只能产生伪随机数。
引用随机数需要引用头文件
#include
1.随机数函数
(1) c 提供产生随机数的函数:
rand(),原型为:int rand(void);
rand() 产生一个 [0…rand_max] 之间的数字,rand_max是可以产生的最大随机数(2^31-1),是一个常量:
#define rand_max ox7fff
(2) 使用:
生成[0…max-1]之间的随机数:
rand()%max //这个表达式会生成[0..max-1]之间的随机数
2.随机数种子
直接使用rand()确实可以产生随机数,但是有一个问题:发现每一次 rand()产生的都是同一个值,不信你试试:
#include
#include
using namespace std;
int main()
{
cout<
这就和我们所说的随机数种子有关了。
种子函数:srand(seed);原型为:void srand(unsigned seed);
如果我们在使用 rand()之前 ,如果不写srand(seed),那么就会默认调用 srand(1),这就是问题所在:
rand()看似是产生一个随机数,但是实际上就是rand()在一个固定的数字序列不断取值生成所谓的随机数,而这个数字序列是由srand(seed)产生,数字序列的数字大小和排序由seed确定,只要seed相同,生成的随机数列就是一样的。
比方说,我执行10次rand()
#include
#include
using namespace std;
int main()
{
cout<
发现输出结果都是一样的。
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
这就说明在我的电脑里 srand(1)产生的数字序列就是
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
…… ……
当然,不同的电脑可能是不一样的。
当产生一个序列之后,只要不更新队列,每调用一次rand(),rand()就会从上到下依次取值给程序使用,但是若途中调用srand(seed)更新队列,rand()就会从新队列的头再开始依次向下取值。
eg:
#include
#include
using namespace std;
int main()
{
cout<
输出:
41
18467
6334
26500
19169
41
18467
6334
26500
19169
过程分析:
3.产生真正的随机数
根据前面的说明我们知道,需要再让seed动起来才能产生近似随机的伪随机数。
所以我们可以使用系统的时间来做种子,系统的时间是不断变化的,符合我们更菜的要求。
系统的时间获取:time(null)
,单位是s
它的头文件是:
#include
eg:
#include
#include
#include
using namespace std;
const int maxs=10;
int main()
{
srand(time(null));
for (int i=0; i<=10; i)
{
cout<
第一次运行
17717
21613
1852
28959
371
10155
11222
1420
9654
23944
19598
第二次运行
17894
12203
16245
17658
302
25591
15455
7187
16544
19629
11611
发现是不一样的数据。
4.问题
执行如下代码
#include
#include
#include
using namespace std;
int main()
{
for (int i=0; i<=10; i)
{
srand(time(null));
cout<
发现执行结果是一样的数据
18299
18299
18299
18299
18299
18299
18299
18299
18299
18299
18299
这是因为srand(seed)
每执行一次就更新一次数字序列,并且将rand()的指向放在序列首部;而程序的运行效率很快,不到1s就执行完循环,seed还没来的及改变,每次产生的数字序列一样,所以每个rand都是取序列首部数据,就是一样的了。
所以说还是不能真正地完全实现随机数的产生。