第十六章:标准函数库
Github
链接:ch16. 标准函数库
库函数能极大简化平时的业务处理,也不必再重复造轮子了,况且自己造的轮子质量也不咋滴…但是我个人觉得某些不常用的库函数了解即可,知道它的干啥的就行了,确实在某些特定的业务处理才会用到,用的时候查文档即可。
本章总结及注意点
部分课后习题解答
16.12 问题
-
这个是
UB
行为,基数base
的取值范围为 0,2~36,在书中P329
可以看到相关定义。这或许可能能输出一串结果,但是没有意义,可移植性将大大降低。 -
是的,所有需要的是相互之间没有明显关系的数字。够用就行,可用来造数据写对拍!
-
很明显,生成 100 个随机数,并且将其范围限制在 0、1 之间,那么结果就取决于随机数的 “质量”,
哈哈,我的随机数还不是那么的规律,见
demo01.c
。 -
没读懂问题是啥意思。答案给的挺不错的,利用睡眠函数
sleep()
统计这段时间是否被计算在内就能分别出了。见答案:要做到绝对肯定并不容易。一些实现提供了一个睡眠函数暂停程序一段时间;如果在a
期间时钟值持续增加休眠,然后测量经过的时间。如果没有这一点,可以尝试从标准输入中读取十秒内什么都没输入。如果时钟在这段时间内继续增加,它就是度量运行时间或机器上的操作系统都不是很擅长管理其I/O
设备。另一个选择是启动另一个项目;如果时钟在第一个当第二个程序在运行时,它在测量运行时间。 -
为啥只意识到了月份需要加 1 这个细节…几个函数传参确实得注意!见
P332
和P333
。 -
主要的问题是在调用
setjmp
的函数返回后调用longjmp
。这意味着保存在跳转缓冲区中的状态信息不再有效,因此结果是不可预测的。与此相比,事实是,主功能并没有检查是否正确给出的命令行参数的数目很小。当这个执行时会发生什么?它这取决于具体的机器。有些将中止从号码返回的非法返回地址活动set_buffer
函数。其他的则会在某个地方进入无限循环。特别是RISC
机器,它不把函数参数存储在堆栈上有了回信地址,就会进入一个无限循环。见P337
警告部分。 -
大部分
OJ
都直接SE
,但在我本地编译器竟然只是warning
,估计开的警告级别太低了,作为程序员应该避免这种情况,执行了两次结果都是随机的。 -
降序排序。
16.13 编程练习
-
很不错的一道题目,简单的实现了一个
p
进制,虽然是借助的库函数。采用了main()
函数传参来接收命令行参数很不错,代码给的非常标准!见demo03.c
。 -
其实也是很常见的一类题型,概率相关,自己以为只需要简单的
%6
进行一个简单的映射即可,但是显然还是太年轻了啊。见答案: -
简单的一个模拟题,见
demo04.c
。 -
关于年份计算星期是有个公式的,貌似叫做基姆拉尔森公式。
tm_wday
不需要自己手动赋值,在转换之后tm
结构会进行格式化,可以很方便的判断是星期几!!!见P335
。见demo05.c
。 -
注意
△t
就行了。见demo06.c
。 -
常见错误:将
payment
的数量参数作为整数传递,未能将年数及利息换算为每月的等值,未能转换小数的利息,没有四舍五入到最接近的一分钱。 -
懒得去做这个试验了,参考答案书后就有。
-
sscanf
将不再工作,因为可能有任何数量的年龄。相反,我们将使用strtol
。strtol
在这可以忽略前导空格,并且进行 10 进制意义下的转换,真的是太方便了,直接将其第二个参数给char *buf
取地址为&buf
作为二级指针传入进去就很灵性。见demo08.c
。可对比看下ch15 README.md
中的编程 7。 -
高中数学课上讲概率的时候做过这个实验,老师还帮助选出了同年同月的一对同学。答案是令人惊讶的:在一个 30 人的小组中,70% 的几率至少有两个他们的生日是同一天。只要一组 23 人左右的成员就能赢得平局。暂时我的电脑不能引入
<malloc.h>
…应该在<stdlib.h>
下包含了空间配置函数了,也能正常使用,就不去折腾了。见demo09.c
。 -
之前总结过:[排序算法] 0. 专栏简介及各文章链接 插排就是比冒泡厉害,其在逆序对数量相当的情况下,插排交换的次数会更少!
随笔
-
随机函数
rand()
和srand()
,随机种子等。虽然写的算法题不少了,但是自己还没用对拍自己造数据测过程序。这个近期就得提上日程了啊。 -
字符串转换函数也是蛮重要的。用的时候再看就行了。不过
LeetCode
中的让你实现atoi()
和atof()
是真的挺恶心的。 -
至于
abs()
和fabs()
不知道现在abs()
支持浮点数了没,不过还是按照标准来就行了。 -
三角函数、双曲函数没怎么用过…顺手证明了下换底公式,手生了啊。
-
浮点数表示形式,这个没怎么看懂。浮点数标准各个机器可能不同,用这几个函数来传递浮点数吗?
-
floor()
、ceil()
这个需要注意负数的情况,再C++
中\
是单纯的向 0 取整,及-3 / 2
就是单纯的 -1,但是floor(-3/2)
就是 -2,ceil(-3/2)
是 -1。这个得注意下,C++
向零取值这个,且是忽略小数位的,若想四舍五入,就再后面加个 0.5。以及某些情况下是需要向下取取整的,向下取整式子有相应的恒等式变换,给忘了… -
日期函数看看就行了。
-
这个非本地跳转有点秀,以前是没遇见过。结合
P337
的例子来很有帮助。但深觉还是用得少吧… -
信号这个建议直接去看操作系统,会讲解的更加清楚一点。进程间通信等等八股文还是得背的。信号处理函数,
volatile
等都是些基础知识。 -
打印可变参这几个函数了解用途即可。
-
assert()
宏还是蛮常用的,它是个宏,不是函数!至于排序qsort()
和二分查找bsearch()
函数,还发现在P345
程序一开始的注释中bsearch
拼写错误。不过我确实没在这用过这两个函数,写个自定义的cmp()
函数,传函数名等于传递函数指针就可以进行调用了。 -
locale
只是简单粗略的看了下,可以格式化数字、货币等表示方式,更加方便点,可以提高移植性吧。
疑问
-
注意区分
floor()
与ceil()
函数的区别,及其两者在处理负数的时候的不同作用。 -
非本地跳转有点懵。
-
信号和
locale
都只是简单的看了看。 -
编程题 4 判断星期蛮秀的,很方便,
mktime()
组织起来之后就直接内部格式化了,调用结构体成员tm_wday
就可以得到星期数了。 -
编程题 8 采用
strtol()
来进行一行以空格间隔的数字字符串向数字的转换,也是很秀。利用了其第二个参数且忽略前导空格的特性来解决这个问题,关键在于它可以选择进制。strtol()
是专门用来处理整数的,有base
可以设置,而strtod()
是专门用来处理浮点数字符串的,自然也不设置base
了