格式化字符串的基本格式:
%[标志][输出最小宽度][.精度][长度][类型]
1. 类型
字符 | 含义 |
---|---|
%a、%A | 读入一个浮点值(仅 C99 有效) |
%c | 输出单个字符 |
d%d | 以十进制形式输出整数,负数带负号 |
%e %E | 以指数形式输出单、双精度实数 |
%f | 以小数形式输出单、双精度实数 |
%g | double 型的参数会自动选择以%f 或%e 的格式来打印,其标准是根据打印的数值及所设置的有效位数来决定 |
%G | 与%g 作用相同,唯一区别在以指数形态打印时会选择%E 格式 |
%i | 有符号十进制整数,与%d相同 |
%o | 以8进制输出无符号整数 |
p | 以指针形式输出 |
s | 输出字符串 |
x | 以十六进制形式输出无符号整数(不输出前缀OX) |
X | 以十六进制形式输出无符号整数 (不输出前缀OX) |
u | 以十进制形式输出无符号整数 |
2. 长度
长度格式符主要为 h , l 两种, h 表示按短整型量输出, l 表示按长整型量输出。
字符 | 含义 | 用法 |
---|---|---|
%h | 表示一个short int 或者unsigned short int类型的数值, | %hu,%hx,%6.4hd |
%hh | 表示一个singned char 或者unsigned char 类型的数值, | %hhu,%hhx,%6.4hhd |
%j | 表示一个intmax_t或者uintmax_t类型的数值 | %jd,%8jx |
%l | 表示一个long int 或者unsigned long int类型的数值 | %ld,%8lu |
%ii | 表示一个long int 或者unsigned long int类型的数值(C99) | %lld,%8llu |
%L | 表示一个long double的值, | 示例:%Lf,%10.4Le |
%t | 表示一个ptrdiff_t值(两个指针之间的差相对应的类型)(C99), | %td,%12ti |
%z | 表示一个size_t值(sizeof返回的类型)(C99) | %zd,%12zx |
注:
intmax_t 和uintmax_t,表示最大宽度整数类型。在64位系统中:
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
size_t 和 ssize_t 表示sizeof返回值的数据类型。(sizeof的返回值是无符号类型,但其长度在32位和64位系统中有别)
typedef unsigned int size_t(32位);
typedef signed int ssize_t(32位);
typedef unsigned long int size_t (64位)
typedef long int ssize_t (64位)
char类型有可能是signed char 或 unsigned char,取决于编译器。具体使用时,应加上前缀。
数据类型请参考文档:
C语言数据类型
3. 标志
字符 | 含义 |
---|---|
- | 结果左对齐,右边填空格 |
+ | 输出符号(正号或负号) |
空格 | 输出值为正时冠以空格,为负时冠以负号 |
# | 对c,s,d,u类无影响;对o类,在输出时加前缀0;对x类,在输出时加前缀0x或者0X;对g,G 类防止尾随0被删除 |
0 | 对于所有的数字格式,用前导0填充字段宽度,若出现-标志或者指定了精度(对于整数),忽略 |
4. 输出最小宽度
用十进制整数来表示输出的最少位数(包括小数点在内)
若实际位数多于定义的宽度,则按实际位数输出;
若实际位数少于定义的宽度:
- 则右对齐,左边留空;
- 有负号,则左对齐,右边留空;
- 表示宽度的数字以0开始,则右对齐,左边留空;
5.精度:
精度格式符以“.”开头;
若输出为数字,若实际位数大于定义精度,则四舍五入;若不足,则补0;
若输出为字符,若实际位数大于定义精度,则截去超过的部分。
sample code:
#include “stdio.h”
#include “conio.h”
int main ()
{
printf("%.3d\n" , 5555);
getch();
printf("%.3f\n" , 0.88888);
getch();
printf("%.3f\n" , 0.9999);
getch();
printf("%.4s\n" , "this is a test!");
getch();
}
注:
格式化字符输出时,函数printf只管从内存中取出数据,再按照相应格式解析,它无法判断数据的类型,只能由用户加以指定。
倘若将一个负数,按照无符号类型输出,其数值可能会非常大,比如:
int a = -1;
printf("HU:%u\n",a);
输出结果为:4294967295.
这是因为数据在内存中都以补码的方式存储,-1的补码是0xffffffff,按%u的方式打印,就是一个很大的无符号整数值。补充:
原码、反码、补码的基本概念:
原码: 十进制数据的二进制表现形式就是原码,原码最左边的一个数字就是符号位,0为正,1为负。
反码: 正数的反码是其本身(等于原码),负数的反码是符号位保持不变,其余位取反。
补码: 正数的补码是其本身,负数的补码等于其反码+1。
计算机中将减法变成加法进行计算,可以能有效的简化电路设计。
- 原码无法将减法转换成加法运算。
- 反码能实现减法转成加法运算,但缺点是会引入+0 和 -0 的问题,这会使计算变得复杂。
- 补码的出现完美解决了上述问题。它通过将负数的反码统一向后移了一位,解决了-0的问题。如8bit的有符号数,原本范围是127~0,-0 ~127, 现在变成了127 ~ 0, -1 ~ -128. 原本-0的反码 1000 0000 就被定义成了 -128的补码(-128没有反码和源码表示)。
参考文档:
原码、反码、补码的产生、应用以及优缺点有哪些?