如何在 ANSI C (C89) 中使用 printf 打印 size_t 和 ptrdiff_t
How to print size_t and ptrdiff_t using printf in ANSI C (C89)
我知道这在 SO 上被质疑过很多次,但我的问题是特定于 ANSI C (C89) 的。
在 C99 中有子说明符 z
和 t
,它们在 ANSI C 中不受支持。
使用 p
说明符怎么样?
size_t
是实现定义的无符号整数类型。 ptrdiff_t
是实现定义的有符号整数类型。
在C89/C90中(通常,但严格来说是错误的,简称为"ANSI C"),这些类型没有特殊的格式说明符。但是最宽的整数类型是 long int
和 unsigned long int
,它们当然有自己的格式说明符。
要打印 size_t
值,将其转换为 unsigned long
并使用 "%lu"
.
要打印 ptrdiff_t
值,将其转换为 long
并使用 "%ld"
.
请注意,如果您的代码随后使用 C99 或 C11 编译器编译,则 size_t
and/or ptrdiff_t
可能比 long
更宽,并且代码可能会失败。 (我记得 64 位 Windows 接口有 32 位 long
,所以这在实践中可能是个问题。)
在 C99 及更高版本中,只需对 size_t
使用 %zu
,对 ptrdiff_t
使用 %td
。如果您希望您的代码 真正 可移植,请考虑使用 #if
来测试 __STDC_VERSION__
.
的值
如果您的编译器仅部分符合 C99 或 C11,您也可能 运行 遇到问题。您的编译器可能不完全支持 C99,但确实提供 long long
。但是为了打印 size_t
值,只有当您打印的值实际超过 ULONG_MAX
时才会成为问题,即至少 232-1。对于 ptrdiff_t
值,转换为 long
是可以的,只要不超过 LONG_MAX
,至少是 231-1 .
最后,如果您碰巧知道要打印的值不是太大,则可以使用 int
并使用 %d
。我建议强制转换为 unsigned long
或 long
,但是 int
对于快速代码来说是可以的。
What about using the p
specifier?
不,%p
仅适用于 void*
类型的指针,并且在任何情况下输出格式都是实现定义的(通常是十六进制,但我见过其他表示形式)。
我知道这在 SO 上被质疑过很多次,但我的问题是特定于 ANSI C (C89) 的。
在 C99 中有子说明符 z
和 t
,它们在 ANSI C 中不受支持。
使用 p
说明符怎么样?
size_t
是实现定义的无符号整数类型。 ptrdiff_t
是实现定义的有符号整数类型。
在C89/C90中(通常,但严格来说是错误的,简称为"ANSI C"),这些类型没有特殊的格式说明符。但是最宽的整数类型是 long int
和 unsigned long int
,它们当然有自己的格式说明符。
要打印 size_t
值,将其转换为 unsigned long
并使用 "%lu"
.
要打印 ptrdiff_t
值,将其转换为 long
并使用 "%ld"
.
请注意,如果您的代码随后使用 C99 或 C11 编译器编译,则 size_t
and/or ptrdiff_t
可能比 long
更宽,并且代码可能会失败。 (我记得 64 位 Windows 接口有 32 位 long
,所以这在实践中可能是个问题。)
在 C99 及更高版本中,只需对 size_t
使用 %zu
,对 ptrdiff_t
使用 %td
。如果您希望您的代码 真正 可移植,请考虑使用 #if
来测试 __STDC_VERSION__
.
如果您的编译器仅部分符合 C99 或 C11,您也可能 运行 遇到问题。您的编译器可能不完全支持 C99,但确实提供 long long
。但是为了打印 size_t
值,只有当您打印的值实际超过 ULONG_MAX
时才会成为问题,即至少 232-1。对于 ptrdiff_t
值,转换为 long
是可以的,只要不超过 LONG_MAX
,至少是 231-1 .
最后,如果您碰巧知道要打印的值不是太大,则可以使用 int
并使用 %d
。我建议强制转换为 unsigned long
或 long
,但是 int
对于快速代码来说是可以的。
What about using the
p
specifier?
不,%p
仅适用于 void*
类型的指针,并且在任何情况下输出格式都是实现定义的(通常是十六进制,但我见过其他表示形式)。