当前位置: 首页 > news >正文

别死记硬背!用一个“猜数字”游戏,掌握库函数的学习方法

引入

很多编程初学者都会走入一个误区:把库函数当成英语单词来背。今天记printf,明天背malloc,结果真到写代码时,要么想不起来,要么用错参数,最后感叹编程好难。

其实,库函数不是用来“背”的,而是用来“查”和“用”的。只要掌握正确的学习方法,任何陌生的库函数都能快速上手。

今天,我们就通过一个经典的“猜数字”游戏,来彻底讲清楚这件事。

猜数字的游戏规则及代码实现

游戏规则(以1~100的数为例)

1.生成一个在1~100范围内的随机数

2.输入一个在1~100范围内的数

3.判断.

(1).输入大于生成的数,则返回“大了”

(2).输入小于生成的数,则返回“小了”

(3).输入等于生成的数,则返回“恭喜你猜对了,数字是”

(4).输入的数不在1~100,则返回“输入错误”

我们根据以上的思路以C语言为例,就可以写出以下代码(只要学了分支与循环就会)

#include <stdio.h> int main() { int num2 = ?;// 生成随机数 int num1 = 0;//这是输入的数 while (1) { printf("请猜数字:>"); scanf("%d", &num1); a++; if (num1 < num2) { printf("小了\n"); } else if (num1 > num2) printf("大了\n"); else if (num1 == num2) { printf("恭喜你猜对了,数字是%d\n", num2); break; } else { printf("输入错误\n"); } } return 0; }

此时,你遇到了第一个知识缺口:如何生成随机数?这恰好就是我们学习库函数的起点。

陌生库函数的学习

第一步:明确需求,而非盲目搜索

在上面我们需要的是怎样的函数呢,思考一下可以得到以下内容

  • 需要一个函数,能返回一个随机整数。

  • 最好能限定范围,比如 1 到 100。

  • 这个函数最好在标准库里,无需安装额外东西。

这一步将模糊的问题转化成了精确的技术目标。上网搜索很快便能得到这个函数是rand()。而我们学习这给函数的学习和查看⼯具有很多⽐如:

C/C++官⽅的链接:https://zh.cppreference.com/w/c/header

Cplusplus.com:https://legacy.cplusplus.com/reference/clibrary

第二步:查阅官方文档

当我们知道了这个函数的名字时就可以去查了。我们以Cplusplus为例:

当我们点开这个网站时,点击上的输入框

并输入rand,按下回车就会得到这样的画面

当然我们要学会这种文档的阅读,这对我们以后的学习很重要。

结合以上信息我们不难看出这个函数的信息。定义在stdlib.h中。返回类型为int,返回值的范围为0~RAND_MAX(在部分编译器上0~32767),不接受参数。

看到以上功能,在回头看我们的需要,发现我们只需要1~100的随机数,而他的范围太大了。这个问题不难解决,只需要这个生成的随机数取模100再+1就行

int num2 = rand() % 100 + 1;//%100的余数是0~99,0~99的数字+1,范围是1~100

结合以上内容,我们可以写出一下代码

#include <stdio.h> #include <stdlib.h> int main() { int num2 = rand() % 100 + 1;// 生成随机数 int num1 = 0;//这是输入的数 while (1) { printf("请猜数字:>"); scanf("%d", &num1); if (num1 < num2) { printf("小了\n"); } else if (num1 > num2) printf("大了\n"); else if (num1 == num2) { printf("恭喜你猜对了,数字是%d\n", num2); break; } else { printf("输入错误\n"); } } return 0; }

第三步:功能完善与延申,善用“See Also”

但我们在多次测试中发现,每次生成的数并不随机。如:

我们每次打开第一个数都是42.其实原因也很简单。在Cplusplus中有这样一段话:

Returns a pseudo-random integral number in the range between and .

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function .

其大意为:这个函数是用算法生成在范围内的伪随机数.而这个算法用的是种子生成的。所以我们只要改变种子的值。就可以解决这个问题

而在Cplus plus中的例子里也用到了随机种子也在相关中提到了他——srand库函数

顺着文档的指引,我们找到了两个新函数:

srand—— 设置种子

  • 头文件<stdlib.h>

  • 原型void srand(unsigned int seed);

  • 作用:为rand()设置一个起始种子。种子不同,随机数序列才不同。

time—— 获取不断变化的值

  • 头文件<time.h>

  • 原型time_t time(time_t *timer);

  • 作用:返回当前日历时间(通常是从 1970-01-01 至今的秒数)。每次运行程序时,这个值都不同,是天然的好种子。

于是,我们将两者组合:srand((unsigned int)time(NULL));。这行代码只需在程序开始时调用一次,否则反而可能让序列变回可预测状态。

我们总结上面的库函数,在结合我们的需要,就可以写出以下内容

#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand((unsigned int)time(NULL)); int num2 = rand() % 100 + 1;// 生成随机数 int num1 = 0;//这是输入的数 while (1) { printf("请猜数字:>"); scanf("%d", &num1); if (num1 < num2) { printf("小了\n"); } else if (num1 > num2) printf("大了\n"); else if (num1 == num2) { printf("恭喜你猜对了,数字是%d\n", num2); break; } else { printf("输入错误\n"); } } return 0; }

第四步:完善代码,交付最终版

经过多次测试,这个代码是符合我们的要求的,我们再完善一下这个练习就完成了

