Programowanie w języku C/C++

Enum

  • 2015-12-28 03:22
  • 3 komentarze
  • 33380 odsłon
  • 5,5/6
<justify>Jednym z wielu sposobów deklarowania stałych liczbowych w języku C/C++ jest typ wyliczeniowy, zwany także stałą wyliczeniową (ang. enumeration constant). Jest to zwyczajna lista wartości stałych całkowitych const int. Deklaracja typu wyliczeniowego składa się ze słowa kluczowego enum, następnie nazwy (opcjonalnie), po której występuje lista oddzielonych przecinkami elementów, ujęta w nawiasach klamrowych. Deklarację kończy średnik:</justify>
    enum dzien {PON, WT, SR, CZW, PT, SOB, NIE};

<justify>Pierwszy element na liście ma domyślnie wartość 0, następny - wartość 1 i tak dalej, chyba, że wystąpi jawnie podana wartość danego elementu. W powyższym przykładzie element PON ma wartość 0, WT ma wartość 1, z kolei NIE ma wartość 6.</justify>
<justify>Brak jawnego przypisania wartości powoduje, że kolejne niesprecyzowane wartości będą stanowiły rosnący ciąg arytmetyczny, zaczynając od ostatnio określonej wartości:</justify>
    enum dzien {PON = 1, WT, SR, CZW, PT, SOB, NIE};
    /* element PON ma wartość 1, WT ma wartość 2, z kolei NIE ma wartość 7 */
 
    enum marka {VOLKSWAGEN, AUDI, SEAT, SKODA = 9, BENTLEY, BUGATTI = 32, LAMBORGHINI};
    /* powyższa deklaracja przypisuje elementom następujące wartości:
     * VOLKSWAGEN = 0, AUDI = 1, SEAT = 2,
     * SKODA = 9, BENTLEY = 10,
     * BUGATTI = 32, LAMBORGHINI = 33 */

<justify>Jak widać nie jest to trudne, a bardzo przydatne. Wyobraźmy sobie podobną deklarację, tylko przy użyciu #define. Musielibyśmy wówczas deklarować wartość dla każdego elementu z osobna...</justify>
Nazwa każdego elementu występującego w typie wyliczeniowym musi być unikalna. W tym samym wyliczeniu mogą natomiast powtarzać się wartości:
    enum boolean {NO = 0, FALSE = 0, YES = 1, TRUE = 1};
        /* co krócej można zapisać jako: */
    enum boolean {NO,FALSE = 0, YES,TRUE = 1};

<justify>Kolejnym argumentem przemawiającym na korzyść trybu wyliczeniowego jest to, że istnieje możliwość deklarowania zmiennych typu enum. Co więcej, kompilator może (ale nie musi) sprawdzać, czy wartość przypisana takiej zmiennej jest prawidłową wartością wyliczenia.</justify>

Używanie zmiennych typu enum


<justify>Korzystanie ze zmiennych typu enum nie odbiega zbytnio do korzystania z innych typów. Rozważmy przykład:</justify>
ANSI C
#include <stdio.h>
#include <stdlib.h>
 
enum srodekTransportu {SAMOCHOD, TRAMWAJ, AUTOBUS, ROWER, NOGI};
 
void tankuj (enum srodekTransportu pojazd)
{
    if ( pojazd == SAMOCHOD )
        printf("Samochod zatankowany do pelna!\n");
    else
        printf("Przeciez nie jade samochodem, wiec co mam zatankowac?\n");
    return;
}
 
int main (int argc, char* argv[])
{
    enum srodekTransportu sposob;
    sposob = rand()%5;    /* losowanie sposobu dotarcia do pracy */
 
    switch (sposob)
    {
        case SAMOCHOD:
                  printf("Pojade dzis sobie samochodem!\n");
                  break;
        case AUTOBUS: case TRAMWAJ:
                  printf("Skorzystam dzis z transportu publicznego!\n");
                  break;
        case ROWER:
                  printf("Pojade dzis sobie rowerem!\n");
                  break;
        default:
                  printf("Pojde na piechote!\n");
                  break;
    }
 
    tankuj(sposob);
 
    return 0;
}

C++
#include <cstdio>
#include <cstdlib>
 
using namespace std;
 
enum srodekTransportu {SAMOCHOD, TRAMWAJ, AUTOBUS, ROWER, NOGI};
 
void tankuj (srodekTransportu pojazd)
{
    if ( pojazd == SAMOCHOD )
        cout<<"Samochod zatankowany do pelna!"<<endl;
    else
        cout<<"Przeciez nie jade samochodem, wiec co mam zatankowac?"<<endl;
    return;
}
 
int main (int argc, char* argv[])
{
    srodekTransportu sposob;
    sposob = SAMOCHOD;    /* wybranie sposobu dotarcia do pracy */
 
    switch (sposob)
    {
        case SAMOCHOD:
                  cout<<"Pojade dzis sobie samochodem!"<<endl;
                  break;
        case AUTOBUS: case TRAMWAJ:
                  cout<<"Skorzystam dzis z transportu publicznego!"<<endl;
                  break;
        case ROWER:
                  cout<<"Pojade dzis sobie rowerem!"<<endl;
                  break;
        default:
                  cout<<"Pojde na piechote!"<<endl;
                  break;
    }
 
    tankuj(sposob);
 
    return 0;
}

<justify>Powyższe przykłady, mimo, że z pewnością nie najwyższych lotów, w miarę dobrze obrazują dość znaczące różnice wynikające z korzystania ze zmiennych typu enum w czystym C i C++:</justify>
<center>ANSI C</center><center>C++</center>
• można przypisywać dowolną wartość liczbową• wolno przypisywać jedynie wartości należące do wyliczenia, przy czym można używać jedynie nazw stałych (a nie postaci liczbowych tych stałych)!
• przy deklaracji zmiennej trzeba podać słowo kluczowe enum, następnie nazwę typu wyliczeniowego i na końcu nazwę zmiennej* • przy deklaracji zmiennej podaje się tylko nazwę typu wyliczeniowego, która sama w sobie jest nowym typem

<justify>*Można jednak zastosować definicję typu typedef, by uzyskać ten sam efekt jak w przypadku C++, co dobrze zobrazuje następny przykład.</justify>

Definicja typu bool dla języka ANSI C, przy pomocy typu wyliczeniowego


Ponieważ w czystym języku C nie istnieje typ danych bool, zazwyczaj trzeba do tego celu użyć zmiennej całkowitej (1 - true, 0 - false). Można jednak, za pomocą typedef, stworzyć własną, skróconą definicję typu enum:

#include <stdio.h>
#include <ctype.h>
 
  typedef enum {TRUE = 1, FALSE = 0} bool;
 
int main()
{
  char c;
  bool dig;
 
  printf("Podaj jakis znak z klawiatury, a powiem, czy zostala podana cyfra\n");
  scanf("%c", &c);
  dig = isdigit(c) == 0 ? FALSE : TRUE;
  if ( dig == TRUE )
    printf("Podana zostala cyfra\n");
  else
    printf("Podany zostal znak niebedacy cyfra\n");
}

Standard wymaga, by nazwy stałych w języku C pisane były wielkimi literami, stąd FALSE oraz TRUE. Mimo to, nie będzie dużym błędem, jeśli ktoś użyje małych liter, tak jak to ma miejsce w C++.

Zobacz też:

3 komentarze

Future Knight 2015-12-27 22:51

Charllie: Nie, należy zmienić na <stdio.h> na <cstdio>.
ninja_koder: Polecam przestać używać Dev-cpp i zacząć używać czegoś z prawdziwego zdarzenia, np. Code::Blocks. DevCpp ma więcej bugów niż funkcjonalności. A poza tym DevCpp to nie kompilator, tylko środowisko programistyczne (IDE). Kompilator działający pod DevCpp to MinGW.

Charllie 2015-08-26 16:35

Aby kod działał pod C++ należy zmienić bilbioteki na #include <iostream>

ninja_koder 2015-04-28 17:55

Kod dla C++ nie działa [przynajmniej w kompilatorze Dev-C++]. Czy to przypadkiem nie dlatego, że napisany jest  jak dla C?  Te pliki nagłówkowe...