个人对rand()、srand()函数之间的关系及其内部实现原理的猜测

欢迎转载,转载请注明出处,谢谢

//首先我们先只看rand()函数,有函数如:
int main(int argc,char* argv[])
{
	int tmp=0;
	for(int i=0;i<50;++i)
	{
		// 获取 0~19 的伪随机数,存入tmp中
		tmp=rand()%20;
		cout<<tmp<<'\t';
	}
	cout<<endl;
	cin.get();
	cin.get();
	return 0;
}


其执行结果如下图:

多执行几次,你会发现该随机数表与时间是无关的,到这里我们还没有什么思路可以猜测其内部

实现原理,只知道没有用srand()设置时间种子的rand()函数返回的其实是可记录的值

//现在我们再来看下面的函数执行结果
int main(int argc,char* argv[])
{
	// time(0);返回的是从格林尼治时间到当前时间的间隔(单位:秒)
	srand((unsigned int)time(0));
	int tmp=0;
	for(int i=0;i<50;++i)
	{
		// Mark .
		// 获取 0~19 的伪随机数,存入tmp中
		tmp=rand()%20;
		cout<<tmp<<'\t';
	}
	cout<<endl;
	cin.get();
	cin.get();
	return 0;
}

OK,现在我们发现每次运行输出的随即数列是不一样的,这说明srand()和rand()直接存在一定的联系(这不废话么,嘿嘿)现在关键的步骤来了,将上面的srand((unsigned int)time(0));函数剪切到Mark行下面,再编译执行,发现所有的输出值都是一样的;为什么会这样呢,你先关掉程序,再重新执行,发现输出序列仍然是一样的,但是值和上一次不同了,这时候我们就可以来猜想一下它的内部实现方式了;

先复习一下高中数学对函数的定义之一:对于给定的自变量(可以是多元函数),只有一个因变量与之对应的方程才能称之为函数,例如以x为自变量,y为因变量则x^2 + y^2 =1 就不是函数,x=0时,y有两个值与之对应,现在开始将正文。我个人的猜想是这样的:rand()函数每次只得出一个特定的值(因变量),但是得出这个值需要依赖于某个或某些变量(即是前面讲的自变量)的值,而如果我们没有设置时间种子的话程序 第一次 执行rand函数,自变量的初始值都是同一个定值,所以每次执行程序输出的随机值都一一对应。但是为什么rand()在同一次程序执行时能够生成不同的数呢(伪随机数列),我个人分析是这样:rand()在计算出返回值,且在返回它之前会通过某种算法改变因变量的值所以在下一次调用rand()函数时,由于因变量的值与上次不一样了,所以计算出的返回值自然也就很可能不同;那srand()函数与rand()函数有什么关系?我认为srand函数可以改变rand函数依赖的自变量的值,所以设置时间种子后,rand函数依赖的自变量值与默认的或设置其它时间种子所得到值不一样,当调用rand函数计算返回值时,由于自变量不同,故而返回值不同,但是请注意,rand函数返回值之前仍然会调用某个算法来改变自变量的值,从而导致同一次程序执行中调用rand的返回值与上次调用返回的值不同。

//为了验证srand和rand之间确实有共享数据(因变量)
//我写了个简单的测试程序:
int main(int argc,char* argv[])
{
	int tmp=0;
	for(int i=0;i<50;++i)
	{
		srand(0);
		// 获取 0~19 的伪随机数,存入tmp中
		tmp=rand()%20;
		cout<<tmp<<'\t';
	}
	cout<<endl;
	cin.get();
	cin.get();
	return 0;
}
//输出结果每次都是一样的,这说明尽管rand改变了因变量的值

//但是srand都会用0将因变量重置(不一定是将0赋值给因变量)

//所以每次输出都是一样的,这也可以很好的解释在上面我们将

//srand((unsigned int)time(0));剪切至Mark处为什么每次输出

//都一样,这是因为程序执行很快,以至于每次time(0)返回的都

//是同一个数,故rand返回值也就一样咯。

所以我们自己也可以写个rand函数来产生“随机数”,不过改变因变量的算法及计算返回值的算法要好一点

以上全都是个人的猜想(不过我认为原理上应该是这样的),如果有什么不对,还望各位指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值