Typ wyliczeniowy w języku C ("legitymujący się" jako "enum" 😁) to kolejny ciekawy budulec mogący uprzyjemnić pisanie kodu i sprawić, że podniesie się jego czytelność 📖. Znajduje swoją użyteczność na wielu płaszczyznach i każdy porządny programista powinien tę strukturę znać 💪. Z tego materiału dowiesz się czym jest "enumeracja", jak utworzyć zmienną typu wyliczeniowego oraz jak ją można wykorzystać w praktyce i do jakich celów 🎯!

"ENUM" W JĘZYKU C. TAJNA BROŃ DO DEFINIOWANIA ABSTRAKCYJNEGO ZESTAWU OPCJI!

Zaczniemy od definicji, a potem przejdziemy do prezentacji kodów źródłowych 🎯!

CZYM JEST TYP WYLICZENIOWY W JĘZYKU C?

Typ wyliczeniowy w języku C (tzw. "enum"), to jest zbiór stałych w postaci liczb całkowitych, opatrzonych własną nazwą. Nadaje się świetnie do sytuacji, w której jest potrzeba zdefiniować wiele ścieżek jakimi może pójść program i jaki wpływ ma mieć każda z nich na dalszy przebieg ℹ️.

Możesz na to patrzeć, jak na menu główne w grze 🎮. Masz przed nosem kilka opcji i musisz wybrać jedną z nich. Zależnie od wyboru, stanie się coś innego 😊. "enum" w języku C działa dokładnie w taki sposób ✅. Jest wiele opcji, natomiast może być przypisana tylko jedna możliwość.

Możesz także definiować zmienne typu wyliczeniowego, a następnie przypisać jeden z typów zgodnych z tym typem wyliczeniowym w dowolnym miejscu w kodzie 👍. Oprócz tego, podnosi rewelacyjnie czytelność kodu w połączeniu z instrukcją wielokrotnego wyboru "switch" (więcej szczegółów w odrębnym artykule) 🏆.

"enum" jest skrótem od "enumeration", czyli "enumeracja". A enumeracja to inaczej "wyliczenie". A wyliczenie, to nic innego jak lista pewnych pozycji wymienianych po przecinku ❤️!

Przeróbmy sobie prosty przykład, do którego wstawienie wyliczenia będzie pasować jak ulał 😄.

JAK KORZYSTAĆ Z TYPU WYLICZENIOWEGO W JĘZYKU C?

Dajmy na to, że tworzymy system do nadawania oceny testom i chcemy dodać do niego różne rodzaje (np. niezaliczony, zaliczony, zaliczony z wyróżnieniem, najwyższa ocena), tak jak jest to powszechnie stosowane. Mając na uwadze opis powyżej, tak będzie wyglądać "surowa" postać "enum" w języku C 👇:

enum TestRating
{
	Failed, Passed, Merit, Distinction
};

Słowo kluczowe "enum", nazwa typu wyliczeniowego, klamerki i zestaw stałych zakończony średnikiem. To jest podstawowa struktura ✔️.

Jak widzisz, mamy przypisane pozycje, dokładnie jak w liście. Mamy "Failed", "Passed" i "PassedWithMerit". Jednak...w jaki sposób program może później identyfikować czym się różni jedna od drugiej 🤔?

CO SIĘ KRYJE ZA STAŁĄ TYPU WYLICZENIOWEGO?

Musisz wiedzieć, że stałe w typie wyliczeniowym są przyporządkowywane do liczb całkowitych! Domyślnie, w takiej formie w jakiej jest zdefiniowane jak u góry, poszczególne pozycje otrzymają własny numer porządkowy liczony od 0 (zera) 💡. To oznacza, że 👇:

  1. pod "Failed" będzie przypisana liczba 0,
  2. pod "Passed" będzie przypisana liczba 1,
  3. pod "Merit" będzie przypisana liczba 2,
  4. pod "Distinction" będzie przypisana liczba 3.

W taki właśnie sposób będzie można z łatwością rozpoznawać jaką wartość ma obecnie zmienna typu wyliczeniowego 👍!

W JAKI SPOSÓB PRZYPISAĆ WŁASNĄ LICZBĘ DO STAŁEJ TYPU WYLICZENIOWEGO?

Masz prawo do dostosowywania liczb jakie mają się znaleźć i pod którą stałą. Wystarczy drobny "dodatek" do definicji stałej 👇:

enum TestRating
{
	Failed = 1, Passed = 2, Merit = 3, Distinction = 4
};

Nie musisz dodawać jawnych przypisań do wszystkich możliwości, tylko trzeba być świadom konsekwencji jakie dotykają resztę stałych 🔥!

Na przykład takie przypisanie 👇:

enum TestRating
{
	Failed = 1, Passed, Merit, Distinction
};

spowoduje, że po "jedynce" kolejne pozycje otrzymają kolejne numery porządkowe tj. 2 i 3. To z kolei 👇:

enum TestRating
{
	Failed = 6, Passed, Merit, Distinction = 3
};

przypisze pozycji "Passed" kolejny numer (7), pozycji "Merit" przypisze liczbę 8, a "Distinction" będzie posiadać numer 3 💥! Taki zapis też jest dopuszczalny 👇:

enum TestRating
{
	Failed = 6, Passed = 6, Merit = 6, Distinction = 6
};

aczkolwiek nie robi niczego innego poza wzbudzaniem poczucia absurdu 😅, że nie wspomnę o niepotrzebnych problemach jakie mogą powstać z tego tytułu 😏.

