

C语言新增stdint.h头文件的讨论,什么是“快”类型,什么是“小”类型?
source link: https://blog.popkx.com/c%E8%AF%AD%E8%A8%80%E6%96%B0%E5%A2%9Estdint-h%E5%A4%B4%E6%96%87%E4%BB%B6%E7%9A%84%E8%AE%A8%E8%AE%BA-%E4%BB%80%E4%B9%88%E6%98%AF%E5%BF%AB%E7%B1%BB%E5%9E%8B-%E4%BB%80/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C语言新增stdint.h头文件的讨论,什么是“快”类型,什么是“小”类型?
虽说C语言是一门很成熟的编程语言,但是近些年来也是有所发展的,从早期的C89到后来的C99、C11等新标准,C语言逐步增加了许多好用的功能,例如新标准头文件“stdint.h”的添加。
如果程序员希望写出可移植的C语言程序,首先最重要的一点是不能假定位宽。C语言标准并没有明确指定的 short、int、long 等类型的位宽,因此可能在某些平台 sizeof(int) 等于 2,在其他平台 sizeof(int) 等于 4,所以如果编写的C语言代码假定 sizeof(int) 是一个固定值,显然就属于不可移植的代码。
为了解决这样的问题,在新标准文件“stdint.h” 之前,程序员必须做些额外的工作,以确定C语言代码运行的平台的各种数据位宽,这样的工作着实烦人,稍不留神就会出错。
“stdint.h”头文件的添加就是为了便于程序员写出不假定位宽的程序的。其内部通过 typedef 和宏判断定义了不少好用的整数类型,例如 int8_t 类型表示 8 位的有符号的整数类型,uint32_t 则表示 32 位的无符号的整数类型。类似的,还有 int16_t、int64_t、uint64_t 等类型,都是比较好理解的。
C语言中的“快”类型
不过,如果读者打开 stdint.h 头文件,应该能够看到一些更有趣的类型,如下图:
可以看出,这些类型被称作“fast type”,类型名中也有 fast 的字样(如 int_fast16_t),直译成中文即“快类型”,那么它们到底有什么含义呢?
观察力敏锐的读者应该发现了,int_fast16_t 和 int_fast32_t 其实是一样的,以上图黄框为例,它们都表示 int 类型,这是怎么回事呢?int 类型怎么能同时表示 16 位宽和 32 位宽的整数类型呢?
int 类型当然不能同时表示两种位宽的整数类型,事实上,int_fastxx_t 类型并不是准确的 xx 位宽类型,它表示不低于 xx 位宽的类型,因此,只要 int 的位宽大于或者等于 32 位,它就能同时表示 int_fast16_t 和 int_fast32_t 类型。
有读者看到这里可能会有疑问,如果 int 的位宽等于 32,那么使用它来表示 16 位宽的 int_fast16_t 整数类型,不是造成资源浪费了吗?
其实读者应将注意力放在“fast”一词上。CPU 从内存取数据一般是逐字取的,这里的“字”并不是字节的意思,在 32 位主机上,字长常常是 4 个字节,也即 CPU 单次取出数据的最小单位是 4 个字节。
字长也可以理解为 CPU 读取数据的“步长”。
也就是说,CPU 读取数据的“步长”是字长(下文以4字节为例),也就是说假设这次读取了地址 0~3 的数据,接下来若是希望读取相邻的数据,最接近的地址也得是地址 4~7。其实从这里可以看出,CPU 每次读取数据的起始地址都是字长的整数倍。
这也是“数据对齐”的原因——为了CPU读取数据的效率。
如果需要读取的数据只有一个字节(char 型),那么显然,无论该字节放在哪里,它总是在某个字长段的范围内的(例如地址 0~3,地址 4~7 内),此时 CPU 一次就能读取完毕。
如果需要读取的数据有两个字节(16bits),情况就不同了——它的地址可能是 3~4,而 CPU 读取数据的“步长”是 4 个字节,若要读取该值,CPU 只能先读取 0~3 字节的数据,再读取 4~7 字节的数据,最后还需要组合拼凑,才能得到该值。这样的一系列操作显然非常低效。
所以 stdint.h 将“快”类型定义为字长的整数倍的意图就一目了然了,无非就是牺牲一些“空间”换取“时间”。当然了,读者在使用“快类型”时需要注意:int_fast16_t 并不一定恰好是 16 位宽,它只是不少于 16 位宽的类型。
C语言中的“小”类型
前面提到,int_fastxx_t 类型牺牲了“空间”换取“时间”,如果在某个C语言项目中,“空间”效率并不是特别重要,而“空间”效率却非常重要,那么 int_fastxx_t 类型显然就不合适了。此时可以使用 stdint.h 中定义的 “small type”,也即“小类型”。
int_leastxx_t 系列的数据类型基本上保证了其恰好是 xx 位宽,避免了空间浪费,但是按照前文的分析,“小类型”付出的代价是损失了一部分时间效率。
本文主要讨论了C语言新增头文件“stdint.h”中定义的几种整数类型,并在此基础上讨论了“时间”效率和“空间”效率的矛盾。事实上,"stdint.h" 头文件中还定义了其他一些好用的宏,比如整数指针,各个数据类型的最大值和最小值等等,留给读者自己查看了。
// 详解下各种类型
https://stackoverflow.com/questions/9239558/what-is-the-difference-between-intxx-t-and-int-fastxx-t
https://stackoverflow.com/questions/tagged/c?tab=votes&page=124&pagesize=15
Recommend
-
36
Rust新增存在类型支持
-
56
-
42
“Go 是谷歌的编程语言,而不是社区的?”对于这样的观点,你是赞同还是反对?欢迎在文章下方评论区留言,与其他小伙伴展开讨论。 我们将在评论区选出三位精彩评论者,送上“InfoQ 限量版定制 T 恤”一件或
-
11
《C语言高级专题第8部分-4.8.一些杂散但值得讨论的问题》 官方网站:www.zhulaoshi.org 欢迎大家到论坛讨论学习 第一部分、章节目录 4.8.1.操作系统究竟是个什么玩意? 4.8.2.main函数返回给谁? 4.8.3.argc、argv与main函数...
-
9
点击上方“蓝色字”可关注我们!
-
9
鲍威尔称,美联储将发布关于CBDC利弊的讨论文件
-
4
1、不完全类型的概念 ISO(国际标准化组织(International Standard Organizat...
-
7
想要在编辑器里面添加新的Asset类型,算是比较常见又不是经常使用的需求。 当前UE4版本为4.26.2。 虽然本身并不复杂,但是每次添加的时候如果项目中没有相关的代码,就又要取查一次。不然总是会在一些奇怪的地方卡住导致在编辑器中无法使用的情况...
-
6
新浪VR > 正文页 VR节奏游戏《Beat Saber》将新增方块类型...
-
6
Go语言的表达性、错误处理方法和泛型等讨论摘录 - 黑客新闻 - 极道 可汗网络学院发布了50万行Go代码以后的
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK