“猜数字游戏“的模拟实现
目录摘要一程序的要求二函数介绍1rand函数2srand函数3time函数4易混淆点三代码编写1菜单函数2主体函数3游戏函数4总代码四游玩效果五限制猜测次数摘要本文从零开始实现猜数字游戏程序从程序的具体需求出发详细介绍了rand、srand及time等关键函数的用法并逐步讲解了菜单、主体及游戏核心逻辑的代码编写。最后展示游戏的实际运行效果以及如何通过代码限制猜测次数来增加游戏挑战性。一程序的要求程序会先生成一个随机数字然后让玩家进入循环反复猜根据玩家猜测的结果进行提示(猜大了或小了)然后并继续猜直到猜对时显示“恭喜你猜对了”并结束本轮游戏。每轮结束后会询问玩家是否继续玩若选择是则生成新的随机数开始下一轮否则退出整个程序。二函数介绍要想实现猜数字游戏⾸先得产⽣随机数那怎么产⽣随机数呢随机数必然会涉及到三个函数randsrandtime。这是C语言设计的三者一起使用即可在每次程序启动后都能生成不同的随机数1rand函数intrand(void);解释rand函数会返回⼀个伪随机数这个随机数的范围是在0~RAND_MAX之间这个RAND_MAX的大小是依赖编译器上实现的但是大部分编译器上是32767。而为什么是伪随机数是因为单独的使用rand函数是有缺陷的如下进行两次测试每次测试都是连续调用5次rand函数#include stdio.h #include stdlib.h int main() { printf(%d\n, rand()); printf(%d\n, rand()); printf(%d\n, rand()); printf(%d\n, rand()); printf(%d\n, rand()); return 0; }多次运行结果如下图单次运行中不断的rand的确生成了不同的随机数但是第二次重启程序发现生成的5个随机数和上一次程序是相同的这就是单独使用rand函数的缺陷原因是rand 函数是对⼀个叫种子的基准值进⾏运算⽣成的随机数。之所以每次运⾏程序产生的随机数序列是⼀样的那是因为每次rand函数生成随机数的默认种子都是1。所以导致每次程序启动得到的随机数序列都是一样则用户玩猜数字游戏只需记住这几个数字就可以一次猜中所以单独的使用rand函数是不对的而要想要rand的种子值改变而rand函数又没有参数那怎么办呢不必担心C语言给我们提供了srand函数去间接的修改rand函数的种子值2srand函数voidsrand(unsigned intseed);解释程序中在调⽤ rand 函数之前先调⽤ srand 函数通过 srand 函数的参数seed来间接设置rand函数的种子值然后rand再根据此种子值去生成随机数序列❓️想要每次游戏程序启动rand都能生成不同的随机数序列则需要保证每次的种子值不同所以每次srand的参数都要不同但我们不可能每次启动游戏前都手动的去代码中改变一下srand的参数把所以需要借助time函数3time函数time_ttime(time_t* timer);注返回的类型是time_t类型的time_t 类型本质上其实就是32位或者64位的整型类型time 函数会返回当前的日历时间返回1970年1月1日0时0分0秒到现在程序运⾏时间之间的差值单位是秒。所以time的返回值是动态改变的time函数返回的这个时间差也被叫做时间戳time函数的参数 timer指针 如果是非NULL的指针的话函数会将这个返回的差值放在timer指针指向的内存中。 如果 timer 是 NULL就只返回这个时间的差值。所以我们这里只需给time传递NULL参数然后把time的返回值作为srand的参数(强转即可)即可获得动态的种子值无需再在每次程序运行前都手动修改代码所以写法如下srand((unsigned int)time(NULL));//调用srand其根据time函数给rand函数一个初始种子值三种函数结合使用则可以确保在每次启动的游戏中都生成不同的随机数序列4易混淆点正确调用逻辑一次srand 多次 rand解释一次srand代表确定了游戏在本次启动的种子值而多次rand就是从这个种子值获取随机数序列然后下一次游戏启动srand的种子值会因为时间而改变则多次rand的值也会改变~错误调用逻辑每次rand前都srand一次解释这必然是错的首先srand的作用是重置起点(重置种子值)而不是“生成随机数”、你完全没必要重复的调用其次这种写法在同一秒内连续运行则会生成相同的数字因为你在同一秒内进行就代表此时的时间戳一样就代表种子值一样就代表srand会把起点重置到相同的值那么你此时在这一秒内rand值必然是一样的验证错误的代码如下#include stdio.h #include stdlib.h #include time.h int main() { for (int i 0; i 5; i) { srand(time(NULL)); // 每次循环都重新设置种子 printf(%d , rand() % 100); // 每次都是该种子的第一个数 } return 0; }解释srand的调用不仅仅是设置一下rand的种子值并且会重置该种子值所对应的随机数序列的起点此时你在同一秒内rand由于种子值相同所以当然会生成相同的数字啦所以srand只需要调用一次而rand可以重复调用在这个随机数序列中不断的往后取随机数即使是正确的代码逻辑你如果能在一秒之内猜出数字并重启程序进行下一把游戏则下一把游戏的随机数也是和上一把一样的因为一秒内时间戳相同种子值相同随机数都是序列的第一个但是一秒内完成这么多操作不太现实~三代码编写1菜单函数任何游戏上来肯定都是一个菜单让玩家选择玩还是退出所以我们制作一个简单的菜单函数。//菜单的打印 方便用户操作 void menu() { printf(*********************************\n); printf(*****1-玩游戏***0-退出游戏*****\n); printf(*********************************\n); }打印效果如下2主体函数玩家进来看见显示的菜单后可能输入0或1或其他的数字。所以我们用一个switch语句来对玩家的输入进行分类管理。switch语句选择1玩游戏选择0退出游戏选择其他选择错误。再综合我们玩完一把可以不关闭程序再次游玩的目的所以这个switch语句应该放在一个循环中那么循环的判断条件是什么呢当然是用户输入0了这就是为什么我们设置0是退出游戏的原因0为假刚好可以用来结束循环。所以玩家输入的1或者0或者输入错的其他非0的数字既用于switch语句中case的选择又用于了循环的条件判断代码int main() { srand((unsigned int)time(NULL));//调用srand其根据time函数给rand函数一个初始种子值 int input 0; do { menu();//打印菜单 printf(请选择:); scanf(%d, input); switch (input) { case 1://1代表玩游戏 game();//启动游戏 break; case 0://0代表退出游戏 printf(游戏已退出\n); break; default://其他输入不合规 printf(选择错误重新选择\n); break; } } while (input); return 0; }3游戏函数我们游戏函数主题内部对于猜数字一定是循环的玩家一般不可能一下子就猜对所以是一个循环整体代码//game函数的实现 void game() { int ret rand() % 100;//控制随机数的范围为0~99 int guess 0;//初始化猜测值为0 while (1) { printf(请猜数字\n); scanf(%d, guess); if (guess ret) { printf(恭喜你猜对了\n); break; } else if (guess ret) { printf(猜大了\n); } else { printf(猜小了\n); } } }解释其中的%100可以让随机数的范围为0~99利用了模的性质rand() %100;//余数的范围是0~99rand()%1001;//%100的余数是0~99,0~99的数字1,范围是1~100100 rand()%(200-1001)//余数的范围是0~100加100后就是100~2004总代码#define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includetime.h #includestdlib.h //菜单的打印 方便用户操作 void menu() { printf(*********************************\n); printf(*****1-玩游戏***0-退出游戏*****\n); printf(*********************************\n); } //game函数的实现 void game() { int ret rand() % 100;//控制随机数的范围为0~99 int guess 0;//初始化猜测值为0 while (1) { printf(请猜数字\n); scanf(%d, guess); if (guess ret) { printf(恭喜你猜对了\n); break; } else if (guess ret) { printf(猜大了\n); } else { printf(猜小了\n); } } } int main() { srand((unsigned int)time(NULL));//调用srand其根据time函数给rand函数一个初始种子值 int input 0; do { menu();//打印菜单 printf(请选择:); scanf(%d, input); switch (input) { case 1://1代表玩游戏 game();//启动游戏 break; case 0://0代表退出游戏 printf(游戏已退出\n); break; default://其他输入不合规 printf(选择错误重新选择\n); break; } } while (input); return 0; }四游玩效果五限制猜测次数#include stdio.h #include stdlib.h #include time.h void game() { int r rand() % 100 1; int guess 0; int count 5; while (count) { printf(\n你还有%d次机会\n, count); printf(请猜数字:); scanf(%d, guess); if (guess r) { printf(猜小了\n); } else if (guess r) { printf(猜大了\n); } else { printf(恭喜你猜对了\n); break; } count--; } if (count 0) { printf(你失败了正确值是:%d\n, r); } } void menu() { printf(***********************\n); printf(****** 1. play ******\n); printf(****** 0. exit ******\n); printf(***********************\n); } int main() { int input 0; srand((unsigned int)time(NULL)); 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; }解释本质就是用一个变量count作为循环的判断条件当其为0代表猜测次数用完❓️为什么C语言要设计srand函数去间接改变rand的种子值而不是让rand自己进行改变其实设计一个能自己管理种子的rand函数在技术上是完全可行的。但C语言的设计者选择了当前这种“职责分离”的更优设计哲学也就是“低耦合”原则。在这个设计下srand(seed)专门负责设置或重置随机数生成器的“起点”种子。rand()则专注于从当前起点开始推进状态并返回下一个随机数。这样拆分后两个函数各司其职互不干扰。如果某一部分的逻辑需要修改比如更换更复杂的随机数算法另一部分完全不受影响极大地方便了程序的维护和调试。这种清晰、解耦的设计是C语言系统级编程哲学的典型体现。 [ 作者 ] shylyly [ 首次发布 ] 2024.1.11❌ [ 最新修改 ] 2026.10.11 [ 声明 ] 由于笔者水平有限文中难免有疏漏或不妥之处还望读者不吝赐教。

