ChatGPT解决这个技术问题 Extra ChatGPT

中与平台无关的 size_t 格式说明符?

我想在 C 中打印出 size_t 类型的变量,但似乎 size_t 在不同架构上被别名为不同的变量类型。例如,在一台机器(64 位)上,以下代码不会引发任何警告:

size_t size = 1;
printf("the size is %ld", size);

但在我的另一台机器(32 位)上,上面的代码会产生以下警告消息:

警告:格式“%ld”需要类型“long int *”,但参数 3 的类型为“size_t *”

我怀疑这是由于指针大小的不同,所以在我的 64 位机器上 size_t 别名为 long int ("%ld"),而在我的 32 位机器上 size_t 别名为另一个类型。

是否有专门针对 size_t 的格式说明符?

您的警告消息与代码不匹配。警告提到了指针,您的代码没有任何指针。您是否在某处删除了一些 &
指针?不,我没有收到任何关于指针的警告,实际上取决于我在哪台机器上运行该代码,有时我根本没有收到任何警告。试试下面的测试代码:#include int main(){ size_t size = 1; printf("大小为 %ld", size);返回0; }
@EthanHeilman 他指的是您的警告说warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *',而它可能应该warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'。当您收到这些警告时,您是否使用了 scanf()

a
anatolyg

是:使用 z 长度修饰符:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

其他可用的长度修饰符有 hh(用于 char)、h(用于 short)、l(用于 long)、ll(用于 long long)、{9 }(用于 intmax_t)、t(用于 ptrdiff_t)和 L(用于 long double)。参见 C99 标准的 §7.19.6.1 (7)。


zd和zu有什么区别?我知道 zd 是十进制的,但它是否已签名,如果是这样,zd 被签名会如何影响事物。
这是 size_tssize_t 之间的区别;后者很少使用。
对,所以在这种情况下,您应该使用 %zu,因为参数是无符号的。
printf 手册页中解释了其他可用选项:linux.die.net/man/3/printf
@detly:不,z 长度修饰符不是 C89/C90 的一部分。如果您的目标是符合 C89 的代码,您可以做的最好的事情是强制转换为 unsigned long 并改用 l 长度修饰符,例如 printf("the size is %lu\n", (unsigned long)size);;同时支持 C89 和 size_t 大于 long 的系统比较棘手,并且需要使用许多预处理器宏。
m
maxschlepzig

就在这里。它是 %zu(在 ANSI C99 中指定)。

size_t size = 1;
printf("the size is %zu", size);

注意 size_t 是无符号的,因此 %ld 是双重错误的:错误的长度修饰符和错误的格式转换说明符。如果您想知道,%zd 代表 ssize_t(已签名)。


A
Arkantos

MSDN,表示 Visual Studio 支持在 32 位和 64 位平台上可移植代码的“I”前缀。

size_t size = 10;
printf("size is %Iu", size);

它是特定于 MS 的,不符合标准,因此它不是独立于平台的
@phuclv 确实。如果它真的说——正如答案所暗示的那样——“便携”,那比我对 MS 的了解还要糟糕。并不是说这会让我感到惊讶......我不是一个拒绝投票的人,因为有人努力尝试回答某些问题,但这个答案仍然是错误的。啊,我想我在“便携式”中理解了这个想法。必须说它适用于 32 位和 64 位。但当然会。