如何在 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 中有子说明符 zt,它们在 ANSI C 中不受支持。

使用 p 说明符怎么样?

size_t 是实现定义的无符号整数类型。 ptrdiff_t 是实现定义的有符号整数类型。

在C89/C90中(通常,但严格来说是错误的,简称为"ANSI C"),这些类型没有特殊的格式说明符。但是最宽的整数类型是 long intunsigned 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 longlong,但是 int 对于快速代码来说是可以的。

What about using the p specifier?

不,%p 仅适用于 void* 类型的指针,并且在任何情况下输出格式都是实现定义的(通常是十六进制,但我见过其他表示形式)。