10.6. Tipul enumerare

2019/03/28 in Programare in C

Tipul enumerare permite programatorului sa foloseasca nume sugestive pentru valori numerice. De exemplu, in locul unei luni calendaristice este mai sugestiv sa folosim denumirea lunii respective sau eventual o prescurtare:

ian pentru ianuarie, in locul cifrei 1;
feb pentru februarie, in locul cifrei 2.

si asa mai departe.

Un alt exemplu se refera la posibilitatea de a utiliza cuvintele FALS si ADEVARAT pentru valorile 0, respectiv 1. In felul acesta se obtine o mai mare claritate in programele sursa, deoarece valorile numerice sunt inlocuite prin sensurile lor atribuite intr-un anumit context.

In acest scop se utilizeaza tipul enumerare. Un astfel de tip se declara printr-un format asemanator cu cel utilizat in cazul structurilor. Un prim format general este:

enum nume {nume1, nume2, ..., numek} d1, d2,..., dn;

unde:

nume este numele tipului enumerare introdus prin aceasta declaratie;
nume1, nume2, ..., numek sunt nume care se vor utiliza in continuare in locul valorilor numerice si anume numei are valoarea i;
d1, d2,..., dn sunt date care se declara de tipul nume;
Aceste date sunt similare cu datele de tip int.

Ca si in cazul structurilor, in declaratia de mai sus nu sunt obligatorii toate elementele. Astfel, poate lipsi nume, dar atunci va fi prezent cel putin d1. De asemenea, poate lipsi lista d1, d2,..., dn, ar atunci va fi prezent nume. In acest caz, se vor defini ulterior date de tip nume folosind un format de forma:

enum nume d1, d2,..., dn;

Exemple:

  1. enum {ileg, ian, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec} luna;

    Prin aceasta declaratie, numarul lunii poate fi inlocuit prin denumirea prescurtata a lunii respective. De exemplu, o atribuire de forma:

    luna = 3

    se poate inlocui cu una mai sugestiva:

    luna = mar

    deoarece, conform declaratiei de mai sus, mar are valoarea 3.

    In mod analog, o expresie de forma:

    luna == 7

    este identica cu expresia:

    luna == iul

    Daca in locul declaratiei de mai sus s-ar fi folosit declaratia de tip enumerare:

    enum dl {ileg, ian, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec};

    atunci putem declara ulterior data luna de tip dl astfel:

    enum dl luna;

    Data luna declarata in acest fel este o data identica cu data luna declarata la inceput.

  2. Fie tipul enumerare Boolean declarat astfel:

    enum Boolean {false, true};

    Declaram data bisect de tip Boolean:

    enum Boolean bisect;

    Atribuirea:

    bisect = an%4 == 0 && an%100 || an%400 == 0;

    atribuie variabilei bisect valoarea 1 sau 0, dupa cum anul definit de variabila an este bisect sau nu (se presupune ca anul apartine intervalului [1600, 4900]).

    In continuare se pot folosi expresii de forma:

    bisect == false

    sau

    bisect == true
  3. Fie f o functie care returneaza numai doua valori: 0 sau 1. O astfel defunctie se considera, de obicei, ca returneaza o valoare booleana. Atunci, antetul ei poate fi definit astfel:

    enum Boolean f(...)

    In continuare se pot folosi expresii de forma:

    f(...) == false

    sau

    f(...) == true

    La declararea tipurilor enumerare se poate folosi cuvantul cheie typedef, ca si in cazul structurilor definite de utilizator. In acest caz vom utiliza o declaratie de forma:

    typedef enum nume {nume0, nume1,..., numek} nume_tip;

    In continuare se pot declara mai simplu date de tipul enumerare nume folosind:

    nume_tip d1, d2,..., dn;

    In acest caz, nume este optional si de obicei lipseste. Folosind aceasta conventie, exemplele de mai sus pot fi scrise3 astfel:

    typedef enum {ileg, ian, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec} DL;
    DL luna;
    typedef enum {false, true} Boolean;
    Boolean bisect;

    sau antetul functiei f:

    Boolean f(...)

    Tipul enumerare poate fi declarat impunand valori altele decat cele care rezulta implicit. In acest caz, numei se va inlocui cu numei = eci, unde:

    eci este o expresie constanta.

    Numele numei va avea ca valoare, valoarea expresiei eci. Daca numelui urmator nu i se atribuie o valoare, atunci acesta va avea ca valoare, valoarea lui numei marit cu 1.

    Folosind aceasta observatie, modificam tipul DL astfel:

    typedef enum {ian=1, feb, mar, apr, mai, iun, iul, aug, sep, oct, nov, dec} DL;

    Mentionam ca datele de acest tip nu sunt supuse la controale din partea compilatorului C si de aceea se pot scrie expresii care sa nu corespunda scopului pentru care s-au definit datele respective.

    De exemplu, fie:

    DL d1, d2, d3;

    Expresiile de mai jos nu sunt tratate ca eronate de compilator:

    d3 = d1 + d2;
    d3 = d1 * d2;
    d3 = d1/d2;
    ...
    etc.

    Aceasta, deoarece datele de tip enum sunt tratate ca simple date de tip int.

10.7. Date definite recursiv