C Language
Перечисления
Поиск…
замечания
Перечисления состоят из ключевого слова enum
и необязательного идентификатора, за которым следует список перечислителей, заключенный в фигурные скобки.
Идентификатор имеет тип int
.
Список перечислителей имеет как минимум один элемент перечисления .
Перечислитель может необязательно «назначать» постоянное выражение типа int
.
Перечислитель является постоянным и совместим либо с char
, либо с целым char
, либо с целым числом без знака. Используемый когда-либо используется для реализации . В любом случае используемый тип должен иметь возможность представлять все значения, определенные для рассматриваемой нумерации.
Если не константа не «назначен» на переписчик , и это 1 - й вход в перечислителях-листе он принимает значение 0
, иначе получите принимает значение предыдущей записи в перечислителях-листе плюс 1.
Использование нескольких «назначений» может привести к тому, что разные счетчики того же перечисления несут одни и те же значения.
Простое перечисление
Перечисление представляет собой пользовательский тип данных, состоящий из интегральных констант, и каждой интегральной константе присваивается имя. Перечисление enum
слова используется для определения перечислимого типа данных.
Если вы используете enum
вместо int
или string/ char*
, вы увеличиваете проверку времени компиляции и избегаете ошибок при передаче недопустимых констант, и вы документируете, какие значения являются законными для использования.
Пример 1
enum color{ RED, GREEN, BLUE };
void printColor(enum color chosenColor)
{
const char *color_name = "Invalid color";
switch (chosenColor)
{
case RED:
color_name = "RED";
break;
case GREEN:
color_name = "GREEN";
break;
case BLUE:
color_name = "BLUE";
break;
}
printf("%s\n", color_name);
}
С основной функцией, определенной следующим образом (например):
int main(){
enum color chosenColor;
printf("Enter a number between 0 and 2");
scanf("%d", (int*)&chosenColor);
printColor(chosenColor);
return 0;
}
Пример 2.
(В этом примере используются назначенные инициализаторы, которые стандартизованы с C99.)
enum week{ MON, TUE, WED, THU, FRI, SAT, SUN };
static const char* const dow[] = {
[MON] = "Mon", [TUE] = "Tue", [WED] = "Wed",
[THU] = "Thu", [FRI] = "Fri", [SAT] = "Sat", [SUN] = "Sun" };
void printDayOfWeek(enum week day)
{
printf("%s\n", dow[day]);
}
В этом же примере используется проверка диапазона:
enum week{ DOW_INVALID = -1,
MON, TUE, WED, THU, FRI, SAT, SUN,
DOW_MAX };
static const char* const dow[] = {
[MON] = "Mon", [TUE] = "Tue", [WED] = "Wed",
[THU] = "Thu", [FRI] = "Fri", [SAT] = "Sat", [SUN] = "Sun" };
void printDayOfWeek(enum week day)
{
assert(day > DOW_INVALID && day < DOW_MAX);
printf("%s\n", dow[day]);
}
Typedef перечисление
Существует несколько возможностей и условных обозначений для перечисления. Первое - использовать имя тега сразу после ключевого слова enum
.
enum color
{
RED,
GREEN,
BLUE
};
Это перечисление должно всегда использоваться с ключевым словом и тегом, как это:
enum color chosenColor = RED;
Если мы используем typedef
непосредственно при объявлении enum
, мы можем опустить имя тега, а затем использовать тип без ключевого слова enum
:
typedef enum
{
RED,
GREEN,
BLUE
} color;
color chosenColor = RED;
Но в этом последнем случае мы не можем использовать его как enum color
, потому что мы не использовали имя тега в определении. Одна общая конвенция использовать оба, так что же имя может использоваться с или без enum
ключевых слов. Это имеет особое преимущество совместимости с C ++
enum color /* as in the first example */
{
RED,
GREEN,
BLUE
};
typedef enum color color; /* also a typedef of same identifier */
color chosenColor = RED;
enum color defaultColor = BLUE;
Функция:
void printColor()
{
if (chosenColor == RED)
{
printf("RED\n");
}
else if (chosenColor == GREEN)
{
printf("GREEN\n");
}
else if (chosenColor == BLUE)
{
printf("BLUE\n");
}
}
Подробнее о typedef
см. Typedef
Перечисление с дублирующимся значением
Значение перечислений никоим образом не должно быть уникальным:
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
enum Dupes
{
Base, /* Takes 0 */
One, /* Takes Base + 1 */
Two, /* Takes One + 1 */
Negative = -1,
AnotherZero /* Takes Negative + 1 == 0, sigh */
};
int main(void)
{
printf("Base = %d\n", Base);
printf("One = %d\n", One);
printf("Two = %d\n", Two);
printf("Negative = %d\n", Negative);
printf("AnotherZero = %d\n", AnotherZero);
return EXIT_SUCCESS;
}
Образец печатает:
Base = 0
One = 1
Two = 2
Negative = -1
AnotherZero = 0
константа перечисления без typename
Типы перечислений также могут быть объявлены без указания им имени:
enum { buffersize = 256, };
static unsigned char buffer [buffersize] = { 0 };
Это позволяет нам определять константы времени компиляции типа int
которые могут, как в этом примере, использоваться как длина массива.