- •Массивы структур
- •Структуры – параметры функций
- •Если обработка структуры в функции связана с изменением содержимого полей, то такую структуру необходимо передавать по указателю или по ссылке. Доступ к отдельному биту
- •Структуры
- •9.1.1. Объявление и инициализация структур
- •Структуры – параметры функций
- •9.1.3.Функции, возвращающие структуры
- •9.2. Перечисления
- •9.3. Объединения
9.2. Перечисления
Перечисления представляют собой список идентификаторов, введенных пользователем:
enum name_list {name1,name2,...};
За каждым таким именем по умолчанию закрепляются целочисленные константы:
имени name1 соответствует константа 0;
имени name2 соответствует константа 1;
.....................................
В чем смысл замены целочисленных констант такими символьными обозначениями? Дело в том, что в конкретных прикладных задачах удобно иметь дело с мнемоническими обозначениями характеристик некоторых объектов. Например, имея дело с цветами радуги, было бы удобно ввести обозначение для палитры радуги (rainbow) и перечислить в ней цвета в том порядке, как они упорядочены в природе ("каждый охотник желает знать, где сидят фазаны" – красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый):
enum rainbow {red, orange, yellow, green, aqua, blue, purple};
Переменная r_col, которая будет в дальнейшем обозначать цвет радуги, должна быть связана с именем списка, и это позволит присваивать ей значения, более понятные, чем соответствующие целые числа:
enum rainbow r_col;
r_col=yellow;
...............
if(r_col==yellow)...
В языке C++ при объявлении переменных типа перечисление разрешается опускать служебное слово enum:
rainbow r_col=yellow;
В программах обработки экономической информации очень часто приходится иметь дело с названиями месяцев, дней недели. В таких случаях полезно прибегать к перечислениям типа:
enum week {sunday=1, monday, tuesday, wednesday, thursday,
friday, saturday};
enum month {jan=1, feb, mar, apr, may, jun, jul, aug, sep,
oct, nov, dec };
В приведенных выше примерах две особенности. Во-первых, нумерация констант по умолчанию с 0 противоречит общепринятым нормам работы с календарем. Поэтому для первой константы указано нестандартное значение 1, а все последующие будут пронумерованы в порядке возрастания номеров. Во-вторых, в перечислении названий месяцев имеется возможность нарваться на сообщение об ошибке. Дело в том, что сокращения для "октября" и "декабря" совпадают со служебными словами oct - восьмеричный и dec - десятичный, которые участвуют в управлении потоковым выводом числовых данных. Можно перейти к другим обозначениям, где первая буква месяца будет заглавной, тогда конфликта удастся избежать.
Перечисления очень широко используются многими системными программами, особенно графическими:
enum line_style{SOLID_LINE, //сплошная линия
DOTTED_LINE, //пунктирная линия
CENTER_LINE, //штрих-пунктирная линия
DASHED_LINE, //штриховая линия
USERBIT_LINE}; //линия, определяемая пользователем
enum COLORS {BLACK,BLUE,GREEN,CYAN,RED,MAGENTA,BROWN,...};
Системный набор операций над переменными типа перечислений довольно ограниченный: им можно присваивать значения из объявленного списка, сравнивать значения однотипных переменных, передавать в качестве параметров другим функциям. Попытка вывести их значения приводит к появлению на экране приписанных им числовых номеров. Даже какой-то контроль за выходом из допустимого числового интервала для этих данных не реализован. Об этом свидетельствует следующий пример:
#include <stdio.h>
#include <conio.h>
void main()
{ enum qq {zero, one, two, three};
enum qq a,b;
a=one;
b=a+two;
printf("a=%d b=%d",a,b);
getch();
}
//=== Результат работы ===
a=1 b=3
Правда, при компиляции 7-й строки было выдано предупреждение о попытке присвоения значения типа int переменной типа qq, но все обошлось. Однако замена на оператор b=a+three; никаких эмоций у компилятора не вызвала и был получен результат b=4. Даже попытка выполнить b=5; тоже прошла гладко. Так что с данными типа enum компилятор работает как с целыми числами и на выход за пределы заданного диапазона внимания не обращает.
Обратим внимание еще на один нюанс в приписывании числовых номеров константам из перечисления:
enum num12 {one=1,ein=1,two,zwei=2};
Этот пример демонстрирует, что числовые номера в списке констант могут дублироваться, но сами имена должны быть уникальными. Использование одного и того же имени в двух разных перечислениях недопустимо.