如何在ANSI C(C89)中使用printf打印size_t和ptrdiff_t

时间:2017-05-28 18:44:08

标签: c printf c89

我知道在SO上多次受到质疑,但我的问题是ANSI C(C89)特有的。

在C99中有子说明符zt,ANSI C不支持。

使用p说明符怎么样?

1 个答案:

答案 0 :(得分:9)

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和/或ptrdiff_t可能会比long更宽,并且代码可能会失败。 (我记得64位Windows界面有32位long,所以这在实践中可能是一个问题。)

在C99及更高版本中,只需将%zu用于size_t,将%td用于ptrdiff_t。如果您希望代码真正可移植,请考虑使用#if来测试__STDC_VERSION__的值。

如果您的编译器只有部分符合C99或C11,您也可能会遇到问题。您可能有一个不完全支持C99的编译器,但确实提供了long long。但是为了打印size_t值,如果您打印的值实际超过ULONG_MAX,那么这只会是一个问题,这至少是2 32 - 1。对于ptrdiff_t值,转换为long即可,只要它不超过LONG_MAX,即至少2 31 -1。

最后,如果您碰巧知道您要打印的值不是太大,那么您可以使用int转换为%d并使用unsigned long。我建议转换为longint,但p可用于快速和脏代码。

  

使用%p说明符怎么样?

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