Перечисляемый тип

Теги: Си перечисление, enum.



Перечисляемый тип

В си выделен отдельный тип перечисление (enum), задающий набор всех возможных целочисленных значений переменной этого типа. Синтаксис перечисления

enum <имя> {
	<имя поля 1>,
	<имя поля 2>,
	...
	<имя поля N>
};	//здесть стоит ;!

Например

#include <conio.h>
#include <stdio.h>

enum Gender {
	MALE,
	FEMALE
};

void main() {
	enum Gender a, b;
	a = MALE;
	b = FEMALE;
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	getch();
}

В этой программе объявлено перечисление с именем Gender. Переменная типа enum Gender может принимать теперь только два значения – это MALE И FEMALE.

По умолчанию, первое поле структуры принимает численное значение 0, следующее 1, следующее 2 и т.д. Можно задать нулевое значение явно:

#include <conio.h>
#include <stdio.h>

enum Token {
	SYMBOL,			//0
	NUMBER,			//1
	EXPRESSION = 0,	//0
	OPERATOR,		//1
	UNDEFINED		//2
};

void main() {
	enum Token a, b, c, d, e;
	a = SYMBOL;
	b = NUMBER;
	c = EXPRESSION;
	d = OPERATOR;
	e = UNDEFINED;
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	printf("c = %d\n", c);
	printf("d = %d\n", d);
	printf("e = %d\n", e);
	getch();
}

Будут выведены значения 0 1 0 1 2. То есть, значение SYMBOL равно значению EXPRESSION, а NUMBER равно OPERATOR. Если мы изменим программу и напишем

enum Token {
	SYMBOL,				//0
	NUMBER,				//1
	EXPRESSION = 10,	//10
	OPERATOR,			//11
	UNDEFINED			//12
};

То SYMBOL будет равно значению 0, NUMBER равно 1, EXPRESSION равно 10, OPERATOR равно 11, UNDEFINED равно 12.

Принято писать имена полей перечисления, как и константы, заглавными буквами. Так как поля перечисления целого типа, то они могут быть использованы в операторе switch.

Заметьте, что мы не можем присвоить переменной типа Token просто численное значение. Переменная является сущностью типа Token и принимает только значения полей перечисления. Тем не менее, переменной числу можно присвоить значение поля перечисления.

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

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

static char *ErrorNames[] = {
	"Index Out Of Bounds",
	"Stack Overflow",
	"Stack Underflow",
	"Out of Memory"
};

enum Errors {
	INDEX_OUT_OF_BOUNDS = 1,
	STACK_OVERFLOW,
	STACK_UNDERFLOW,
	OUT_OF_MEMORY
};

void main() {
	//ошибка случилась
	printf(ErrorNames[INDEX_OUT_OF_BOUNDS-1]);
	exit(INDEX_OUT_OF_BOUNDS);
}

Так как поля принимают численные значения, то они могут использоваться в качестве индекса массива строк. Команда exit(N) должна получать код ошибки, отличный от нуля, потому что 0 - это плановое завершение без ошибки. Именно поэтому первое поле перечисления равно единице.

Перечисления используются для большей типобезопасности и ограничения возможных значений переменной. Для того, чтобы не писать enum каждый раз, можно объявить новый тип. Делается это также, как и в случае структур.

typedef enum enumName {
	FIELD1,
	FIELD2
} Name;

Например

typedef enum Bool {
	FALSE,
	TRUE
} Bool;
Q&A

Всё ещё не понятно? – пиши вопросы на ящик email

Хотите помочь? - отключите AdBlock и посмотрите рекламу
Структуры