C语言rand随机数知识解析和猜数字小游戏

rand随机数

rand

C语言中提供了一个可以随机生成一个随机数的函数:rand()
函数原型:

int rand(void);

rand函数返回的值的区间是:0~RAND_MAX(32767)之间。大部分编译器都是32767。

#include<stdlib.h>
int main()
{printf("%d", RAND_MAX);return 0;
}

在这里插入图片描述
要想使用这个rand函数需要包含头文件:#include<stdlib.h>
但是rand函数直接使用是提供的伪随机数,这个随机数是有有迹可循的,没有实现真正的随机,这是因为它生成这个数是基于一个确定的算法而生成的。

int main()
{int x = rand();int y = rand();printf("%d  %d\n", x, y);return 0;
}

执行第一次:
在这里插入图片描述

执行第二次
在这里插入图片描述

可以看出两次执行的随机数相同,所以单纯使用rand函数生成不了真正的随机数。
所以,要想真正实现随机生成,需要使rand() 函数基于一个种子(seed)来生成,默认情况下,这个种子是1。
每次调用 rand(),它都会基于前一个随机数生成下一个随机数。这意味着如果你多次使用相同的种子调用 rand(),你会得到相同的随机数序列。

srand

C语言又提供了一个初始化随机数的函数:srand()
函数原型:

void srand(unsigned int seed);

注意:seed的数据类型是unsigned int
在程序中显示有srand函数确定一个种子,只要种子在变化,rand()函数生成的随机数也就在变化。也就是说只要srand的种子是随机的,rand就能生成随机数,在生成随机数的同时又生成一个随机数,这就矛盾了。所以种子的随机不能由我们来确定,所以我们交给time()函数

time

在程序中我们一般使用程序运行时间作为种子的,因为时间时刻在发生变化,就省去我们去随机种子了。
在C语言中有一个表示时间的函数:time()
函数原型:

time_t time(time_t* timer);

timer是一个可选的参数,如果提供了这个参数,那么函数会将返回的时间(从1970年1月1日00:00:00 开始到现在的秒数)存储在这个参数指向的变量中。如果这个参数是NULL,那么函数只返回时间值而不存储它。
要想使用time(),需要头文件:#include<time.h>
代码实现:

#include<time.h>
#include<stdio.h>
int main() {printf("%d",time(NULL));return 0;
}

在这里插入图片描述

这是一个时间戳,就是从1970年1月1日00:00:00 开始到现在的秒数。

  1. 先在浏览器中找一个可以转换时间戳的网站
    在这里插入图片描述

  2. 将代码结果复制并放在转换工具里,就可以看到当前时间
    在这里插入图片描述

所以我们用time()函数的返回值充当srand()函数的参数,就可以返回一个随机值了。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main() {srand((unsigned int)time(NULL));int x = rand();int y = rand();printf("%d %d\n", x, y);return 0;
}

执行第一次:
在这里插入图片描述

执行第二次:
在这里插入图片描述

这样就可实现随机值生成了。

设置随机数的范围

当我们可以生成随机数的时候就可以设置随机数生成范围了,上文说过随机数生成范围是0—32767,我们可以要rand()%100就可以得到得到0—99之间的数了,这是因为不管什么数对100求余,只能得到0—99的数。
所以:

生成0~99之间的随机数

rand() %100

生成1~100之间的随机数

rand() %100+1;

生成a~b之间的随机数

a + rand() % (b-a+1);

猜数字小游戏

问题:

写一个随机猜数字小游戏,只有10次机会,超过则失败

规则

  1. 电脑自动生成1~100的随机数
    2.玩家猜数字,猜数字过程中,根据数据的大小给出大了或者小了的反馈,在10次猜测中,猜对了,则游戏结束。

代码实现

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void interface(void) {//游戏界面printf("******************\n");printf("****1 游戏开始****\n");printf("****2 退出游戏****\n");printf("******************\n");
}
void game(void) {int type = 10;//只有10次猜测机会int result = rand() % 100 + 1;//产生1~100之间的随机数int guess = 0;while (type) {//只有还有机会时才进入循环printf("还有%d次机会", type);printf("请猜测数字:>");scanf("%d", &guess);if (guess < result) {printf("猜小了\n");}else if (guess > result) {printf("猜大了\n");}else {printf("恭喜!猜对了\n");break;}type--;//while循环一次机会少一次}if (type == 0) {printf("机会用完了,答案是:%d\n", result);}
}
int main() {//控制是玩游戏还是退出游戏srand((unsigned int)time(NULL));//设置种子,以确保生成正确的随机数int n = 0;do {interface();//调用界面函数printf("请选择:>");scanf("%d", &n);//选则游戏模式switch (n) {case 1:game();break;case 2:printf("游戏结束\n");break;default :printf("选择错误,重新选择:>\n");break;}} while (n);//当选则了再进入循环return 0;
}

在这里插入图片描述

易错点