#include <stdio.h> #include <stdlib.h> #include <time.h> void menu() { printf("**********************************\n"); printf("********* 1. play **************\n"); printf("********* 0. exit **************\n"); printf("**********************************\n"); } void game() { int num2 = 0; num2 = rand() % 100 + 1; int num1 = 0; int a = 0; while (1) { printf("请猜数字:>"); scanf("%d", &num1); a++; if (num1 < num2) { printf("小了\n"); } else if (num1 > num2) printf("大了\n"); else { printf("恭喜你猜对了,数字是%d\n", num2); printf("你一共猜了%d次\n", a); break; } } } int main() { srand((unsigned int)time(NULL)); strat: menu(); int play = 0; scanf("%d", &play); if (play == 1) { game(); goto strat; } else if (play == 0) { printf("退出游戏\n"); } else { printf("输入错误\n"); goto strat; } return 0; }

总结

我们上面用完成“猜数字”这个项目,通过一系列的问题来驱动我们学习库函数,从“如何生成随机数”这个实际的问题出发,学习rand和srand,以及time,即学即用,这种方式记忆的追深刻。

库函数学习方法论

从这个过程中,我们可以提炼出一套通用的“库函数学习五步法”:

  1. 明确需求:我需要函数帮我解决什么问题?(输入、输出、副作用)

  2. 搜索定位:用关键词找到可能相关的函数名

  3. 查阅文档:到权威站点看懂函数签名、参数、返回值和注意事项

  4. 写最小测试:单独测试这个函数,确认它的行为

  5. 融入项目:将它组合到你的代码中,并处理边界情况

记住:你不是在背字典,而是在学“查字典”的方法。

以上是作者总结出来的一些方法。如果有问题在评论区说出来,或者是有更好的方法你可以在评论区分享出来。

你们是以什么方法来学习库函数的呢?可以在评论区分享出来。

写代码,就是一个不断遇到未知、查询文档、动手验证的过程。希望今天的“猜数字”之旅,能让你放下“背函数”的包袱,真正享受探索的乐趣。

你还遇到过哪些让你当初一头雾水,后来查文档才豁然开朗的库函数?欢迎在评论区聊聊你的“踩坑”故事!

或者,试着用今天学到的方法去查一查 sleep() 或 usleep() 函数怎么用,把发现写在评论区,我会和你一起讨论~

如果这篇博客对你有帮助,点个赞和收藏支持一下吧,你的鼓励是我持续分享的最大动力!

http://www.jsqmd.com/news/907433/

相关文章:

  • 【Gemini Go编程实战指南】:20年Go专家亲授,避开97%开发者踩过的5大陷阱
  • H3CSE 高性能园区网:IRF 堆叠技术详解
  • 鼎捷Tiptop ERP T100/GP 5.3版本Webservice接口开发:从零到部署的完整避坑指南(含SoapUI测试)
  • Go跨平台编译的决策树:从“能编译“到“能部署“的5个关键抉择
  • Sora 2动效渲染瓶颈全拆解:从GPU管线调度到CSS Layering的12ms响应达标实操指南
  • Navicat vs DBeaver:从零到一,手把手教你根据项目需求选对数据库管理工具(附避坑指南)
  • 从需求分析到产品落地:AI产品经理实战训练营,带你玩转AI赋能产品全流程!
  • 告别付费!用FileZilla Server在Win10上5分钟搞定个人FTP服务器(附防火墙配置)
  • 不止是安装:用HFish在Windows搭建你的第一个‘诱饵’系统,实战检测内网扫描
  • Git 分支合并操作备忘录
  • AI赋能社交:从算法匹配到动态理解与主动赋能的约会新范式
  • 【评测】csdn与微信公众号后台的深度集成能力
  • 金字塔原理:教你做一个技术强会表达的芯片工程师(7000字)
  • 【 linux 】文件系统
  • Solar Pro Preview 模型架构详解:从Phi-3-medium到220亿参数的深度上采样技术
  • NLP —— 英译法实例
  • IPv4 和 IPv6 在地址结构、表示方式、地址空间大小及计算逻辑上存在根本性差异
  • 告别ifconfig!用networkctl命令优雅管理你的Linux网络(systemd-networkd实战)
  • Keil MDK许可证问题解析与解决方案
  • 第3章:裂痕——Siri、Copilot与寄生者入侵
  • 10.【学习】SPI UART 验证环境与测试用例
  • GeoServer数据源创建失败?别慌,可能是这个Windows文件命名‘潜规则’在捣鬼
  • 如何安全备份微信聊天记录:完整指南与实用工具推荐
  • WPF文本框的Placeholder效果,除了Watermark和Style,这几种实现方式你知道吗?
  • 别再踩坑了!手把手教你用YOLOv5 v6.0 + ONNX在Ubuntu 20.04的ROS上部署目标检测(附VMware虚拟机USB摄像头连接完整流程)
  • Python爬虫实战:极客实战 - 全自动化构建 GraphQL/REST API 结构化字典!
  • 别再折腾Docker了!Ubuntu 22.04上源码编译ZLMediaKit保姆级教程(含libsrtp/openssl避坑指南)
  • Midjourney Remix mode保姆级教程:手把手教你修改提示词,让AI更懂你
  • 脉冲神经网络与二进制权重的能效优化技术
  • UE4半透明材质性能优化全指南:从Surface模式选择到RTGI参数调优