Перечисления - это набор именованных целочисленных констант, определяющий все допустимые значения, которые может принимать переменная. Перечисления можно встретить в повседневной жизни. Например, в качестве перечислений монет в Соединенных Штатах используются:
один цент, пять центов, десять центов, двадцать пять центов, полдоллара, доллар
Перечисления определяются с помощью ключевого слова enum, которое указывает на начало перечисляемого типа. Стандартный вид перечислений следующий:
enum ярлык { список перечислений} список переменных;
Как имя перечисления - ярлык, так и список переменных необязательны, но один из них должен присутствовать. Список перечислений - это разделенный запятыми список идентификаторов. Как и в структурах, ярлык используется для объявления переменных данного типа. Следующий фрагмент определяет перечисление coin и объявляет переменную money этого типа:
enum coin { penny, nickel, dime, quarter, half_dollar, dollar };
enum coin money;
Имея данное определение и объявление, следующий тип присваивания совершенно корректен:
money = dime;
if (money==quarter) printf("is a quarter\n");
Важно понять, что в перечислениях каждому символу ставится в соответствие целочисленное значение и поэтому перечисления могут использоваться в любых целочисленных выражениях. Например:
printf("The value of quarter is %d ", quarter);
совершенно корректно.
Если явно не проводить инициализацию, значение первого символа перечисления будет 0, второго - 1 и так далее. Следовательно:
printf("%d %d", penny, dime);
выводит 0 2 на экран.
Можно определить значения одного или нескольких символов, используя инициализатор. Это делается путем помещения за символом знака равенства и целочисленного значения. При использовании инициализатора, символы, следующие за инициализационным значением, получают значение больше чем указанное перед этим. Например, в следующем объявлении quarter получает значение 100.
enum coin ( penny, nickel, dime, quarter=100, half_dollar, dollar);
Теперь символы получат следующие значения:
penny 0
nickel 1
dime 2
quarter 100
Half dollar 101
dollar 102
Используя инициализацию, более одного элемента перечисления могут иметь одно и тоже значение.
Заблуждением считается возможность прямого ввода или вывода символов перечислений. Следующий фрагмент кода не работает так, как нужно:
/* Не работает. */
money = dollar;
printf("%s", money);
Надо помнить, что символ dollar - это просто имя для целого числа, а не строка Следовательно, невозможно с помощью printf() вывести строку «dollar», используя значение в money. Аналогично нельзя сообщить значение переменной перечисления, используя строковый эквивалент. Таким образом, следующий код не работает:
/* этот код не будет работать */
money = "penny";
На самом деле, создание кода для ввода и вывода символов перечислений - это довольно скучное занятие. Например, следующий код необходим для вывода состояния money с помощью слов:
switch(money) {
case penny: printf("penny");
break;
case nickel: printf("nickel");
break;
case dime: printf("dime");
break;
case quarter: printf("quarter");
break;
case half_dollar: printf("half_dollar");
break;
case dollar: printf("dollar");
}
Иногда возможно объявить массив строк и использовать значения перечислений как индекс для их перевода в соответствующие строки. Например, следующий код также выводит соответствующую строку:
char name[][12]={
"penny",
"nickel",
"dime",
"quarter",
"half_dollar",
"dollar"
};
...
printf("%s", name[money] );
Конечно, это работает только в том случае, если не используется инициализатор, поскольку массив строк должен индексироваться начиная с 0.
Поскольку значения перечислений должны преобразовываться вручную к строкам, которые могут читать люди, они наиболее полезны в подпрограммах, не выполняющих такие преобразования. Например, перечисления, как правило, используются для определения символьном таблицы компилятора.