相关新闻

java项目实战扶贫助农系统[文档+开题+PPT

java项目实战扶贫助农系统[文档+开题+PPT

🍅选题推荐——以防找不到我们,点击上方订阅专栏✌✌\ Java毕设实战项目 Python毕设项目源代码 asp.net毕业设计项目 Uniapp安卓毕业设计项目 node.js毕业设计项目 python毕业设计 微信小程序毕业设计项目 php毕业设计 👇🏻&#…

2026/10/12 1:17:41 阅读更多 →
PyTorch 离线安装实战:解决 pip 找不到 CUDA 版本的问题

PyTorch 离线安装实战:解决 pip 找不到 CUDA 版本的问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 1:17:41 阅读更多 →
Windows 下 OpenClaw 提示无法使用 exec 命令或下载插件:从配置文件到 TaoToken 的排查路径

Windows 下 OpenClaw 提示无法使用 exec 命令或下载插件:从配置文件到 TaoToken 的排查路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 1:17:41 阅读更多 →

最新新闻

百万级缺陷样本开源:工业视觉的「地基」被补上了

百万级缺陷样本开源:工业视觉的「地基」被补上了

1.工业质检的两道坎 ▍坎一:数据各管各的现成的工业缺陷数据集,几乎都窝在单一行当里。VisA、3CAD 盯着 3C 电子,PKU-GoodsAD 盯着包装,Real-IAD、MulSen-AD 盯着材料。覆盖面稍宽些的 VISION、MVTec AD、MMAD,又卡在…

2026/10/12 5:42:21 阅读更多 →
多模态 RAG 实战(二):一张图片,为什么我给它建立了两条向量索引?

多模态 RAG 实战(二):一张图片,为什么我给它建立了两条向量索引?

上一篇文章聊了一个多模态 RAG 中遇到的问题:图片明明被检索到,最终回答却可能没有正确展示。这次想把视角往前移,聊聊图片是如何被检索到的。在项目中,我通过 MinerU 解析 PDF,将图片保存到 MinIO。但图片存下来只是第…

2026/10/12 5:42:21 阅读更多 →
研究中合成数据使用闸门:失败含义与当天最小实验

研究中合成数据使用闸门:失败含义与当天最小实验

图:披露、种子复现、来源标记、漂移声明与结论边界五闸门,加合规打包。 千笔-AIWritePaper https://www.aiwritepaper.com 合成与 AI 生成数据能补样本、护隐私、做情景,但也会冒充实测、污染下一代训练集。欧盟出版署 data.europa academy …

2026/10/12 5:42:21 阅读更多 →
写时复制、读写分离:一文吃透CopyOnWriteArrayList原理与实战

写时复制、读写分离:一文吃透CopyOnWriteArrayList原理与实战

如果你在并发环境里用过ArrayList,大概率被ConcurrentModificationException教育过:一边遍历一边改数据,轻则抛异常,重则读到脏数据。很多人第一反应是加锁,加synchronized关键字或者直接套一层Collections.synchroniz…

2026/10/12 5:42:21 阅读更多 →
从ReAct到多Agent协作:AI Agent工程化落地关键实践

从ReAct到多Agent协作:AI Agent工程化落地关键实践

1. 从一套“能干活”的提示词说起这几年 AI Agent 的概念红得发紫,但很多团队拿着大模型 API 折腾了个把月,最后发现所谓的 Agent 就是个“会聊天的脚本”。真正把 Agent 推向生产环境,绕不开两个关键词——ReAct和多 Agent 协作。我参与过几…

2026/10/12 5:42:21 阅读更多 →
【AI应用】用TaoToken统一Key把AI生成的HTML一键转成可编辑PPTX

【AI应用】用TaoToken统一Key把AI生成的HTML一键转成可编辑PPTX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 5:41:20 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →