C语言之随机数的生成---rand函数

一、 rand函数 - 产生一个伪随机数

1. 函数介绍

int rand (void);//使用时包含头文件#include<stdlib.h>

rand函数在使用的时候无需传参,调用该函数时它返回一个介于0和RAND_MAX(32767)之间的伪随机整数
例如:我们用rand函数生成10个随机数。

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

int main()
{
	for (int i = 0; i < 10; ++i)
	{
		printf("%d ", rand());//每次rand函数返回的都是不同的数字
	}
	printf("\n");
	return 0;
}

运行结果如下:
在这里插入图片描述

当我们重复运行上面的代码时,我们会发现,每次的运行结果都是一样的,这说明了这里的随机指的是,如果程序持续运行,rand返回不同的数字,而这里每次程序运行结果都是相同序列明显不相关的数字,并没有做到真正意义上的随机。这是因为rand函数生成的随机数是由一个算法生成的,该算法每次调用它时都会返回一系列明显不相关的数字。而该算法是使用不同种子来生成不同的序列,且序列使用函数srand初始化为一些不同种子。如果用rand函数之前并没有调用srand函数来初始化进去不同的种子,它就会默认为1为种子,来生成随机数序列。而我们上面的程序,就是没有用srand函数初始化不同的种子,它都默认1为种子来生成随机数序列,而相同种子生成的随机数序列是相同的,因此当我们重复运行上面的代码时,程序每次的运行结果都是一样的。接下来我们就来了解一下srand函数是如何用不同的种子来进行初始化的。

二、 srand函数

1.函数介绍

> void srand (unsigned int seed);//使用时包含头文件#include<stdlib.h>

srand函数是用来初始化随机数生成器,它只有一个参数,这个参数就是伪随机数生成器算法用作种子的整数值。
注意事项:

  • 对于srand调用中使用的不同种子值,可以使得伪随机数生成器在随后的rand调用中生成不同的连续结果。
    例如:用10作为种子和20作为种子生成随机。
#include <stdio.h>
#include <stdlib.h>

int main()
{
	srand(10);//10作为种子
	//srand(20);//20作为种子
	for (int i = 0; i < 10; ++i)
	{
		printf("%d ", rand());//每次rand函数返回的都是不同的数字
	}
	printf("\n");
	return 0;
}

10作为种子运行结果如下:在这里插入图片描述
20作为种子运行结果如下:在这里插入图片描述
从两次代码运行结果就可以验证这一说法。

  • 如果调用srand函数并将seed设置为1,则生成器将被重新初始化为其初始值,则与没调用srand函数产生相同的值。

例如:用1作为种子调用srand和不调用srand。

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

int main()
{
	srand(1);//1作为种子
	for (int i = 0; i < 10; ++i)
	{
		printf("%d ", rand());//每次rand函数返回的都是不同的数字
	}
	printf("\n");
	return 0;
}

运行结果如下:
在这里插入图片描述
把1作为种子调用srand函数生成的10个随机和上面没调用srand相比较(没调用sran函数时,种子也默认设置成1),我们不难发现两次生成的随机数是一模一样的。

  • 使用相同种子来初始化随机数生成器将在对rand的后续调用中生成相同的连续结果。

从上面用1作为种子调用srand和不调用srand的例子我们可以看出相用同种子初始化随机数生成器,将产生相同的随机数序列,这里就不在举例,读者下去可自行测试。
我们如何才能使得程序每次运行的时候让srand自动获取到不同的种子呢?接下来我们介绍一下time函数便可以知晓答案。

三、 time函数

1.函数介绍

time_t time (time_t* timer);//使用时包含头文件#include<time.h>

time函数的功能是获取当前时间,并返回自1970年1月1日00:00到当前时间以来的秒数(时间戳),time函数只有1个参数,如果参数不是空指针,它还会将计算的时间戳存储在指针指向的变量中,该参数也可以是空指针,在这种情况下,不使用该参数,但函数仍然返回时间戳。
例如:计算当前时间的时间戳。

#include <stdio.h>
#include <time.h>
int main()
{
	printf("1970年1月1日00:00到当前时间以来的秒数:%d\n", time(NULL));
	return 0;
}

运行结果如下:
在这里插入图片描述当我们每次运行上面打的代码的时候会发现,每次打印的数字都不一样,这是因为每次运行程序的时间不同,time函数返回的时间戳就不同,因此我们可以用time函数返回的时间戳当作srand初始化随机生成器的种子。
注意事项:

  • srand的参数类型是unsigned int,而time函数的返回值是time_t,因此把time函数的返回值当srand函数的参数时,需要强制类型转换一下。
  • 而我们也不需要time函数通过参数把时间戳存储起来,因此可以给传一个空指针(NULL)。
    代码如下:
  • srand函数在每次程序运行的时候在调用rand函数之前调用一次即可,只需要保证这次运行程序的种子和下次运行程序的种子不同。
srand((unsigned int)time(NULL));

四、rand函数简单应用

1.rand函数生成[a, b]范围内的数字

  • 我们知道,如果我们要想生成1~100内的随机数,只需要用生成的随机数%100,就能得到 0~99之间的数字,然后在此基础上+1,即可得到,即
    rand() % 100 + 1。
  • 因此我们要生成[a, b]范围内的数字,只需要用生成的随机数%(b-a+1),就能得到 0~(b-a)之间的数字,然后在此基础上+a,即可得到[a, b]范围内的数字,即
    rand() % (b-a+1) + a

2. 猜数字游戏实现

  • 游戏规则:系统随机生成一个1~100的数字,让玩家来猜,若玩家猜大了,提示玩家猜大了,并让其重新猜,猜小了也同理,直到玩家猜对为止。
    代码如下:`
//猜数字游戏
//数字范围 0 ~ 100
#include <time.h>
#include <stdlib.h>

//打印菜单
void menu()
{
	printf("******************************\n");
	printf("********** 1. play ***********\n");
	printf("********** 0. exit ***********\n");
	printf("******************************\n");
}
//游戏逻辑
void game()
{
	int guess = 0;
	int ret = rand() % 100 + 1;//生成随机数
	while (1)
	{
		printf("请输入你要猜的数字>:");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了\n");
		}
		else if (guess < ret)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你,猜对了!!!\n");
			break;
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//使用rand函数之前需要调用srand函数,设置随机数的种子,每次程序运行的时候调用一次即可
	do
	{
		menu();
		printf("请输入你的选择>:");
		scanf("%d", &input);

		switch(input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("输入错误,请重新输入\n");
				break;
		}
	} while (input);
	return 0;
}

若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !
在这里插入图片描述

  • 18
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值