别死记硬背!用一个“猜数字”游戏,掌握库函数的学习方法
引入
很多编程初学者都会走入一个误区:把库函数当成英语单词来背。今天记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,即学即用,这种方式记忆的追深刻。
库函数学习方法论
从这个过程中,我们可以提炼出一套通用的“库函数学习五步法”:
明确需求:我需要函数帮我解决什么问题?(输入、输出、副作用)
搜索定位:用关键词找到可能相关的函数名
查阅文档:到权威站点看懂函数签名、参数、返回值和注意事项
写最小测试:单独测试这个函数,确认它的行为
融入项目:将它组合到你的代码中,并处理边界情况
记住:你不是在背字典,而是在学“查字典”的方法。
以上是作者总结出来的一些方法。如果有问题在评论区说出来,或者是有更好的方法你可以在评论区分享出来。
你们是以什么方法来学习库函数的呢?可以在评论区分享出来。
写代码,就是一个不断遇到未知、查询文档、动手验证的过程。希望今天的“猜数字”之旅,能让你放下“背函数”的包袱,真正享受探索的乐趣。
你还遇到过哪些让你当初一头雾水,后来查文档才豁然开朗的库函数?欢迎在评论区聊聊你的“踩坑”故事!
或者,试着用今天学到的方法去查一查 sleep() 或 usleep() 函数怎么用,把发现写在评论区,我会和你一起讨论~
如果这篇博客对你有帮助,点个赞和收藏支持一下吧,你的鼓励是我持续分享的最大动力!
