【问题标题】:How to calculate the size of enum [duplicate]如何计算枚举的大小[重复]
【发布时间】:2019-09-20 12:22:51
【问题描述】:
typedef enum enumStruc_2 {
    ENUM_5 = 0xFFFFFFF0, ENUM_6, ENUM_7, ENUM_8
} enumStruc_2;

这里,枚举的大小是 4 个字节(整数大小)。它如何将其所有枚举成员值保存在 4 个字节内? 无论其成员的值如何,枚举大小总是 4 字节吗?

【问题讨论】:

  • enum 有四个不同的顺序值。为了能够表示所有四个不同的值,需要不超过两位。由于编译器需要查看枚举才能使用它,因此它可以使用int 作为基础类型轻松地表示它(实际上)。如果您平台上的本机 int 是 32 位的,那将解释 sizeof 给出的结果为 4。而且,不,枚举类型的大小不能保证为 4。它们的大小是实现定义的 - 标准对它们的大小应该保持沉默。
  • 问题与C有关
  • 当已有答案时,请不要编辑语言标签。是的,这应该只标记为 C,但是一旦发布了 C++ 答案,就为时已晚。对于同时带有 C 和 C++ 标签的案例,请考虑tag wiki 中的标签审核指南。

标签: c++ c enums


【解决方案1】:

enum 的大小取决于实现。来自C standard 中关于枚举说明符的第 6.7.2.2p4 节:

每个枚举类型都应兼容 char ,有符号整数类型,或无符号整数类型。
类型的选择是实现定义的,但应该是 能够代表所有成员的价值观 的枚举。枚举类型不完整,直到 紧跟在终止枚举数列表的} 之后 声明,然后完成。

所以enum 类型的大小可以是intchar 或任何其他整数类型的大小。比如gcc sizes enums如下:

通常,如果没有负值,则类型为unsigned int 枚举,否则为int。如果指定了-fshort-enums,那么如果 有负值是signed charshortint 可以表示所有值,否则为第一个 unsigned charunsigned shortunsigned int可以代表所有 值。

至于每个成员的价值观,第 3 段规定:

枚举器列表中的标识符声明为 具有int 类型的常量,并且可能出现在任何位置
被允许。 枚举器 = 将其枚举常量定义为常量表达式的值。 如果第一个枚举数没有 = ,其枚举常量的值为0。后面的每个枚举数都没有 = 将其枚举常量定义为常量表达式的值加 1 得到的值 以前的枚举常量。(枚举器的使用与 = 可能会生成枚举常量,其值与同一枚举中的其他值重复。)枚举的枚举数 也称为其成员。

在这种情况下,常量ENUM_5 被显式分配值0xFFFFFFF0,所以ENUM_60xFFFFFFFENUM_70xFFFFFFF2ENUM_80xFFFFFFF3。这些常量中的每一个都需要 4 个字节来存储值,因此这个特定的 enum 的大小必须至少为 4 个字节,尽管它可能更大。

关于:

它如何将其所有枚举成员值保存在 4 个字节内?

它不会同时容纳所有 4 个成员。一个枚举可以容纳这 4 个成员中的一个。您正在定义一个类型,而不是一个值。例如:

enum enumStruc_2 e1 = ENUM_5;
enum enumStruc_2 e2 = ENUM_6;

【讨论】:

  • 为什么它的内存大小不是 4*sizeof(int) 当它容纳 4 个成员时?
  • @SurendarSekar 它不会同时容纳所有 4 个成员。一个枚举可以容纳 其中一个 这 4 个成员。您正在定义一个类型,而不是一个值。例如enum enumStruc_2 e1 = ENUM_5.
  • @SurendarSekar 很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer
【解决方案2】:

类型的大小不是存储该类型的所有可能值所需的大小。它是存储该类型的一个实例所需的大小。

【讨论】:

  • 如何在4个字节内存储0xFFFFFFF0,0xFFFFFFF1,0xFFFFFFF2,0xFFFFFFF3这4个值?
  • 问“枚举如何存储 4 个值”就像问“int 如何存储数百万个可能的值”。它没有。 一个整数存储一个整数值。如果要存储 40 个整数值,则需要 40 个整数。同样,枚举类型的 one 变量存储枚举的 一个 可能值,它需要有足够的大小才能做到这一点。您的停车位需要容纳一辆车,而不是您可能购买的所有汽车。
  • 还值得注意的是,“枚举的可能值之一”不仅仅是您在枚举定义中列出的值。这些只是捷径。它仍然可以合法地持有其基础类型的任何值(例如int)。
  • 是的,你是对的。这些枚举成员名称是否在预处理期间被替换为原始常量整数值,例如#define?
【解决方案3】:

在 C 和 C++ 中,枚举器 sizeof(enumStruc_2) 的大小是该枚举中任何单个元素的大小。

在 C 中,答案是 sizeof(int)。所以至少是 2。

在 C++ 中,答案是sizeof(std::underlying_type<enumStruc_2>::type)

【讨论】:

    【解决方案4】:

    当你声明一个枚举时,你做了两件事。首先是您声明一个具有枚举名称的新类型。此类型是一个整数类型,它足够大,可以存储您在枚举中使用的值的最大值,并且它不会小于int,除非您指定。

    接下来要做的是声明 0 个或多个该类型的常量值。这些不像类成员变量那样参与枚举的大小,因为它们不是真正的变量。它们只是您可以使用的命名常量,并且它们具有枚举类型的类型。这就是为什么你可以拥有尽可能多的枚举值并且sizeof(enum_name) 永远不会改变。

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 2020-01-07
      • 2021-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-02
      相关资源
      最近更新 更多