C++学习------cinttypes头文件的源码学习01

619 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情

引言

cinttypes是C++对inttypes.h头文件的封装,里面封装了一系列宏定义,用于C语言printf和scanf函数的format打印,封装了一些函数,用于str类型转换为xxmax_t类型。我们来一起看看具体的实现。

inttypes.h

代码参考: www.aospxref.com/android-12.…

宏定义

基础前缀定义

这里根据平台(32/64)分别定义了64位打印和指针打印的前缀,与前一篇文章中一致,64位机器用long,32位机器需要long long,值得注意的是,32位下面的指针前缀为空

25  #ifdef __LP64__
26  #define __PRI_64_prefix  "l"
27  #define __PRI_PTR_prefix "l"
28  #else
29  #define __PRI_64_prefix "ll"
30  #define __PRI_PTR_prefix
31  #endif
32  #define __PRI_FAST_prefix __PRI_PTR_prefix

有符号整数输出定义

通常有符号整数用'%d'、'%i'打印,其中'%jd','%ji'分别表示intmax_t,代码如下:

50  /* fprintf macros for signed integers */
51  #define	PRId8			"d"		/* int8_t */
52  #define	PRId16			"d"		/* int16_t */
53  #define	PRId32			"d"		/* int32_t */
54  #define	PRId64			__PRI_64_prefix"d"		/* int64_t */
55  
56  #define	PRIdLEAST8		"d"		/* int_least8_t */
57  #define	PRIdLEAST16		"d"		/* int_least16_t */
58  #define	PRIdLEAST32		"d"		/* int_least32_t */
59  #define	PRIdLEAST64		__PRI_64_prefix"d"		/* int_least64_t */
60  
61  #define	PRIdFAST8		"d"		/* int_fast8_t */
62  #define	PRIdFAST16		__PRI_FAST_prefix"d"	/* int_fast16_t */
63  #define	PRIdFAST32		__PRI_FAST_prefix"d"	/* int_fast32_t */
64  #define	PRIdFAST64		__PRI_64_prefix"d"		/* int_fast64_t */
65  
66  #define	PRIdMAX			"jd"		/* intmax_t */
67  #define	PRIdPTR			__PRI_PTR_prefix"d"		/* intptr_t */
68  
69  #define	PRIi8			"i"		/* int8_t */
70  #define	PRIi16			"i"		/* int16_t */
71  #define	PRIi32			"i"		/* int32_t */
72  #define	PRIi64			__PRI_64_prefix"i"		/* int64_t */
73  
74  #define	PRIiLEAST8		"i"		/* int_least8_t */
75  #define	PRIiLEAST16		"i"		/* int_least16_t */
76  #define	PRIiLEAST32		"i"		/* int_least32_t */
77  #define	PRIiLEAST64		__PRI_64_prefix"i"		/* int_least64_t */
78  
79  #define	PRIiFAST8		"i"		/* int_fast8_t */
80  #define	PRIiFAST16		__PRI_FAST_prefix"i"	/* int_fast16_t */
81  #define	PRIiFAST32		__PRI_FAST_prefix"i"	/* int_fast32_t */
82  #define	PRIiFAST64		__PRI_64_prefix"i"		/* int_fast64_t */
83  
84  #define	PRIiMAX			"ji"		/* intmax_t */
85  #define	PRIiPTR			__PRI_PTR_prefix"i"		/* intptr_t */

无符号整数输出定义

因为无符号整数可以被'%o'(8进制),'%u'(10进制),'%x'(16进制小写字母),'%X'(16进制大写字母)修饰,再加上最大值修饰'j',所以定义的宏如下(展示%o的,其余类似):

