Количество элементов в перечислении
В C есть хороший способ отслеживать количество элементов в перечислении? Я видел
enum blah {
FIRST,
SECOND,
THIRD,
LAST
};
Но это работает только в том случае, если элементы являются последовательными и начинаются с нуля.
Ответы
Ответ 1
Я не верю, что есть. Но что бы вы сделали с таким числом, если они не являются последовательными, и у вас их еще нет? И если они последовательны, но начинаются с другого номера, вы всегда можете:
enum blah {
FIRST = 128,
SECOND,
THIRD,
END
};
const int blah_count = END - FIRST;
Ответ 2
Если вы не назначаете свои перечисления, вы можете сделать что-то вроде этого:
enum MyType {
Type1,
Type2,
Type3,
NumberOfTypes
}
NumberOfTypes будет оценивать значение 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, поэтому автозавершения будут работать нормально (поскольку все это сделано в предварительном процессоре).
Ответ 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
означает не быть частью предлагаемых предметов? Это выглядит странно для меня, но хорошо, я думаю, это может иметь смысл...
Ответ 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 );
Ответ 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
Попробуйте следующее:
Это некрасиво, и могут быть некоторые компиляторы, которым это не нравится, но обычно это работает и полезно. Вы можете использовать его для каждого типа перечисления.