具有printf格式的"%zd"需要有符号类型的参数,该参数对应于无符号类型size_t。
标准C没有为这种类型提供名称,也没有提供确定它是什么的好方法。例如,如果size_t是unsigned long的类型--那么"%zd"需要一个long类型的参数,但这不是一个可移植的假设。
该标准要求相应的有符号类型和无符号类型对两种类型中可表示的非负值使用相同的表示形式。一个脚注说,这意味着它们作为函数参数是可互换的。所以这个:
代码语言:javascript复制size_t s = 42;
printf("s = %zd\n", s);应该工作,并应打印"42“。它将解释无符号类型42的值size_t,就好像它是对应的有符号类型一样。但是没有充分的理由这样做,因为"%zu"也是正确的,并且定义得很好,而不需要使用其他的语言规则。"%zu"适用于size_t类型的所有值,包括相应的有符号类型范围以外的值。
最后,POSIX在标头ssize_t和中定义了一个类型的。虽然POSIX没有明确地这样说,但是ssize_t很可能是与size_t相对应的有符号类型。因此,如果您正在编写特定于POSIX的代码,"%zd"可能是打印ssize_t类型值的正确格式。
UPDATE: POSIX 明示 -- ssize_t并不一定是size_t的签名版本,因此编写假定为size_t的代码是不明智的:
ssize_t
这是一个签名的模拟size_t。其措辞是这样的:实现可以选择使用更长的类型,也可以简单地使用作为size_t基础的类型的签名版本。返回ssize_t (read()和write()) )的所有函数都将输入超过{SSIZE_MAX}的结果描述为“实现定义的”。可以认识到,某些实现可能具有比int更小的size_t。符合规范的应用程序将被限制不以大于{SSIZE_MAX}的块执行I/O,但是使用扩展的合格应用程序将能够使用整个范围,如果实现提供了扩展范围,同时仍然具有单一类型兼容接口。size_t和ssize_t符号在