Хорошо, давайте ненадолго оставим C ++ в стороне. C ++ - это просто расширенный набор C (это означает, что все, что можно сделать в C, можно сделать и в C ++). Итак, давайте сосредоточимся на обычном C (потому что это язык, который я хорошо знаю). C имеет перечисления:
enum fruit { apple, banana, cherry, peach, grape };
Это совершенно допустимый C, и значения являются смежными, и яблоко имеет значение ноль, а банан имеет значение яблоко + 1. Вы можете создавать перечисления с дырками, но только если вы явно делаете отверстия как это
enum fruit { apple = 0, banana, cherry = 20, peach, grape };
В то время как яблоко - 0, а банан - 1, вишня - 20, таким образом, персик - 21, а виноград - 22, и все между 1 и 20 неопределено. Обычно вы не хотите дыр. Вы можете сделать следующее:
enum fruit { apple = 0, banana, cherry, peach, grape };
enum fruit myFruit = banana;
myFruit++;
// myFruit is now cherry
printf("My fruit is cherry? %s\n", myFruit == cherry ? "YES" : "NO");
Это напечатает ДА. Вы также можете сделать следующее:
enum fruit { apple = 0, banana, cherry = 20, peach, grape };
enum fruit myFruit = banana;
myFruit++;
// myFruit is now cherry
printf("My fruit is cherry? %s\n", myFruit == cherry ? "YES" : "NO");
При этом будет напечатано NO, и значение myFruit будет не таким, как любая из констант перечисления.
Кстати, во избежание того, что вы должны сказать «enum fruit myFruit», вы можете избежать перечисления с помощью typedef. Просто используйте «typedef enum fruit fruit»; на собственной линии. Теперь вы можете сказать «Фрукты myFruit» без перечисления впереди. Это часто делается непосредственно при определении перечисления:
typedef enum fruit { apple = 0, banana, cherry, peach, grape } fruit;
fruit myFruit;
Недостаток в том, что вы больше не знаете, что фрукт - это перечисление, это может быть объект, структура или что-то еще. Я обычно избегаю такого типа typedefs, я скорее пишу enum перед, если enum, и struct перед, если struct (я просто буду использовать их здесь, потому что это выглядит лучше).
Получить строковое значение невозможно. Во время выполнения перечисление - это просто число. Это означает, что это невозможно, если вы не знаете, что это за перечисление (0 может быть яблоком, но это может быть и другая вещь из другого набора перечислений). Однако, если вы знаете, что это фрукт, тогда легко написать функцию, которая сделает это за вас. Препроцессор - твой друг: -)
typedef enum fruit {
apple = 0,
banana,
cherry,
peach,
grape
} fruit;
#define STR_CASE(x) case x: return #x
const char * enum_fruit_to_string(fruit f) {
switch (f) {
STR_CASE(apple); STR_CASE(banana); STR_CASE(cherry);
STR_CASE(peach); STR_CASE(grape);
}
return NULL;
}
#undef STR_CASE
static void testCall(fruit f) {
// I have no idea what fruit will be passed to me, but I know it is
// a fruit and I want to print the name at runtime
printf("I got called with fruit %s\n", enum_fruit_to_string(f));
}
int main(int argc, char ** argv) {
printf("%s\n", enum_fruit_to_string(banana));
fruit myFruit = cherry;
myFruit++; // myFruit is now peach
printf("%s\n", enum_fruit_to_string(myFruit));
// I can also pass an enumeration to a function
testCall(grape);
return 0;
}
Вывод:
banana
peach
I got called with fruit grape
Это именно то, что вы хотели, или я здесь не на том пути?