预计阅读本页时间:-
正如第3章“数据和C”中介绍的那样,C99头文件inttypes.h为不同的整数类型提供了一系列可选的名字。这些名字比标准名更清楚地描述了类型的属性。例如,int类型可能是16位、32位或64位,但是int32_t类型总是32位。
更准确地说,inttypes.h头文件定义了一些可以被用在scanf()和printf()中读写这些类型整数的宏。这个头文件包含了stdlib.h头文件,实际上是它提供了类型定义。格式化宏是可以与其他字符串进行连接来形成适当的格式化指示的字符串。
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
这些类型使用typedef进行定义。例如,具有32位int的系统可能会使用这样的定义:
使用#define指令来定义格式说明符。例如,使用前面int32_t定义的系统可以这样定义:
#define PRId32“d” // 输出说明符
#define SCNd32“d” // 输入说明符
使用这些定义,就可以像下面这样声明一个扩展的整数变量,输入一个值并进行显示:
如果需要,会把字符串进行连接来得到最后的控制字符串。这样,前面的代码就可以转换成下面这样:
如果把原始的代码移植到16位int的系统中,该系统可能把int32_t定义为long,把PRId32定义为“d”,把SCND32定义为“ld”。但是您可以使用同样的代码,只要知道它使用的是32位的整数就行了。
本参考资料的剩余部分列出了扩展类型及其格式说明符以及表示类型限制的宏。
B.6.1 确切长度类型
一组typedef定义标识了具有确切大小的类型。通常为有符号类型使用intN_t格式,而无符号类型使用uintN_t格式,其中N表明了位数。但是要注意不是所有的系统都支持所有这些类型。例如,可能有一种系统,它最小的可用内存大小是16位,这样的系统就不支持int8_t和uint8_t类型。格式宏可以使用d或i来表示有符号类型,所以PRIi8和SCNi8都有效。对无符号类型而言,可以使用o、x或X以得到% o、%x或%X说明符用来代替%u。例如,可以使用PRIX32来以十六进制格式打印一个uint 32_t类型的值。表B.49列出了确切长度类型、格式说明符和限制值。
表B.49 确切长度类型
类 型 名 | printf()说明符 | scanf()说明符 | 最 小 值 | 最 大 值 |
---|---|---|---|---|
int8_t | PRId8 | SCNd8 | INT8_MIN | INT8_MAX |
intl6_t | PRId16 | SCNd16 | INT16_MIN | INT16_MAX |
int32_t | PRId32 | SCNd32 | INT32_MIN | INT32_MAX |
int64_t | PRId64 | SCNd64 | INT64_MIN | INT64_MAX |
uint8_t | PRIu8 | SCNu8 | 0 | UINT8_MAX |
uint16_t | PRIu16 | SCNu16 | 0 | UINT16_MAX |
uint32_t | PRIu32 | SCNu32 | 0 | UINT32_MAX |
uint64_t | PRIu64 | SCNu64 | 0 | UINT64_MAX |
B.6.2 最小长度类型
最小长度类型可以保证一种类型的大小至少为某个确定的位。这些类型总是存在的。例如,不支持8位单元的系统可以把int_least_8定义为16位的类型。表B.50列出了最小长度类型、格式说明符和限制值。
表B.50 最小长度类型
类 型 名 | printf()说明符 | scanf()说明符 | 最 小 值 | 最 大 值 |
---|---|---|---|---|
int_least8_t | PRILEASTd8 | SCNLEASTd8 | INT_LEAST8_MIN | INT_LEAST8_MAX |
int_least16_t | PRILEASTd16 | SCNLEASTd16 | INT_LEAST16_MIN | INT_LEAST16_MAX |
int_least32_t | PRILEASTd32 | SCNLEASTd32 | INT_LEAST32 | MININT_LEAST32_MAX |
int_least 64_t | PRILEASTd64 | SCNLEASTd64 | INT_LEAST64_MIN | INT_LEAST64_MAX |
uint_least 8_t | PRILEASTu8 | SCNLEASTu8 | 0 | UINT_LEAST8_MAX |
Uint_least 16_t | PRILEASTu16 | SGNLEASTu16 | 0 | UINT_LEAST16_MAX |
uint_least 32_t | PRILEASTu32 | SCNLEASTu32 | 0 | UINT_LEAST32_MAX |
Uint_least 64_t | PRILEASTu64 | SCNLEASTu64 | 0 | UINT_LEAST64_MAX |
B.6.3 最快最小长度类型
对于特定的系统,有些整数表示可能比其他表示更快。例如,int_least16_t可能实现为short,但是系统在进行算术运算时使用int类型会更快一些。所以inttypes.h定义了表示至少某个位数的最快类型。这些类型总是存在的,在某些情况下哪种类型最快可能没有明显的选择,这时系统会简单地选择其中的一种。表B.51列出了最快最小长度类型、格式说明符和限制值。
表B.51 最快最小长度类型
类 型 名 | printf()说明符 | scanf()说明符 | 最 小 值 | 最 大 值 |
---|---|---|---|---|
int_fast8_t | PRIFASTd8 | SCNFASTd8 | INT_FAST8_MIN | INT_FAST8_MAX |
int_fastl6_t | PRIFASTd16 | SCNFASTdl6 | INT_FAST16_MIN | INT_FAST16_MAX |
int_fast32_t | PRIFASTd32 | SCNFASTd32 | INT_FAST32_MIN | INT_FAST32_MAX |
int_fast64_t | PRIFASTd64 | SCNFASTd64 | INT_FAST64_MIN | INT_FAST64_MAX |
uint_fast8_t | PRIFASTu8 | SCNFASTu8 | 0 | UINT_FAST8_MAX |
uint_fastl6_t | PRIFASTul6 | SCNFASTul6 | 0 | UINT_FASTl6_MAX |
uint_fast32_t | PRIFASTu32 | SCNFASTu32 | 0 | UINT_FAST3 2_MAX |
uint_fast64_t | PRIFASTu64 | SCNFASTu64 | 0 | UINT_FAST64_MAX |
B.6.4 最大长度类型
有时您可能想要使用可用的最大整数类型。表B.52列出了这些类型。实际上,它们可以比long long或unsigned long long更长,因为系统可能会提供比所要求的类型更长的附加类型。
表B.52 最大长度类型
类 型 名 | printf()说明符 | scanf()说明符 | 最 小 值 | 最 大 值 |
---|---|---|---|---|
Intmax_t | PRIdMAX | SCNdMAX | INTMAX_MIN | INTMAX_MAX |
uintmax_t | PRIuMAX | SCBuMAX | 0 | UINTMAX_MAX |
B.6.5 可以保存指针值的整数
inttypes.h头文件(通过包含stdint.h头文件)定义了表B.53中列出的两种整数类型,它们可以精确地保存指针值。也就是说,如果您把类型为void *的值赋值给这种类型变量,然后又把该整数赋回给指针,不会丢失任何信息。这两种类型都有可能不存在。
表B.53 可以保存指针值的整数类型
类 型 名 | printf()说明符 | scanf()说明符 | 最 小 值 | 最 大 值 |
---|---|---|---|---|
intptr_t | PRIdPTR | SCNdPTR | INTPTR_MIN | INTPTR_MAX |
uintptr_t | PRIuPTR | SCBuPTR | 0 | UINTPTR_MAX |
B.6.6 扩展的整数常量
您可以使用L后缀来表示一个long常量,例如445566L。但是如何表示一个类型为int 32_t的常量呢?可以使用inttypes.h中定义的宏。例如,表达式INT32_C(445566)展开为一个类型为int 32_t的常量。本质上说,这些宏是到低层类型的类型指派,也就是说,到特定实现中表示int 32_t的基本类型的指派。
宏的名称是用_C替换类型名中的_t,然后把所有字母大写得到的。例如要使1000成为uint_least64_t类型的常量,使用表达式UINT_LEAST64_C(1000)。