Jason. Cała informatyka w jednym miejscu!

Enumeracja to odrębna gałąź w programowaniu, która też wymaga porządnego wyjaśnienia. Typ wyliczeniowy (identyfikowany jako "enum" w języku C) również znajduje swoją użyteczność na wielu płaszczyznach i każdy porządny programista powinien tę strukturę znać. Co to jest "enumeracja"? Jak ją utworzyć? Jak ją można wykorzystać w praktyce i do jakich celów?

TYP WYLICZENIOWY. ZASTOSOWANIE PRAKTYCZNE TYPU "ENUM" W JĘZYKU C

Tytułowy "typ wyliczeniowy" kryjący się zwykle pod słowem kluczowym "enum" jest to lista stałych wartości składająca się z nazw. Nadaje się doskonale do sytuacji wybrania jednej z kilku dostępnych opcji, tak jak w menu głównym. Oczywiście, możemy to samo zrobić za pomocą "integera" jednak skorzystanie z takiej listy jest dużo lepszym rozwiązaniem. Po pierwsze jest bezpieczniejsze, a po drugie o wiele bardziej czytelne (po nazwie znacznie szybciej rozpoznać jaka jest zależność niż po samej liczbie).

Tyle tytułem części teoretycznej. Teraz patrzymy na taki oto kod źródłowy wykorzystujący typ wyliczeniowy. Pozwoliłem sobie dodać małą interakcję z użytkownikiem, aby można było wybrać jedną z wielu dostępnych opcji celem lepszego zobrazowania użyteczności tej listy wartości. Powtórzę, że w języku C rozpoznajecie coś takiego po słowie "enum":

#include <stdio.h>

enum Difficulties
{
	EASY = 1, NORMAL, HARD, EXTREME
};

enum Difficulties selectedDifficulty(void);
int firstCharacter(void);

int main(void)
{
	enum Difficulties difficulty;			// zmienna typu "enum" w języku C
	
	printf("Dostepne sa cztery poziomy trudnosci:\n");
	printf("Wybierz jeden z nich od 1 do 4: ");
	
	difficulty = selectedDifficulty();
	
	// instrukcja wielokrotnego wyboru wykorzystująca typ wyliczeniowy
	switch (difficulty)
	{
		case EASY:
			printf("Wybrales poziom %d: LATWY\n", difficulty);
			break;
			
		case NORMAL:
			printf("Wybrales poziom %d: NORMALNY\n", difficulty);
			break;
			
		case HARD:
			printf("Wybrales poziom %d: TRUDNY\n", difficulty);
			break;
			
		case EXTREME:
			printf("Wybrales poziom %d: EKSTREMALNY!\n", difficulty);
			break;
	}
	
	getchar();
	
	return 0;
}

// funkcja zwracająca typ wyliczeniowy
enum Difficulties selectedDifficulty(void)
{
	int c = firstCharacter();
	
	while (c < 1 || c > 4)
	{
		printf("Podaj wartosc od 1 do 4.\n");
		
		c = firstCharacter();
	}
	
	return c;
}

int firstCharacter(void)
{
	int c = getchar();
	
	while (getchar() != '\n')
	{
		;
	}
	
	return c - '0';
}

Tuż pod dyrektywą dołączającą plik nagłówkowy mamy nasz typ wyliczeniowy czyli listę "enum" w języku C. Lista wartości otoczona klamerkami posiada w tym przykładzie listę dostępnych poziomów trudności. Pierwszy argument ("EASY") posiada dodatkowe przypisanie wartości liczbowej (domyślnie przyjmuje wartość zero). To daje szerokie możliwości, bo można podać dowolną wartość, jednak stoi za tym mała pułapka! Pierwsza wartość "przestawia" początkowy punkt, od którego zaczną inkrementować kolejne parametry. A co jakbyśmy dorzucili np. wartość 50 dla "NORMAL"? Wówczas kolejne wartości przyjmowałyby liczby kolejno 51 ("HARD") i 52 ("EXTREME")!!! Widzimy ewidentnie, że to działa TAK SAMO jak oznaczona inicjalizacja tablicy wg standardu C99.

Początek funkcji "main" posiada zmienną typu "enum" wraz z jej podaną nazwą. Język C WYMAGA umieszczenia słowa kluczowego "enum", choć możemy skorzystać z aliasu za pomocą "typedef", aby tego uniknąć. Ponadto można zauważyć, że możemy bez żadnych przeszkód zwrócić wartość liczbową "int", ale już w postaci "enumeracji". Typ wyliczeniowy składa się ze stałych liczb całkowitych, dlatego też to nie robi żadnych przeszkód.

Typ wyliczeniowy "enum" w języku C

Typ wyliczeniowy znany też jako "enumeracja" (albo w skrócie "enum" w języku C) to lista stałych wartości idealnie pasujących do sytuacji wyboru TYLKO JEDNEJ z dostępnych opcji.

A teraz zalety użytkowania. "enum", oprócz zwiększania bezpieczeństwa i czytelności kodu poprzez etykiety, doskonale pasuje do instrukcji "switch", ponieważ każda z wartości listy przyjmuje jedyną unikatową liczbę. Nawet podczas modyfikowania wartości liczbowych, "switch" zawsze "dopasuje się" do sytuacji. Dozwolone jest również przypisanie jednej ze stałych nazw do zmiennej typu "typ wyliczeniowy" (pod warunkiem, że taki sam). Zatem dla przykładu instrukcja:

difficulty = NORMAL;

jest jak najbardziej w porządku od strony składniowejReszta funkcjonalności to jest tylko walidacja danych, aby użytkownik mógł spróbować wielokrotnie wprowadzić prawidłową wartość.


Moi drodzy, to tyle w tym temacie. Typ wyliczeniowy też warto znać, ponieważ separacja jednej części kodu od drugiej zawsze sprzyja czytelności. Ponadto łatwiej rozbudowywać taką listę :).

PODOBNE ARTYKUŁY