web-dev-qa-db-ja.com

列挙内の要素の数

Cでは、列挙型の要素の数を追跡する良い方法はありますか?私は見た

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

しかし、これはアイテムが連続していてゼロから始まる場合にのみ機能します。

40
Peter Gibson

あるとは思わない。しかし、それらが連続しておらず、それらのリストがまだどこかにない場合、そのような番号で何をしますか?そして、それらがシーケンシャルであるが、異なる番号で開始する場合は、いつでも実行できます。

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

列挙型を割り当てない場合、次のようなことができます。

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

NumberOfTypesは、実際の型の数である3に評価されます。

67
vpicaver

古い質問です。これは、同じ質問を持つグーグル向けです。

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に対して透過的であるため、オートコンプリートは正常に機能します(すべてプリプロセッサで行われます)。

23
Sam

残念だけど違う。存在しない。

7
rlbond

私はこれが非常に古い質問であることを知っていますが、受け入れられた答えが間違っているので、私は自分の質問を投稿せざるを得ません。受け入れられた回答の例を少し変更して再利用します。 (列挙型はシーケンシャルであると仮定します。)

// 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は提供されたアイテムの一部ではないことを意味しますか?それは私には奇妙に見えますが、まあ、それは理にかなっていると思います...

5
David Stosik
int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};

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

まあ、列挙型は実行時に変更できないため、できる最善の方法は次のとおりです。

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

しかし、その情報が役立つ状況を想像するのは難しいと思います。正確に何をしようとしていますか?

3
paxdiablo
#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));
}
0
mathedpotatoes