我知道这个问题在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
和/或ptrdiff_t
可能比long
宽,代码可能会失败。(据我所知,64位Windows接口具有32位long
,因此在实践中可能存在问题。)
在C99及更高版本中,只需使用%zu
表示size_t
,%td
表示ptrdiff_t
即可。如果您希望您的代码真正具有可移植性,请考虑使用#if
测试__STDC_VERSION__
的值。
size_t
可能被定义为long long unsigned int
或者__uint64
等等。你该找谁? - n. m.long long unsigned int
并且对其任何使用不发出警告信息的编译器不符合 C89/C90 标准。在 C89/C90 中,long long unsigned int
是语法错误。 - Keith Thompson%p
要求一个 void*
类型的参数。指针不是整数,它们不能安全地互换使用。如果使用任何类型的参数而不是 void*
来使用 %p
,将会有未定义的行为。 (也许可以使用 char*
、unsigned char*
或 signed char*
作为 %p
的参数,但无论如何我都会将它们强制转换为 void*
。) - Keith Thompsonsize_t
强制转换为 unsigned long
并使用 %u
进行打印。只要被打印的值不超过 2^32-1,就可以保证打印出正确的结果。 - Keith Thompson
size_t
不能是int
,而且在一些8/16位和大多数64位架构中,ptrdiff_t
也不会是int
。 - too honest for this sitelu
将其打印出来,将值强制转换为(unsigned long)
- 实际值可能按照某个大的模数显示,但这大概是在如此过时的标准下所能获得的最好效果了。 - Antti Haapala -- Слава Україні