87  /* fprintf macros for unsigned integers */
88  #define	PRIo8			"o"		/* int8_t */
89  #define	PRIo16			"o"		/* int16_t */
90  #define	PRIo32			"o"		/* int32_t */
91  #define	PRIo64			__PRI_64_prefix"o"		/* int64_t */
92  
93  #define	PRIoLEAST8		"o"		/* int_least8_t */
94  #define	PRIoLEAST16		"o"		/* int_least16_t */
95  #define	PRIoLEAST32		"o"		/* int_least32_t */
96  #define	PRIoLEAST64		__PRI_64_prefix"o"		/* int_least64_t */
97  
98  #define	PRIoFAST8		"o"		/* int_fast8_t */
99  #define	PRIoFAST16		__PRI_FAST_prefix"o"	/* int_fast16_t */
100  #define	PRIoFAST32		__PRI_FAST_prefix"o"	/* int_fast32_t */
101  #define	PRIoFAST64		__PRI_64_prefix"o"		/* int_fast64_t */
102  
103  #define	PRIoMAX			"jo"		/* intmax_t */
104  #define	PRIoPTR			__PRI_PTR_prefix"o"		/* intptr_t */

有符号整数输入定义

有输出符号就有输入符号,对应输出的处理基本相同,使用'%d'或'%i',不同的是,输出时,int8_t,int16_t,int32_t都是使用'%d'输出,但是输入时,我们必须要增加修饰符:

  • 'h':表示short int或unsigned short int类型
  • 'hh':表示signed char或unsigned char类型 再加上表示max值的'j',所以其中'%d'的代码示意如下,其它类似:
160  /* fscanf macros for signed integers */
161  #define	SCNd8			"hhd"		/* int8_t */
162  #define	SCNd16			"hd"		/* int16_t */
163  #define	SCNd32			"d"		/* int32_t */
164  #define	SCNd64			__PRI_64_prefix"d"		/* int64_t */
165  
166  #define	SCNdLEAST8		"hhd"		/* int_least8_t */
167  #define	SCNdLEAST16		"hd"		/* int_least16_t */
168  #define	SCNdLEAST32		"d"		/* int_least32_t */
169  #define	SCNdLEAST64		__PRI_64_prefix"d"		/* int_least64_t */
170  
171  #define	SCNdFAST8		"hhd"		/* int_fast8_t */
172  #define	SCNdFAST16		__PRI_FAST_prefix"d"	/* int_fast16_t */
173  #define	SCNdFAST32		__PRI_FAST_prefix"d"	/* int_fast32_t */
174  #define	SCNdFAST64		__PRI_64_prefix"d"		/* int_fast64_t */
175  
176  #define	SCNdMAX			"jd"		/* intmax_t */
177  #define	SCNdPTR			__PRI_PTR_prefix"d"		/* intptr_t */

无符号整数输入定义

这里的输入定义也与有符号相同,需要用'h','hh'修饰,但是不同的是输入并不区分16进制大写或者小写,只定义了'x'的小写输入如下,其它的类似:

234  #define	SCNx8			"hhx"		/* uint8_t */
235  #define	SCNx16			"hx"		/* uint16_t */
236  #define	SCNx32			"x"		/* uint32_t */
237  #define	SCNx64			__PRI_64_prefix"x"		/* uint64_t */
238  
239  #define	SCNxLEAST8		"hhx"		/* uint_least8_t */
240  #define	SCNxLEAST16		"hx"		/* uint_least16_t */
241  #define	SCNxLEAST32		"x"		/* uint_least32_t */
242  #define	SCNxLEAST64		__PRI_64_prefix"x"		/* uint_least64_t */
243  
244  #define	SCNxFAST8		"hhx"		/* uint_fast8_t */
245  #define	SCNxFAST16		__PRI_FAST_prefix"x"	/* uint_fast16_t */
246  #define	SCNxFAST32		__PRI_FAST_prefix"x"	/* uint_fast32_t */
247  #define	SCNxFAST64		__PRI_64_prefix"x"		/* uint_fast64_t */
248  
249  #define	SCNxMAX			"jx"		/* uintmax_t */
250  #define	SCNxPTR			__PRI_PTR_prefix"x"		/* uintptr_t */

结构体定义

定义了一个除法的结构体,里面保存了商值和余数值,用来做后面的函数处理

252  typedef struct {
253  	intmax_t quot;		/* quotient */
254  	intmax_t rem;		/* remainder */
255  } imaxdiv_t;

函数定义及相应的处理参考后续文章