C语言如何生成随机数——随机数原理分析

随机数介绍

在C语言中,如果想生成一个随机数,我们在百度后会很容易发现这两行代码:

srand((unsigned int)time(NULL));
int ret = rand();

为什么这两行代码就能生成随机数了呢?接下来就跟着我一起探寻其中的原理吧!

随机数是如何生成的?

C语言提供了rand函数来生成随机数,我们不妨去cplusplus.com看看吧。
在这里插入图片描述
通过图中的三个红圈我们可以大概了解到rand函数的基本信息:

1.rand函数不需要传参,并且返回一个整型变量。
2.返回整形变量的范围是0-RAND_MAX
3.使用rand函数需要包含头文件<stdlib.h>

其中,RAND_MAX的值我们可以在编译器中查看:
在这里插入图片描述

十六进制的0x7fff转换成十进制的值为32767,即rand函数返回一个0-32767之间的整型变量。

接下来我们写一个简单的程序来看一下rand函数的效果

#include <stdio.h>
#include <stdlib.h>
int main()
{
	for (int i = 0; i < 10; i++)
	{
		int ret = rand();
		printf("%d\n", ret);
	}
}

程序运行结果:
在这里插入图片描述
这时我们就发现问题了!

每一次运行该程序时,打印的结果居然是一样的?这还叫什么随机数呢?
接下来让我们重新回去再看一下官网对rand函数的介绍。

原来还有第二段话:
在这里插入图片描述
将这段话翻译一下:

这个数字是由一个算法生成的,该算法每次调用时都返回一个显然不相关的数字序列。该算法使用种子生成序列,该序列应使用函数srand初始化为某个不同的值。

原来我们还得需要使用srand函数设置随机数的生成器。那么让我们跳转到srand函数的介绍:
在这里插入图片描述
我们发现srand函数需要一个无符号整型参数,于是我们试着这样写代码:
在这里插入图片描述
怎么每次都是365呢? 那我们吧参数改为200试试?
在这里插入图片描述
打印的值又发生了变化。于是我们可以得到结论:

只需每次给srand函数传一个变化的值,我们就能打印出随机数

这时候可能大家就蒙了,我们不是需要生成随机值嘛?怎么到这了又得传随机值呢?
其实大家不必担心,这里其实只需要传一个一直在变化的值给srand函数就行,那这个值在哪里找呢?
编程是为了解决生活中的问题的,而我们生活中什么东西是一直在变化的呢?
时间,C语言提供了time函数,可以生成时间戳。 我们先介绍一下时间戳的概念:

时间戳: 当前时间与计算机起始时间的差值,单位是秒。

我们可以通过一个时间戳的转换网站来简单体会一下它。
在这里插入图片描述
好了,接下来我们去官网了解一下time函数吧:
在这里插入图片描述
我们发现time函数需要传一个指针变量作为参数,并且返回一个time_t类型的变量,而且我们在使用time函数之前,需要调用<time.h>的头文件。于是我们这样写代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
	srand((unsigned int)time(NULL));
	for (int i = 0; i < 10; i++)
	{
		int ret = rand();
		printf("%d\n", ret);
	}
}

我再解释一下为什么这样写。首先,time函数需要传一个指针参数,而我们其实想要的只是它的返回值,所以我们只需要给它传一个空指针过去就行了;而time函数的返回值是time_t类型,srand函数需要一个unsigned int类型的参数,所以我们将time函数返回的值强制类型转换成unsigned int类型。

最后让我们看看结果吧:
在这里插入图片描述
在这里插入图片描述
我们可以看到每次的值都是不一样的。这一次随机数就真的生成完成了!
最后需要注意的几点:
1.srand函数在一个工程中只需要调用一次即可,否则会出现bug。
2.rand函数生成的随机数可以用%操作符将生成的数固定在我们想要的范围内。
举一个例子,比如我们想生成10-99的随机数,我们应该这样写:
在这里插入图片描述
rand()%90得到0-89的数字,再+10得到10-99的数字。

总结

看到这里,你应该了解了随机数生成的原理了吧?随机数在C语言学习的过程中还是会经常遇到的,比如三子棋,扫雷等小游戏的制作过程中就会使用到它。这一篇博客也算是填了上一期猜数字游戏的坑了吧! 希望对你有所帮助。
文章如果有需要改进的地方请指正,希望大家一起讨论,一起进步!
在这里插入图片描述

  • 9
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值