C语言详解生成随机数的过程,time函数、时间戳timer、rand函数和srand函数,附猜数字小游戏

一、准备工作(预备知识)

我们今天来实现一个小游戏:猜数字。那么既然是猜数字,我们就明白,肯定是猜随机数。问题来了,C语言怎么生成随机数?

1.1、生成伪随机数(函数rand)

这个问题,其实设计者已经帮我们解决了,就是产生随机数的一个库函数:rand,那我们一起来看看这个函数吧!
在这里插入图片描述
使用的示例如下:
在这里插入图片描述
那么我们来看看这个函数的一些注意事项,
rand returns a pseudorandom number, as described above. There is no error return.
这个函数不会返回error,也就是它一定会成功生成随机数;
The rand function returns a pseudorandom integer in the range 0 to RAND_MAX. Use the srand function to seed the pseudorandom-number generator before calling rand.
这个函数会生成“伪随机整数”(也就是只随机一次,之后的数字都确定了),这一点很重要,并且最大值是RAND_MAX,简单的说,就是一个可以被使用者定义的最大值,RAND_MAX 的值应至少为32767
在这里插入图片描述
0xfff,这是十六进制的数字:等于十进制的32767等于八进制的77777等于二进制的111111111111111

(百度结果:RAND_MAX指的是C语言标准库 <stdlib.h> 中定义的一个宏。经预编译阶段处理后,它展开为一个整数类型的常量表达式。RAND_MAX 是 <stdlib.h> 中伪随机数生成函数 rand 所能返回的最大数值。)

并且注意这句话:Use the srand function to seed the pseudorandom-number generator before calling rand也就是在调用rand函数之前,记得使用srand数字生成器,不然无法调用rand函数
在这里插入图片描述
The srand function sets the starting point for generating a series of pseudorandom integers.
在这里插入图片描述
Seed for random-number generation

1.2、伪随机数“变成”随机数(函数time)

那么我们既然只能使用伪随机数,肯定不能达到我们的要求,我们得想办法让它每次都能随机产生数字,而不是只有一次。

也就是说,只要srand数字生成器的seed的值是变化的,那么生成的数字就是变化的,所以我们需要把unsigned int seed 换成一个不停变化的值怎么换?使用时间戳。(百度结果:时间戳的主要目的在于通过一定的技术手段,对数据产生的时间进行认证,从而验证这段数据在产生后是否经过篡改。)

我们不需要理解时间戳是什么,只需要直到怎么使用就可以了。这时候我们需要了解一个函数:time:
在这里插入图片描述
它用来得到系统的时间
在这里插入图片描述
并且返回结果是响应时间,不会出错。The return value is stored in the location given by timer. This parameter may be NULL, in which case the return value is not stored.
在这里插入图片描述
这里的参数是一个指针,Storage location for time也就是可能为空指针,返回结果就是NULL
时间戳的地址

那么,这跟我们想要一个变化的值有什么关系?
别忘了,我们可以强制类型转换(并且我们不需要它的参数,参数直接写NULL,也就是我们不需要存储它的返回值,我们只使用它的返回值),这样就解决了我们的问题:

生成随机数

	srand((unsigned int)time(NULL));
	int ret = rand();
	printf("%d\n", ret);

1.3、生成确定范围随机数

那么我们怎么生成确定范围的数字?

很简单,在rand()后面进行取余如果%100,取到的值就是0-99了,那么再减去某个值,就是一个确定范围了。

比如我们想取1-100,那么就需要rand()%100+1。

代码:int ret = rand()%100+1;

二、练手随机数经典项目:猜数字小游戏

实现猜数字游戏,应该是生成随机数最经典的应用,现在我们一起来看看!

2.1完整代码:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void menu()
{
	printf("=================\n");
	printf("=====1.play=====\n");
	printf("=====2.exit=====\n");
	printf("=================\n");
}
//猜数字游戏的实现
void game()
{
	int guess = 0;
	//生成随机数
	int ret = rand() % 100 + 1;
	//猜数字
	printf("输入数字吧:\n");
	while (1)
	{
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("猜对了!\n");
			break;
		}
	}
}

int main()
{
	int input = 0;
	menu();
	srand((unsigned int)time(NULL));
	do {
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误,重新选择:\n");
			break;
		}
	} while (input);
	return 0;
}

分开来看:

2.2、menu()

menu()没什么可说的:

void menu()
{
	printf("=================\n");
	printf("=====1.play=====\n");
	printf("=====2.exit=====\n");
	printf("=================\n");
}

2.3、game()

game()是核心:
不过依然没有太多要强调的,主要注意分析大小关系就可以。

//猜数字游戏的实现
void game()
{
	int guess = 0;
	//生成随机数
	int ret = rand() % 100 + 1;
	//猜数字
	printf("输入数字吧:\n");
	while (1)
	{
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("猜对了!\n");
			break;
		}
	}
}

2.4、main()函数

之后是主函数逻辑:
那么这里主要使用了一个switch函数,对switch函数不太理解的可以看看博主的这篇超细致解说:
C语言中阶第一篇:分支和循环语句透析,包含getchar和scanf的详细介绍(本篇循环只到while)

int main()
{
	int input = 0;
	menu();
	srand((unsigned int)time(NULL));
	do {
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误,重新选择:\n");
			break;
		}
	} while (input);
	return 0;
}

运行结果:
在这里插入图片描述
那么谢谢大大的阅读哦,希望对大大有所帮助。

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值