C语言rand()函数产生随机数详解

1.rand函数的原型,功能和界限

rand函数的原型:

#include <stdlib.h>

int rand(void);

rand函数的功能: 用来产生一个随机数

rand函数的界限: stdlib.h头文件中有宏#define RAND_MAX 0x7fff,这表示rand产生一个0-0x7fff的随机数,即最大是32767的一个数

2.用rand函数获取随机数

rand函数获取随机数的基础用法为:

rand()%a;

a是一个整数,返回值为0到a的随机数,包含0,但不包含a。

如果想要产生一个0-99之间的随机数,那么用法如下:

int num = rand() % 100;

如果想要产生一个1-100之间的随机数,那么用法如下:

int num = rand() % 100 + 1;

同理,如果想要产生一个1-60之间的随机数,那么用法如下:

 int num = rand() % 60 + 1;//产生一个1-60之间的数

从上面的例子中我们可以推理出m-----n的随机数:

rand()%(n-m+1) + m;

比如获取15~43的随机数:

rand()%29+15;

获取小数:
我们只需要将返回值除以10或者其他合适的数,并且在输出时保留若干位小数就可以获取随机小数。

在这里插入图片描述

这里一定要用10.0,不能用整型。

3.随机数生成原理

我们先来看看下面这段代码,反复运行该段代码,我们会发现每次产生的随机数的值都是相同的。

#include<stdio.h>
#include<stdlib.h>


int main()
{

	int ch = rand();
	printf("%d\n", ch);
	
	return 0;
}

这是因为rand函数产生的随机数是伪随机数,它除了被a的值控制外,还被一个隐藏的全局变量seed控制。它实际上是根据a和一个种子按照某个公式推算出来的。

在调用rand函数之前,会先查询是否主动调用过srand(seed)来为伪随机数生成器设定种子,如果有,那么就按照我们的代码设定种子,即初始化seed的起始值,若没有调用srand(seed),那么系统会自动给seed赋初始值,即自动调用srand(1)一次,也就是将seed的值设置为1。如果每次调用rand函数时,种子相同,那么根据公式产生的伪随机数将是相同的。

上面那段代码因为每次运行程序你都没有主动调用srand函数给seed赋值,因此每次都会默认调用srand(1),将seed的值赋值为1,也就是每次seed的值都相同,所以产生的伪随机数不会发生变化。

所以为了让每次产生的随机数不相同,那么我们就需要让每次调用rand函数之前设定的种子不相同,我们可以使用系统时间作种子srand(time(NULL);由于每次运行程序的时间肯定不相同,那么每次设定的种子也就不相同,那么产生的随机数肯定也就不一样了。

srand函数的原型:

#include<stdlib.h>
void srand( unsigned int seed );

我们使用time函数来获取系统时间,time函数的原型如下:

#include<time.h>
time_t time(time_t *tloc);//time_t类型被定义为一个长整型

使用time函数得到的值是一个时间戳,即从1970年1月1日0点到现在时间的秒数,然后将得到的time_t类型数据转化为(unsigned int)的数,再传给srand函数,用法如下:

int main()
{
	srand((unsigned int)time(NULL));
	int ch = rand();
	printf("%d\n", ch);
	
	return 0;
}

添加了srand((unsigned int)time(NULL));之后,当你再次运行该段代码时,你就会发现,每次生成的随机数就不同了。

如果仍然觉得时间间隔太小,可以在(unsigned int)time(0)或者(unsigned int)time(NULL)后面乘上某个合适的整数。 例如,srand((unsigned int)time(NULL)*10),time的参数传NULL表示不需要经过参数得到time_t数据。

还有另外一种初始化种子的方式如下,用进程的pid作为种子值seed,在同一个程序中,这样的种子的值是相同的。

srand((unsigned int)getpid());
  • 209
    点赞
  • 866
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北冥有鱼丶丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值