前言
本篇文章介绍如何在printf中使用正确的转换指令打印我们想要的类型
写在前面
我们在使用printf方法打印我们输出的变量时,会采用一种我称为转换指令
的方式来确定我们输出的类型和输出的格式,而这种转换指令一定是形如下面的格式:
转换指令 = %(标志位)(修饰符)+(转换说明符)
,其中修饰符可以添加多个,标志位和修饰符都可以没有
接下来,我们从右往左依次进行介绍
转换说明符
下面是所有的转换说明符及相应的介绍,按照我觉得使用频次的高低进行排列,当然不同领域的使用频率不一致,仅作参考
%d
/%i
:有符号十进制整数%u
:无符号十进制整数%f
:十进制浮点数%s
:字符串%c
:字符%p
:指针%e
/%E
:e-计数法浮点数%x
/%X
:十六进制整数(包含有符号和无符号)%o
:八进制整数(包含有符号和无符号)%g
/%G
:根据情况自动选择%f
还是(%e
/%E
)%a
/%A
:p-计数法浮点数%%
:百分号
修饰符
h
:和整数型转换说明符
一起使用,表示对应的short类型格式,比如:
%hd
、%hu
、%ho
、%hx
、%hX
表示的意思和int一致,只不过换成了short类型而已hh
:和整数型转换说明符
一起使用,表示对应的char类型数值
格式,比如:
%hhd
、%hhu
、%hho
、%hhx
、%hhX
表示的意思和int一致,只不过换成了char类型数值而已l
:和整数型转换说明符
一起使用,表示对应的long类型格式,比如:
%ld
、%lu
、%lo
、%lx
、%lX
表示的意思和int一致,只不过换成了long类型而已ll
:和整数型转换说明符
一起使用,表示对应的long long类型格式,比如:
%lld
、%llu
、%llo
、%llx
、%lX
表示的意思和int一致,只不过换成了long long类型而已L
:和浮点数转换说明符
一起使用,表示对应的long double类型格式,比如:
%Lf
、%Le
/%LE
、%lg
/%lG
、%la
/%lA
表示的意思和float/double一致,只不过换成了long double类型而已a.b
:表示打印的格式说明,
a表示字段打印的最小宽度,如果该字段不能容纳要打印的数或者字符串,系统就会使用更宽的字符,a可以不写
.b表示显示的精度,虽然是精度,但是不止和浮点数有关系对于
%e
,%E
,%f
,是将要在小数点后面打印的数字的位数
对于%g
,%G
,是有效数字的最大位数
对于%s
,是将要打印的字符的最大数目
对于整数转换,是将要打印的数字的最小位数,如果整数比这个最小位数还小,在前面加0补齐
标志位
-
:项目左对齐+
:显示符号位,整数显示+
,负数显示-
空格
:显示符号位,整数显示-
,该标志位的优先级小于+
#
:对于八进制整数,显示前导0
,对于十六进制整数,显示前导0x
或者0X
0
:对于所有数字格式,用前导0而不是空格填充字段宽度,如果出现标志位-
或者整数指定了精度
,忽略。
整型格式化
测试例子:
int b1 = 10;
unsigned int b2 = 10;
printf("b1 = %d\n", b1);
printf("b1 = %o\n", b1);
printf("b1 = %x\n", b1);
printf("b1 = %X\n", b1);
printf("b1 = %#o\n", b1);
printf("b1 = %#x\n", b1);
printf("b1 = %#X\n", b1);
printf("b2 = %u\n", b2);
运行结果如下:
b1 = 10
b1 = 12
b1 = a
b1 = A
b1 = 012
b1 = 0xa
b1 = 0XA
b2 = 10
short
测试例子:
short a1 = 10;
unsigned short a2 = 49999;
printf("a1 = %hd\n", a1);
printf("a1 = %ho\n", a1);
printf("a1 = %hx\n", a1);
printf("a1 = %hX\n", a1);
printf("a1 = %#ho\n", a1);
printf("a1 = %#hx\n", a1);
printf("a1 = %#hX\n", a1);
printf("a2 = %hu\n", a2);
运行结果如下:
a1 = 10
a1 = 12
a1 = a
a1 = A
a1 = 012
a1 = 0xa
a1 = 0XA
a2 = 49999
long
long的表示和short一致,只需要把h换成l即可
long long
long long的表示和short一致,只需要把h换成ll即可
浮点数格式化
浮点数有三种表达形式:
float a = 123.012f;
float a = 1.23012e2或者1.23012E2
float a = 0xa.1fp10或者0xa.1fP10
其中最后一种是C99新添加的表达格式
对于上面的例子,小数点前的a是十六进制,表示十进制的10,小数点后的.1f
=
1
/
16
+
15
/
256
=
16
256
+
15
256
=
31
256
= 1/16+15/256 = \frac{16}{256}+ \frac{15}{256}= \frac{31}{256}
=1/16+15/256=25616+25615=25631,p后面的数字不是基于10的指数,而是基于2的指数,所以p后面的数字=
2
10
=
1024
2^{10}=1024
210=1024,所以
0xa.1fp10
=
(
10
+
31
256
)
×
1024
=
10364.0
(10+\frac{31}{256})\times1024=10364.0
(10+25631)×1024=10364.0
测试例子:
float a = 12.2;
printf("a = %f\n",a);
printf("a = %e\n",a);
printf("a = %E\n",a);
printf("a = %a\n",a);
printf("a = %A\n",a);
printf("a = %+f\n",a); //加标志位+,显示正号
printf("a = % f\n",a); //加标志位空格,正号用空格代替显示
printf("a = %20f\n",a); //指定修饰符20,表示打印的最小宽度,默认右对齐
printf("a = %-20f\n",a); //指定修饰符20,表示打印的最小宽度,指定标识位-,左对齐
printf("a = %020f\n",a); //指定修饰符20,表示打印的最小宽度,指定标识位0,表示前导用0填充
printf("a = %020.2f\n",a); //指定修饰符20,表示打印的最小宽度,指定标识位0,表示前导用0填充,指定修饰符.2对浮点数来说保留两位小数
运行结果如下:
a = 12.200000
a = 1.220000e+01
a = 1.220000E+01
a = 0x1.866666p+3
a = 0X1.866666P+3
//加标志位+,显示正号
a = +12.200000
//加标志位空格,正号用空格代替显示
a = 12.200000
//指定修饰符20,表示打印的最小宽度,默认右对齐
a = 12.200000
//指定修饰符20,表示打印的最小宽度,指定标识位-,左对齐
a = 12.200000
//指定修饰符20,表示打印的最小宽度,指定标识位0,表示前导用0填充
a = 0000000000012.200000
//指定修饰符20,表示打印的最小宽度,指定标识位0,表示前导用0填充,指定修饰符.2对浮点数来说保留两位小数
a = 00000000000000012.20