<limits.h> 头文件没有定义任何函数或者类型,仅定义了一些与整数类型有关的宏。
在不同的平台、不同的编译器下,整型数据的取值范围可能会有所不同,用户可以读取该头文件中的宏来了解当前环境下整型数据的取值范围。
在C语言中,字符型 char、短整型 short、整型 int、长整型 long、超长整型 long long、有符号类型 signed 以及无符号类型 unsigned 都是整数类型。
C语言的一个优良传统是标量类型(整数是典型的标量类型)要以一种对每个计算机体系结构都很自然的方式表示。例如,基本整型 int 的弹性就很大,它希望自己的大小等于一个机器字长:
int 占用一个机器字长的内存是C语言的初衷,在 16 位环境和 32 环境中确实如此,但是到了 64 位环境中就不遵循这个规则了,这是为什么呢?
计算机发展到 64 位是后来的事情,已经是比较晚的年代了,C语言已经存在了二三十年了,此时已经有大量基于 32 位环境编写的代码,在这些代码中,程序员认为 int 的长度就是 4,并不一定向后兼容,如果冒然将 int 的长度增加到 8 个字节,就可能会导致原来的代码不能正常运行,这多少有点不能接受。
另外,经过多年的编程实践,程序员也已经习惯 int 的长度为 4 了,强行增加 int 的长度也可能让程序员反感。
总之,由于各种历史原因,64 位环境下的 int 依然占用 4 个字节的内存。
这个优良的传统对程序的效率来说是个不错的选择,但是对可移植性来说,就真的是个麻烦了,于是C语言标准委员会发明了 <limits.h> 头文件来捕捉标量类型在不同计算机体系结构之间的变化。
<limits.h> 头文件只对整数类型的取值范围进行了收集:
从“limits”这个名称就可以看出,<limits.h> 的初衷应该不仅仅是定义与整型有关的宏,它希望为更多类型添加宏。当C语言标准委员会决定为浮点数增加一些类似的宏的时候,他们通过投票决定不覆盖 <limits.h> 中已经存在的内容,而是添加了新的头文件 <float.h>。也许应该把已经存在的 <limits.h> 改名为 <integer.h>,但是C语言标准委员会并没有这样做,历史的连贯性、用户的习惯性战胜了命名的规范性。
宏 | 说明 | 取值 |
---|---|---|
CHAR_BIT | char 类型所包含的位(Bit)数。 | 大于等于 8,一般为 8 |
SCHAR_MIN | signed char 类型所能表示的最小值 | 小于等于-127 (-27+1),一般为 -127 |
SCHAR_MAX | signed char 类型所能表示的最大值 | 大于等于 127 (27-1),一般为 127 |
UCHAR_MAX | unsigned char 类型所能表示的最大值 | 大于等于 255 (28-1),一般为 255 |
CHAR_MIN | char 类型所能表示的最小值 | 要么是 0,要么是 SCHAR_MIN |
CHAR_MAX | char 类型所能表示的最大值 | 要么是 SCHAR_MAX,要么是 UCHAR_MAX |
MB_LEN_MAX | 一个多字节字符最多能包含多少个字节(多字节字符和宽字符是相对的) | 大于等于 1 |
SHRT_MIN | short int 类型所能表示的最小值 | 小于等于 -32767 (-215+1),一般是 -32767 |
SHRT_MAX | short int 类型所能表示的最大值 | 大于等于 32767 (215-1),一般是 32767 |
USHRT_MAX | unsigned short int 类型所能表示的最大值 | 大于等于 65535 (216-1),一般是 65535 |
INT_MIN | int 类型所能表示的最小值 | 小于等于 -32767 (-215+1) |
INT_MAX | int 类型所能表示的最大值 | 大于等于 32767 (215-1) |
UINT_MAX | unsigned int 类型所能表示的最大值 | 大于等于 65535 (216-1) |
LONG_MIN | long int 类型所能表示的最小值 | 小于等于 -2147483647 (-231+1) |
LONG_MAX | long int 类型所能表示的最大值 | 大于等于 2147483647 (231-1) |
ULONG_MAX | unsigned long int 类型所能表示的最大值 | 大于等于 4294967295 (232-1) |
LLONG_MIN | long long int 类型所能表示的最小值 | 小于等于 -9223372036854775807 (-263+1) |
LLONG_MAX | long long int 类型所能表示的最大值 | 大于等于 9223372036854775807 (263-1) |
ULLONG_MAX | unsigned long long int 类型所能表示的最大值 | 大于等于 18446744073709551615 (264-1) |
注意,LLONG_MIN、LLONG_MAX 和 ULLONG_MAX 是在 C99 标准中新加入的宏。
C语言中的字节(Byte)和 int 类似,同样不是一个确定长度的位(Bit)组。C语言只是要求字节能够放得下执行环境中和编辑/编译环境中基本字符集的编码,这样在某些编译器(极少数的编译器)中字节包含 9 位(Bit)就不难理解了,这并不违背C语言的基本定义。
一个字节之所以通常包含 8 个位,是因为绝大多数计算机都将标准 ASCII 作为基本的字符集。标准 ASCII 包含了 128 个字符,8 个位的字节足以容纳这些字符。
注意,如果在编辑/编译环境中基本字符集的编码是 8 位,而在运行环境中基本字符集的编码是 16 位的话,那么字节的大小显然就必须至少为 16 位。
总之,C语言中的字节并非一定是大家普遍认为的 8 位组。
C语言中的 char 类型是一种整数类型,它的大小被定义为1个字节,也即sizeof (char)的结果恒为 1。
如果想知道在当前环境下一个字节究竟包含了多少位,可以查看 <limits.h> 头文件中的 CHAR_BIT 宏,该宏指明了 char 类型的位数,也即字节的位数。