代码之家  ›  专栏  ›  技术社区  ›  Peter Gibson

枚举中的元素数

  •  39
  • Peter Gibson  · 技术社区  · 17 年前

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

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

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

    9 回复  |  直到 8 年前
        1
  •  34
  •   Brian Campbell Dennis Williamson    17 年前

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

    enum blah {
        FIRST = 128,
        SECOND,
        THIRD,
        END
    };
    const int blah_count = END - FIRST;
    
        2
  •  64
  •   vpicaver    13 年前

    如果不指定枚举,可以执行以下操作:

    enum MyType {
      Type1,
      Type2,
      Type3,
      NumberOfTypes
    }
    

    NumberOfTypes的计算结果为3,这是实际类型的数目。

        3
  •  19
  •   Sam    11 年前

    老问题,我知道。这是给有同样问题的谷歌用户的。

    你可以使用 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也是透明的,因此自动完成可以很好地工作(就像在预处理器中所做的那样)。

        4
  •  7
  •   rlbond    17 年前

    不幸的是,没有。

        5
  •  5
  •   David Stosik    11 年前

    我知道这是一个非常古老的问题,但由于公认的答案是错误的,我觉得不得不发表自己的答案。我将重用接受的答案示例,稍微修改一下。 (假设枚举是连续的。)

    // 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 不打算成为所提供物品的一部分?我觉得这很奇怪,但我想这是有道理的…

        6
  •  3
  •   paxdiablo    17 年前

    既然枚举在运行时不能改变,最好的方法是:

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

    但我发现很难设想这样一种情况,即信息会变得有用。你到底想做什么?

        7
  •  2
  •   DaveShaw Thishin    14 年前
    int enaumVals[] =
    {
    FIRST,
    SECOND,
    THIRD,
    LAST
    };
    
    #define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );
    
        8
  •  0
  •   mathedpotatoes    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));
    }
    
        9
  •  -3
  •   Legionar    9 年前

    试试这个:

    enter image description here

    它是丑陋的,可能有一些编译器不喜欢它,但它通常是有效的和有用的。您可以将它用于每个枚举类型。