【问题标题】:sizeof(struct) and sizeof(union)sizeof(struct) 和 sizeof(union)
【发布时间】:2014-04-03 17:14:43
【问题描述】:
struct One{
       int x[6];
       short y[12];
} a;

union Two{
       int x[6];
       short y[12];
} b;

假设 int 是 32 位,而 short 是 16 位。

一个。 sizeof(a) 和 sizeof(b) 是什么?

b.如果&a = 0x00320000,那么&a.y是什么?

c。如果&b = 0x00320400,那么&b.y是什么?

谁能解释一下如何导出联合和结构的大小,以及如何获取地址的值。我理解 &a 和 &b 分别表示 a 和 b 的地址。但是,我不确定如何得出 &a.y 和 &b.y 将返回的结果。

【问题讨论】:

  • 为什么不自己编译检查一下。
  • 结构和联合的根本区别是什么?这将在很大程度上控制答案——这也是家庭作业的目的。简而言之,联合的大小是其最大元素的大小。结构的大小是其元素大小的总和,加上需要的填充。
  • 即使给定每种类型的位数,这仍然取决于编译器和系统。
  • 您想要语言律师的答案还是仅针对特定实施的答案?
  • @Shan:该死的,不要强化这种坏主意。它们只适用于一种特定的实现,并且可能只适用于源/编译器/OS/whathaveyou 中的下一个最轻微的错误修复。

标签: c


【解决方案1】:

一个。你不知道。这就是sizeof(struct One) 的用途。认为结构的大小是其元素的总和是一种常见的误解 - 出于对齐原因,实现可以在任何点(除了开头)填充结构 - 实现可以填充任何数量的任何成员之后的结构,尽管以相同初始类型开头的两个结构在相同的偏移量处具有相应的成员(如评论中指出的那样)。对于并集,它是最大字段的大小,即max(sizeof(b.x), sizeof(b.y))

b.和 c。使用宏 offsetof() 作为一种可移植的方式来查找结构中字段的偏移量。 &a.y 就是 ((char *) a)+offsetof(struct One, y)。对于 union,&b&b.x&b.y 都是一样的。

编辑:您可以使用编译器特定的选项来控制填充和对齐。例如,请参阅gcc's structure padding pragmas

【讨论】:

  • 也许改成:实现可以在任何成员之后填充结构,但其初始类型相同的两个结构具有相同偏移量的相应成员...
  • @Deduplicator 正确,我同意。已编辑。
  • 所以只是为了验证我的思维过程是否正确。 sizeof(a) 将是 (32*6) + (16*12) = 384。sizeof(b) 将是 32*6 = 192。然后对于偏移量,&a.y 0x00320016 和 &b.y 它会保持 0x00320400。对吗?
  • sizeof a >= 6*sizeof(int)+12*sizeof(short)。 sizeof 以字节为单位给出大小 (char)。如果您需要移动到 bitcount,请使用 CHAR_BITS
  • 您可能想补充一点,有编译器特定的选项/指令用于强制执行特定的填充和对齐规则。不过,这并不会影响您的原点。
【解决方案2】:

尽管在大多数情况下,答案是实现定义的,但调试和故障排除的程序员需要知道(可能的)答案是什么,在他/她的平台上:

一个。 sizeof(a) 和 sizeof(b) 是什么?

sizeof a = 6 * 4 + 12 * 2 = 48。重要提示:如果您将12 更改为13,此计算可能会出错,因为通常会添加填充,可能是 2 个字节,因此结构的大小不会是其元素大小的总和。

sizeof b = max(6 * 4, 12 * 2) = 24,因为在这个联合中,xy 是重叠的。同样,如果您将12 更改为13,则可能存在填充。

b.如果 &a = 0x00320000,&a.y 是什么?

&a.y = 0x00320000 + 6 * 4 = 0x00320018

c。如果 &b = 0x00320400,&b.y 是什么?

&b.y = &b(保证)

【讨论】:

  • 这也是我的理解,但给定的信息“假设整数是 32 位,而短裤是 16 位”让我失望。那么我还会认为 int 是 4 位,而 short 是 2 位吗?
  • A 32-bit int 是 4 bytes,在所有系统上初学者会遇到。
  • 如果您需要更正确的解释,另请参阅What is CHAR_BIT?
  • @Joseph:除非他从嵌入式系统开始,否则会发生这种情况。
【解决方案3】:

a.) A 的大小将是 sizeof(int) * 6 + sizeof(short) * 12,或 72 字节(可能加上几个字节用于对齐)。而 b 的大小将是 48,即最大成员的大小。基本上,联合被用作对同一内存空间进行别名的一种方式,因此编译器在确定联合将占用内存的多少空间时必须使用最大成员的大小。

b.) 地址将是 0x00320018。

c.) 地址将是 0x00320400,因为 b.X 和 b.Y 都存储在同一个位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-18
    • 2011-08-25
    • 2015-10-14
    • 2019-11-23
    • 2014-06-07
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多