C语言printf系列函数完整格式化占位符速查表
本文最后更新于 2026-01-30,文章内容可能已经过时。
C语言 printf 系列函数完整格式化占位符速查表(依据C89/C99/C11/C17/C23标准)
✅ 严格区分 输出占位符(printf 系列)|⚠️ 非 scanf 输入格式
📌 标注标准版本、数据类型、大小写差异、常见陷阱
🔢 一、整数类型(含长度修饰符组合)
| 占位符 | 数据类型 | 说明 | 标准 | 示例 |
|---|---|---|---|---|
| %d, %i | int | 有符号十进制(%i 可识别八/十六进制前缀) | C89 | printf("%d", -42); → -42 |
| %u | unsigned int | 无符号十进制 | C89 | printf("%u", 4294967295U); |
| %o | unsigned int | 无符号八进制(无 0 前缀) | C89 | printf("%o", 10); → 12 |
| %#o | unsigned int | 带 0 前缀的八进制 | C89 | printf("%#o", 10); → 012 |
| %x, %X | unsigned int | 十六进制(小写/大写字母) | C89 | printf("%x %X", 255, 255); → ff FF |
| %#x, %#X | unsigned int | 带 0x/0X 前缀 | C89 | printf("%#x", 255); → 0xff |
| %hd, %hi | short | 短整型十进制 | C89 | printf("%hd", (short)300); |
| %hu, %ho, %hx | unsigned short | 无符号短整型(十/八/十六进制) | C89 | printf("%hu", 65535); |
| %ld, %li | long | 长整型 | C89 | printf("%ld", 100000L); |
| %lu, %lo, %lx | unsigned long | 无符号长整型 | C89 | printf("%lx", 0xFFFFFFFFUL); |
| %lld, %lli | long long | 长长整型 | C99 | printf("%lld", 9223372036854775807LL); |
| %llu, %llo, %llx | unsigned long long | 无符号长长整型 | C99 | printf("%llu", 18446744073709551615ULL); |
| %zd | ssize_t (POSIX) | 有符号 size_t(非标准C,慎用) | POSIX | — |
| %zu | size_t | sizeof 返回类型(无符号) | C99 | printf("%zu", sizeof(int)); → 4 |
| %td | ptrdiff_t | 指针差值类型(有符号) | C99 | printf("%td", &arr[5]-&arr[0]); → 5 |
| %b, %B | unsigned int | 二进制输出(小写/大写 0b 前缀) | C23 | printf("%b", 10); → 0b1010(需 -std=c23) |
⚠️ 关键修正:
- size_t 标准占位符是 %zu(非 %zd), %zd 描述有误(%zd 用于 ssize_t,属 POSIX 扩展)
- ptrdiff_t 标准占位符为 %td
🌊 二、浮点数类型
| 占位符 | 数据类型 | 说明 | 标准 |
|---|---|---|---|
| %f, %F | float/double | 十进制小数(%F 用大写 INF/NAN) | C89 |
| %e, %E | float/double | 科学计数法(e/E 指数标识) | C89 |
| %g, %G | float/double | 自动选 %f 或 %e(更短者),去除尾零 | C89 |
| %a, %A | float/double | 十六进制浮点(0x1.92p+3 格式) | C99 |
| %Lf, %Le, %Lg, %La | long double | 长双精度浮点(注意大写 L) | C89/C99 |
💡 提示:printf 中 float 会自动提升为 double,故 %f 通用于两者;long double 必须用 %Lf 等。
🔤 三、字符与字符串
| 占位符 | 数据类型 | 说明 | 示例 |
|---|---|---|---|
| %c | char | 单个字符 | printf("%c", 'A'); → A |
| %s | char* | 以 \0 结尾的字符串 | printf("%s", "Hi"); → Hi |
| %hhd | signed char | 作为有符号整数输出 | printf("%hhd", (signed char)-1); |
| %hhu | unsigned char | 作为无符号整数输出 | printf("%hhu", (unsigned char)255); |
📍 四、指针与特殊占位符
| 占位符 | 说明 | 示例 |
|---|---|---|
| %p | 指针地址(十六进制,实现定义格式,通常带 0x) | printf("%p", (void*)&var); |
| %n | 不输出,将已输出字符数写入 int* 参数 | int cnt; printf("Hi%n", &cnt); // cnt=2 |
| %% | 输出字面 % 符号 | printf("100%%"); → 100% |
🎯 五、修饰符组合规则(核心语法)
完整格式:%[flags][width][.precision][length]specifier
| 修饰符类型 | 说明 | 示例 |
|---|---|---|
| Flags | - 左对齐, + 强制符号, 空格补正号, 0 前导零, # 备用格式 | printf("%05d", 7); → 00007 |
| Width | 最小输出宽度(整数或 * 动态指定) | printf("%10s", "Hi"); → Hi |
| Precision | 小数位数/字符串最大长度(.数字 或 .*) | printf("%.2f", 3.1415); → 3.14 |
| Length | hh (char), h (short), l (long), ll (long long), z (size_t), t (ptrdiff_t), L (long double) | printf("%lld", 1LL); |
⚠️ 六、高频陷阱与最佳实践
| 陷阱 | 错误示例 | 正确做法 |
|---|---|---|
| 数组传参后用 sizeof | void f(int a[]) { printf("%zu", sizeof(a)); } | 传入长度参数:f(a, sizeof(a)/sizeof(a[0])) |
| size_t 误用 %u | printf("%u", sizeof(int));(64位系统截断) | 必须用 %zu |
| long long 误用 %ld | printf("%ld", 10000000000LL); | 用 %lld 或 %llu |
| 指针未转 void* | printf("%p", &x);(部分编译器警告) | printf("%p", (void*)&x); |
| %n 安全风险 | 用户可控格式字符串含 %n | 避免将用户输入直接作格式串 |
📚 标准演进摘要
- C89:基础整数/浮点/字符占位符(%d, %f, %s 等)
- C99:新增 %zu(size_t)、%td(ptrdiff_t)、%a(十六进制浮点)、long long 支持
- C23:新增 %b/%B(二进制输出,需编译器支持)
✅ 权威依据:
- C11 标准 §7.21.6.1:z 修饰符用于 size_t,t 用于 ptrdiff_t
- %zu 为 sizeof 返回类型标准占位符
- %zd 描述为常见误区(实际应为 %zu)
此表可作为开发/面试/调试的权威速查 reference,建议收藏! 📌
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

