【问题标题】:Number of elements in an enum枚举中的元素数
【发布时间】:2010-10-17 06:46:09
【问题描述】:

在 C 中,有没有一种很好的方法来跟踪枚举中的元素数量?我见过

enum blah {
    FIRST,
    SECOND,
    THIRD,
    LAST
};

但这只有在项目是连续的并且从零开始的情况下才有效。

【问题讨论】:

标签: c enums


【解决方案1】:

如果你不分配你的枚举,你可以这样做:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

NumberOfTypes 将评估为 3,这是实际类型的数量。

【讨论】:

  • 你能始终确保在每个 C 实现中,任何时候枚举都从 0 开始吗​​?我想是的,但它总是真的吗?
  • 迟到的答案@JohnyTex,但 C 标准在“枚举说明符”下提到:If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. 所以是的,这将适用于任何遵守标准的实现。
【解决方案2】:

我不相信有。但是,如果它们不是连续的,并且您在某个地方还没有它们的列表,您将如何处理这样的数字?如果它们是连续的但从不同的数字开始,你总是可以这样做:

enum blah {
    FIRST = 128,
    SECOND,
    THIRD,
    END
};
const int blah_count = END - FIRST;

【讨论】:

  • 枚举类型可以是负数吗?如果是这样,请注意这个。
  • FIRST=-2 仍然可以正确计算,我认为:1 - (-2) = 3。
  • 不用小心;减法适用于负数。 Pax 说得对。
  • 第一 = -200,第二 = -199,第三 = -198,结束 = -100。 -200 - (-100) = 坏消息
  • 不,你会得到 FIRST = -9 SECOND = -8 THIRD = -7 END = -6,所以你会有 -6 - (-9) = -6 + 9 = 3
【解决方案3】:

老问题,我知道。这是为有相同问题的谷歌员工准备的。

你可以使用X-Macros

例子:

//The values are defined via a map which calls a given macro which is defined later
#define ENUM_MAP(X) \
      X(VALA, 0)    \
      X(VALB, 10)   \
      X(VALC, 20)

//Using the map for the enum decl
#define X(n, v) [n] = v,
typedef enum val_list {
    ENUM_MAP(X) //results in [VALA] = 0, etc...
} val_list;
#undef X

//For the count of values
#define X(n, v) + 1
int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1
#undef X

这对 IDE 也是透明的,因此自动完成可以正常工作(因为它全部在预处理器中完成)。

【讨论】:

  • 太棒了,我真的来这里是因为我正在寻找一种确定X_MACRO中元素数量的好方法,这是一个好方法。
  • 您也可以使用惯用的(sizeof val_list / sizeof val_list[0]) 来获取val_list 数组中的元素数量
  • 不过应该​​是n = v,
【解决方案4】:

很遗憾,没有。没有。

【讨论】:

【解决方案5】:

我知道这是一个非常古老的问题,但由于接受的答案是错误的,我觉得有必要发表我自己的。我将重用已接受答案的示例,稍作修改。 (假设枚举是顺序的。)

// Incorrect code, do not use!
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST;
// And this above would be 3 - 0 = 3, although there actually are 4 items.

任何开发人员都知道原因:count = last - first + 1。 这适用于任何符号组合(两端均为负,均为正,或仅第一端为负)。你可以试试。

// Now, the correct version.
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST + 1; // 4

编辑:再次阅读文本,我有一个疑问。 END 是否不属于所提供项目的一部分?这对我来说看起来很奇怪,但好吧,我想这可能是有道理的......

【讨论】:

  • 意图是枚举中有 3 个元素 (FIRST, SECOND & THIRD),最后一个是始终指定列表末尾的占位符,因此如果添加其他项目,则不会有必要更改项目计数的公式。
  • 是的,这就是我几个小时后再次阅读时的想法。感谢您的确认。 END 旁边的注释说“不打算被使用”或其他内容可能有助于理解代码。
  • 我喜欢使用类似“blah_end_marker”的约定; “end_marker”标识目的,而前缀使结束标记不同。然后您可以定义计数,或者对于从 0 开始的“顺序”枚举,直接使用标记值(例如“blah all_blahs[blah_end_marker];” - 尽管我开始认为 const int blah_count 更有意义......
【解决方案6】:

好吧,由于枚举不能在运行时改变,你能做的最好的事情是:

enum blah {
    FIRST = 7,
    SECOND = 15,
    THIRD = 9,
    LAST = 12
};
#define blahcount 4 /* counted manually, keep these in sync */

但我发现很难想象这种信息会派上用场的情况。你到底想做什么?

【讨论】:

  • 是的,你为什么要这样做!
  • 我有一种情况,我想将枚举值随机分配给一个数组。我需要知道有多少不同的值,这样我才能得到正确的范围。
【解决方案7】:
int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};

#define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );

【讨论】:

  • 这似乎需要在数组中重复整个枚举,纯粹是为了允许使用 sizeof - 对我来说似乎比 #define COUNT 4 更努力
  • 在 C 中,大小在编译时计算。 C 不是解释型语言,这种方法与使用修复定义一样有效,并且简化了维护。
  • 除非它不是。这将使用NUM_ENUMS int 的无用数组污染程序的符号。您的程序将需要更长的时间才能启动,将使用更多的磁盘空间等等。避免这种情况的唯一方法是在一个独立的编译单元中声明和定义它,但是你没有NUM_ENUMS 可用,所以这不起作用。稍后,如果您将成员添加到枚举列表中,您可能会忘记在数组中这样做,NUM_ENUMS 将不再匹配
【解决方案8】:
#include <stdio.h>

// M_CONC and M_CONC_ come from https://stackoverflow.com/a/14804003/7067195
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B

#define enum_count_suffix _count
#define count(tag) M_CONC(tag, enum_count_suffix)
#define countable_enum(tag, ...) \
  enum tag {__VA_ARGS__}; \
  const size_t count(tag) = sizeof((int []) {__VA_ARGS__}) / sizeof(int)

// The following declares an enum with tag `color` and 3 constants: `red`,
// `green`, and `blue`.
countable_enum(color, red, green, blue);

int main(int argc, char **argv) {
  // The following prints 3, as expected.
  printf("number of elements in enum: %d\n", count(color));
}

【讨论】:

  • 这很好 否则 但是当值被明确赋值并且你的代码会中断时,OP 专门要求计算成员。
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多