Программирование на C и C++

Онлайн справочник программиста на C и C++

Перечисления

Перечисления - это набор именованных целочисленных констант, определяющий все допустимые значения, которые может принимать переменная. Перечисления можно встретить в повседневной жизни. Например, в качестве перечислений монет в Соединенных Штатах используются:

один цент, пять центов, десять центов, двадцать пять центов, полдоллара, доллар

Перечисления определяются с помощью ключевого слова 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.

Поскольку значения перечислений должны преобразовываться вручную к строкам, которые могут читать люди, они наиболее полезны в подпрограммах, не выполняющих такие преобразования. Например, перечисления, как правило, используются для определения символьном таблицы компилятора.