【问题标题】:Usage of zd vs lu for sizeofzd vs lu 用于 sizeof
【发布时间】:2021-04-15 11:00:42
【问题描述】:

我了解%zd 是格式化sizeof 结果的建议方式。但是,我不明白为什么这是必要的。例如,使用lu 给了我相同的输出,而且sizeof 的结果不是无符号长吗?例如:

printf("Sizeof(char): %lu, Sizeof(short): %lu, Sizeof(int): %lu, Sizeof(long): %lu, Sizeof(long long): %lu, Sizeof(float): %lu, Sizeof(double): %lu, Sizeof(long double): %lu\n"
       ,sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long), sizeof(float), sizeof(double), sizeof(long double));
printf("Sizeof(char): %zd, Sizeof(short): %zd, Sizeof(int): %zd, Sizeof(long): %zd, Sizeof(long long): %zd, Sizeof(float): %zd, Sizeof(double): %zd, Sizeof(long double): %zd"
       ,sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long), sizeof(float), sizeof(double), sizeof(long double));

Sizeof(char): 1, Sizeof(short): 2, Sizeof(int): 4, Sizeof(long): 8, Sizeof(long long): 8, Sizeof(float): 4, Sizeof(double) : 8, Sizeof(long double): 16
Sizeof(char): 1, Sizeof(short): 2, Sizeof(int): 4, Sizeof(long): 8, Sizeof(long long): 8, Sizeof(float): 4, Sizeof(double): 8, Sizeof(long double): 16

使用%zd 的原因或优势是什么?为什么首先添加它?

【问题讨论】:

  • sizeof 的结果是 size_t,它可能与 unsigned long 相同也可能不同,具体取决于您使用的编译器、操作系统和处理器。格式说明符是%zu,因为size_t 是无符号的。
  • 我想说because Microsoft...(但实际上他们可能不是唯一的)。
  • @user3386109 我明白了,size_t 也像 typedef size_t inttypedef size_t <something-else> 一样取决于平台?
  • 检查this回答。
  • 如果 size_tunsigned longunsigned int 都是 32 位大小(也可以是),那么使用 %zu%lu 或 @987654342 都没有关系@,但代码不可移植。这就是为什么您需要使用正确的说明符——以便printf() 知道传递的参数的大小。它所拥有的只是来自格式说明符的 promise 并且必须相信调用者传递了正确大小的操作数。没有别的办法知道,由程序员来匹配格式和类型。

标签: c printf size-t conversion-specifier


【解决方案1】:

sizeof 的结果不是无符号长吗?

不,它返回一个size_t,并且size_t 不必与unsigned long 大小相同。

例如,在 Windows 世界中,unsigned long 是 32 位,size_t 是 64 位。

我了解%zd 是格式化sizeof 结果的建议方式。

不完全是。

%zu 用于size_t(或%zX%zx%zo
%zd 用于ssize_t

由于sizeof 返回size_t,您需要%zu

【讨论】:

  • 标准 C 中是否有 ssize_t? cppreference 说%zd 用于“已签名 size_t”,我不确定这意味着什么。
  • This answer 阐明了这个问题,它还提到 ssize_t 是 POSIX 事物,不一定是 size_t 的签名版本。所以说%zd 代表ssize_t 是不准确的。
  • @Ayxan Haqverdili,关于“标准 C 中有 ssize_t 吗?”,我没说有。 /// Re "它还提到ssize_t不一定是size_t的签名版本",实际上,它几乎说相反。它指出,虽然 POSIX 规范没有明确说明类型是匹配的,但它被理解为是。
  • 当然,实际上ssize_t 是有符号的size_t,但ptrdiff_t 也是如此,%zd 很可能适用于任何大小与size_t 相同的有符号整数.我想提一下如果 OP 感兴趣,哪些标准中存在哪些保证。
  • @ikegami POSIX 的基本原理是“他的目的是作为 size_t 的有符号模拟。措辞是这样的,实现可以选择使用更长的类型或简单地使用属于 size_t 的类型。” pubs.opengroup.org/onlinepubs/9699919799/xrat/…
【解决方案2】:

运算符sizeof返回的值的类型为size_t

来自 C 标准(6.5.3.4 sizeof 和 alignof 运算符)

5 两个运算符的结果值是实现定义的, 它的类型(无符号整数类型)是 size_t,定义在 (和其他头文件)。

size_t 类型是实现定义的无符号整数类型。通常它被定义为 unsigned long 类型的别名,尽管 C 标准不要求这样做。特别是标准允许size_t 类型的等级可以大于 unsigned long 类型的等级。

来自 C 标准(7.19 通用定义

4 用于 size_t 和 ptrdiff_t 的类型不应为整数 转换等级大于signed long int,除非 实现支持足够大的对象以使其成为必要。

所以要输出 size_t 类型的值,您应该使用转换说明符 zu

【讨论】:

    猜你喜欢
    • 2013-02-19
    • 2023-03-10
    • 2012-04-13
    • 2010-12-25
    • 2021-03-25
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    相关资源
    最近更新 更多