这段代码可能有几个易错点,我一一指出:
1.
在这里插入图片描述
如果把产生随机数的代码放在循环里面,那么每次猜测都是一个新的随机数,那么只有一次机会可以猜测。
2.
在这里插入图片描述
这里把大小于关系写错了,那么根据提示就永远也猜不出答案了。
3.
在这里插入图片描述
这里把种子函数放在循环里面了,这样做的后果是随机生成的值相似甚至相同。这是因为time(NULL) 返回的时间值在两次迭代之间几乎没有变化,导致种子几乎相同,进而产生相似的随机数序列。
可以代码验证一下:


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

在这里插入图片描述
所以写这个代码时应该注意。
在这里插入图片描述

/考研势在必行/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/466793.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux系统下vscode portable版本的python环境搭建003:venv

这里写自定义目录标题 python安装方案一. 使用源码安装&#xff08;有[构建工具](https://blog.csdn.net/ResumeProject/article/details/136095629)的情况下&#xff09;方案二.使用系统包管理器 虚拟环境安装TESTCG 本文目的&#xff1a;希望在获得一个新的系统之后&#xff…

vue 向某个网址 传递数据

1. 需求 现在有一个网站需要 配置上另一个网站的东西 类似这样的东西吧 就是我需要再一个网站上 右边或者其他地方 放另一个页面的地址 这个地址需要给我传递东西 或我这个网站给其他的网站传递token了 id等 2.解决 window.parent.postMessage({ token: loginRes.token, id:…

【Java程序设计】【C00249】基于Springboot的私人健身与教练预约管理系统(有论文)

基于Springboot的私人健身与教练预约管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的私人健身与教练预约管理系统 本系统分为系统功能模块、管理员功能模块、教练功能模块以及用户功能模块。 系统功能模…

2.11日学习打卡----初学RocketMQ(二)

2.11日学习打卡 一. RocketMQ整合springboot 首先配置pom.xml文件 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>annotationProcessor</scope></dependency><dependency>…

数据库基础学习笔记

一.基础概念 数据库、数据库管理系统、SQL 主流数据库&#xff1a; mysql的安装&#xff1a;略 mysql图形化界面的安装&#xff1a;略 二.数据模型 1). 关系型数据库&#xff08;RDBMS&#xff09; 概念&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表…

爬爬爬——今天是浏览器窗口切换和给所选人打钩(自动化)

学习爬虫路还很长&#xff0c;第一阶段花了好多天了&#xff0c;还在底层&#xff0c;虽然不是我专业要学习的语言&#xff0c;和必备的知识&#xff0c;但是我感觉还挺有意思的。加油&#xff0c;这两天把建模和ai也不学了&#xff0c;唉过年了懒了&#xff01; 加油坚持就是…

例38:使用Frame(分组框)

建立一个EXE工程&#xff0c;在窗体上放两个Frame框。分别放两组单选按钮表示性别和收入&#xff0c;注意每组单选按钮的组名要一样。在按钮中输入代码&#xff1a; Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)If Frame1.Visible ThenFrame1.Visib…

幻兽帕鲁游戏配置面板在哪里?腾讯云轻量应用服务器的一键参数配置面板

如何找到游戏配置面板&#xff1f; 目前&#xff0c;满足以下条件的Lighthouse&#xff0c;可以在实例详情页-应用管理页看到幻兽帕鲁的游戏配置面板。 如果你使用了一键/极简部署的方式开服&#xff0c;那么需要保存游戏存档后&#xff0c;将服务器重装系统&#xff0c;否则将…

AMD FPGA设计优化宝典笔记(4)复位桥

高亚军老师的这本书《AMD FPGA设计优化宝典》&#xff0c;他主要讲了两个东西&#xff1a; 第一个东西是代码的良好风格&#xff1b; 第二个是设计收敛等的本质。 这个书的结构是一个总论&#xff0c;加上另外的9个优化&#xff0c;包含的有&#xff1a;时钟网络、组合逻辑、触…

权限提升:利用Linux漏洞提权

目录 Linux权限基础 Linux用户权限 Linux文件权限 特殊的Linux文件权限 Linux本机信息收集 利用Linux漏洞进行提权 脏牛漏洞 pkexec Linux权限基础 Linux用户权限 在Linux中&#xff0c;根据权限的不同&#xff0c;大致可以分为三种&#xff1a;超级用户&#xff08;…

Netty应用——心跳检测机制案例(十七)

编写一个Netty心跳检测机制案例&#xff0c;当服务器超过3秒没有读时&#xff0c;就提示读空闲当服务器超过5秒没有写操作时&#xff0c;就提示写空闲实现当服务器超过 7秒没有读或者写操作时&#xff0c;就提示读写空闲 代码 IdleStateHandler说明 IdleStateHandler是netty提供…

Git分支和迭代流程

Git分支 feature分支&#xff1a;功能分支 dev分支&#xff1a;开发分支 test分支&#xff1a;测试分支 master分支&#xff1a;生产环境分支 hotfix分支&#xff1a;bug修复分支。从master拉取&#xff0c;修复并测试完成merge回master和dev。 某些团队可能还会有 reale…