Przypisywanie numeru porządkowego danemu elementowi działa TAK SAMO, jak przyporządkowywanie elementów w tablicy z jawnym przypisaniem danego indeksu ℹ️.

Teraz pokażę Ci coś, co gorąco zalecam stosować razem z "enum" w języku C 💥.

"ENUM" + "TYPEDEF" = "ENUM NA STERYDACH"

Chcąc utworzyć sobie zmienną bazując na typie wyliczeniowym w jego tradycyjnej formie, operowanie na takiej zmiennej nie jest takie komfortowe, jak to ma miejsce w językach o zwiększonym poziomie abstrakcji np. Java czy C# 👎. Tam, gdzie jest możliwość odwołania się do nazwy typu i konkretnej pozycji spośród dostępnych...tu mamy jedynie "suche" liczby całkowite typu "int" 👇:

enum TestRating testRating = 3;

Ponadto musisz za każdym razem dopisywać na początku słowo "enum", co też może wzbudzać irytację, jako że trzeba się przyzwyczaić do kolejnego odstępstwa od dzisiejszych norm ⚡.

DLACZEGO WARTO POŁĄCZYĆ "TYPEDEF" Z "ENUM" W JĘZYKU C?

Jeżeli chcesz "nagiąć" język pod dużo przyjemniejsze zapisy, dobrze skorzystać ze sztuczki z użyciem słowa kluczowego "typedef", które pozwala tworzyć aliasy dla własnych struktur danych (odrębny artykuł na ten temat, wkrótce) 👇:

typedef enum
{
	Failed = 1, Passed, Merit, Distinction
} TestRating;

Takie "opakowanie" przynosi 2 istotne zalety 👇:

  1. możesz opuścić słowo kluczowe "enum" przy deklaracji zmiennej typu "enum",
  2. możesz zamienić przypisania liczb całkowitych na stałe.

Dla porównania z poprzednim zapisem, tak będzie wyglądać "ulepszona" definicja:

TestRating testRating = Passed;

Dużo przyjemniej 👏! Mimo faktu, iż tutaj nie piszemy pełnego odwołania do stałej, tak jak ma to miejsce w innych językach ("TestRating.Passed"), to jednak taką różnicę daje się dużo lepiej przetrawić, niż tamte u góry 👍!

Pamiętaj jednak, że wciąż możesz wstawić wartość typu "int" (i nawet spoza zakresu podanych stałych!):

TestRating testRating = 2;

choć nie radzę używać liczb całkowitych, tylko kierować się wyłącznie stałymi ⚠️! Czytelność + bezpieczeństwo = kod napisany z głową 🧠.

PRZYKŁAD KODU ŹRÓDŁOWEGO DZIAŁANIA TYPU WYLICZENIOWEGO W JĘZYKU C

Teraz praktyka ✒️! Oto kod źródłowy prezentujący użycie typu wyliczeniowego razem z prostą obsługą zmiany przebiegu działania zależnie od wartości 🔀. Do tego zabiegu, korzystam z instrukcji "switch" osadzonej w osobnej funkcji 👇:

#include <stdio.h>

int main(void)
{
	typedef enum
	{
		Failed = 1, Passed, Merit, Distinction
	} TestRating;
	
	TestRating testRating = Merit;

	switch (testRating)
	{
		case Failed:
			printf("Test niezaliczony.\n");
			break;
		
		case Passed:
			printf("Test zaliczony.\n");
			break;
		
		case Merit:
			printf("Test zaliczony wspaniale!\n");
			break;
		
		case Distinction:
			printf("Test zaliczony rewelacyjnie!\n");
			break;
		
		default:
			printf("Nieznana ocena.\n");
			break;
	}

	return 0;
}

Na samej górze mamy nasz typ wyliczeniowy "na sterydach" (z użyciem "typedef") 😄. Niżej znajduje się prototyp funkcji, a w samej funkcji "main", definiujemy zmienną i wywołujemy funkcję z parametrem ✔️.

Wewnątrz funkcji, definiujemy instrukcję wielokrotnego wyboru ("switch") i określamy co ma się dziać w przypadku każdej możliwej opcji. Zauważ, że uwzględniłem także sytuację, w której zmienna nie przyjmuje żadnej z dostępnych możliwości ("default")! Ponieważ wciąż możemy podstawiać liczby całkowite ("int"), a wartości mogą "wychodzić" poza stałe, musimy założyć, że może się zdarzyć przyjęcie innej opcji spośród dostępnych.

"default" to słowo kluczowe dotyczące instrukcji "switch" i pozwala na uwzględnienie scenariusza: "a co, gdy zmienna posiada wartość inną, niż wszystkie zdefiniowane przypadki powyżej?". Więcej informacji na temat instrukcji "switch" znajdziesz w załączonym artykule.

Jak sam(a) widzisz, "enum" w języku C, zwiększa bezpieczeństwo i czytelności kodu. Oczywiście, że możemy to zadanie zrealizować za pomocą samych liczb całkowitych, jednak skorzystanie z typu wyliczeniowego jest dużo lepszym rozwiązaniem ➕. Po nazwie stałej, znacznie szybciej rozpoznać jaka jest zależność, niż po samej liczbie 😉.

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.


Tyle w tym temacie 😊. Typ wyliczeniowy jak najbardziej warto znać i stosować, ponieważ sprzyja czytelności i łatwej rozbudowie w przyszłości o dodatkowe opcje 🙂.

PODOBNE ARTYKUŁY