Typy wyliczeniowe - jaki jest sens?

Odpowiedz Nowy wątek
2011-11-20 12:49
0

Witam,uczę się C i zastanawiam się jaki sens jest używanie typów wyliczeniowych.

1) Po pierwsze, zmienne tego typu są traktowane jak po prostu zwykłe zmienne całkowite i mogą mieć dowolną wartość, nawet z stałych wylieczeniowych.
2) Po drugie, nawet zwykłem zmiennej całkowitej typu int mogę przypisać wartość za pomocą etykiety typu wyliczeniowego, np: enum kolory {czerwony,zielony,niebieski}; int liczba=czerwony;

Na wielu stronach jest napisane, że zmienne wylieczeniowe mogą przyjmować tylko wartości stałych wyliczeniowych, wtedy myślę byłby jakiś sens, albo gdyby te kolory mógłbym stosować do zmiennych tego typu, a nie do każdej zmiennej całkowitej.

Pozostało 580 znaków

2011-11-20 12:59
Rev
0

Enumy są bardziej czytelne niż deklarowanie miliona intów, prostsze w debugowaniu niż #define'y (co mi po jakiejś liczbie, za którą muszę przejrzeć dokumentację i kilka plików, żeby się dowiedzieć co ona oznacza).


Pozostało 580 znaków

2011-11-20 13:24
0

Ok, co do tego drugiego masz racje (z tym #define), ale co masz na myśli z tym milionem intów, przecież czy będziemy deklarować setki zmiennych typu enum czy typu int to i tak musimy je recznie te 100 razy zadeklarowac?

Pozostało 580 znaków

2011-11-20 14:27
0

Podam ci Bracie matieti historyjkę z życia wziętą.

Otóż,dawniejszymi czasy razem z kumplem robiliśmy obsługę grafów czy czegoś w ten deseń.Do tworzenia węzłów używaliśmy funkcji z około 7 parametrami typu bool.Wyglądało to mniej więcej tak:

utwórz(true,false,false,false,true,false,false);
utwórz(false,true,false,true,true,false,false);
utwórz(true,false,true,true,false,false,true);
utwórz(false,true,false,true,false,true,false);

szybko zaliczylismy WTF podczas patrzenia na taki kod,i boole zastąpiliśmy różnakimi enumami,które miały jakieś dorzeczne nazwy.Wywołanie przy pomocy enumów wyglądało bodajże tak:

utwórz(IsNotRoot,IsChild,LeftChildExist,RightChildNotExist,2 ostatnie już nie kojarzę);

I teraz sam oceń,który kod jest czytelniejszy? :]


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2011-11-20 14:28

Pozostało 580 znaków

2011-11-20 14:29
0

Ale wartości są nadawane z automatu, a wszystkie stałe w jakiś sposób powiązane ze sobą możemy wrzucić w jednego enuma i mamy z tego nowy typ.
Więc możemy zrobić:

void setKolor(Kolor kolor) {
}

zamiast nic niemówiącego inta (skąd mamy brać wartości? jakie są dozwolone?). Enumy są po prostu czytelniejsze.
W dodatku, chociaż konwersja enum -> int jest ok, to na odwrót, chociaż też możliwa, jest unsafe i nie może być niejawna:

setKolor(czerwony); // ok
setKolor(0); // błąd
setKolor(Kolor(0)); // wiem co robię, ale po co tak?

Ok, pytanie było o C, a tam enumy są bardziej krzywe. W takim razie druga połowa postu tyczy się tylko C++

edytowany 4x, ostatnio: iooi, 2011-11-20 14:41

Pozostało 580 znaków

2011-11-20 15:52
0

wyobraź sobie, że piszesz biblioteke do obsługi sieci bez enum:

#define XXX 0x00
#define XXY 0x01
...
#define ZZZ 0xFF

i jak się piierdolniesz w numeracji i założysz, że na pewno nie zrobiłeś tam błędu to potem będziesz długimi godzinami szukać błędu


░█░█░█░█░█░█░█░█░█░█░█░
edytowany 1x, ostatnio: krwq, 2011-11-20 15:52

Pozostało 580 znaków

2011-11-20 18:18
0
MasterBLB napisał(a)
utwórz(IsNotRoot,IsChild,LeftChildExist,RightChildNotExist,2 ostatnie już nie kojarzę);

I teraz sam oceń,który kod jest czytelniejszy? :]

Taki: :)

enum
{
    IsNotRoot  = 1,
    IsChild = 2,
    RightChildNotExist = 4
    // etc..
};

utwórz(IsNotRoot + IsChild);
utwórz(RightChildNotExist);

// czyli 
void utworz(uint maska);

Tak robię jak mam kilka flag bool, ale gdy jest masa nie-bool parametrów, to już wolę obiekt-parametr:

void utworz(const ZestawParametrow &parms);

class ZestawParametrow {
public:
  ZestawParametrow() {
    // ustaw wartosci domyslne
  }

  void setIsNotRoot(bool value);
  void setIsChild(bool value);
  // etc.
};

// A potem użycie:
ZestawParametrow zestaw;
zestaw.setIsNotRoot(true);
zestaw.setIsChild(true);
utworz(zestaw);

Długa lista parametrów jest w każdym wypadku do (negatywny zwrot)...


Szacuje się, że w Polsce brakuje 50 tys. programistów
edytowany 2x, ostatnio: vpiotr, 2011-11-20 18:23

Pozostało 580 znaków

2011-11-20 18:34
0
vpiotr napisał(a)

Tak robię jak mam kilka flag bool, ale gdy jest masa nie-bool parametrów, to już wolę obiekt-parametr:


void utworz(const ZestawParametrow &parms);

class ZestawParametrow {
public:
ZestawParametrow() {
// ustaw wartosci domyslne
}

void setIsNotRoot(bool value);
void setIsChild(bool value);
// etc.
};

// A potem użycie:
ZestawParametrow zestaw;
zestaw.setIsNotRoot(true);
zestaw.setIsChild(true);
utworz(zestaw);


> 
> Długa lista parametrów jest w każdym wypadku do (negatywny zwrot)...

Ostatnio gdzieś wyczytałem by właśnie pakować w struktury skomplikowane parametry funkcji. Też to zacząłem używać i muszę przyznać że upraszcza to kod, a jeśli jest potrzeba dodania parametru to rozbudowuje się strukturę. Tutaj jednak bym optował przy strukturach a nie klasach. Deklarujesz strukturę pomocniczą ze składowymi typu const i dodajesz konstruktor przyjmujący te parametry i jest ok jak na mój gust. Choć w sumie jeśli chodzi o parametry typu bool to klasa chyba użyteczniejsza niż struktura, ale struktura, która ma trzymać konkretne wartości jest lepsza niż kasa(uff zamotałem ale mam nadzieję że da się to zrozumieć).

Jeśli uważasz mój post za wartościowy - daj punkt.
Mój post pomógł Ci rozwiązać problem - zaznacz go.

Pozdrawiam
Zgadza się, właściwie powinno być struct... Ale jakoś nieprzyzwyczajonym do struktur z metodami... - vpiotr 2011-11-20 19:51
Biorąc pod uwagę, że w C++ class=struct+private, to znaczenie to ma tylko takie, że jeden kod może być o parę znaków krótszy. - Azarien 2011-11-20 20:48

Pozostało 580 znaków

2011-11-20 18:42
msm
0
IsNotRoot + IsChild

Czemu '+'? Bitowe OR by tutaj raczej bardziej pasowało.

I jeszcze taka uwaga - nazwy typu IsNotRoot mają tendencję do powodowania wtf-ów, lepiej by było po prostu IsRoot.

IsRoot == true, IsNotRoot == false - Wibowit 2011-11-20 18:45
A później czytanie późno w nocy warunków typu if (!a.isNotRoot) - msm 2011-11-20 18:52
Ale wartości są dwie, więc albo mamy if (a == IsRoot) albo if (a == IsNotRoot). - Wibowit 2011-11-20 18:54
Plus bo dzięki temu widać lepiej że wartości się wykluczają bitowo (gdyby tak nie było wynik byłby opłakany). Ale można i "|". - vpiotr 2011-11-20 19:53

Pozostało 580 znaków

2011-11-20 19:04
0

@Hostel & vpiotr
Mówicie,żeby pakować do struktur większość ilość parametrów funkcji-cóż,zapraszam zatem do zapoznania się z WinAPI i takim fundamentalnym zagadnieniem,jakim jest tworzenie nowego okna w tejże technologii :]

Co do samej zasady,ja tam jestem zwolennikiem KISSa i brzytwy Ockhama-jak najmniej wszystkiego,jak najprostsze,póki absolutnie nie muszę nie wprowadzam nowych klas.

Co do samego przykładu,to było to już tak dawno że za Swaroga sobie nie przypomnę,czemu akurat funkcja z 7 boolami była potrzebna.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
Ten "pattern" właśnie wziąłem z WinAPI. To zgrabne obejście problemu leżącego w samym języku - parametry mogą przyjąć wartości domyślne tylko jeśli są na końcu. W klasycznym czysto-C++ rozwiązaniu nie możesz pominąć pierwszego parametru a następne podać. A w rozwiązaniu z struct/class możesz. Dodatkowo struktura może być wersjonowana (patrz standardowe pole "rozmiar"). - vpiotr 2011-11-20 19:56
To co robi MS zazwyczaj włącza u mnie czerwoną lampkę niż zieloną ;) - Hostel 2011-11-21 10:19
I słusznie ci się włącza,WinAPI jest po prostu straszliwe.Z 2 mańki,Małymiękki nie miał zbyt dużego pola manewru skoro WinAPI stworzone zostało w C-czyli żadnych klas ni konstruktorów dla struktury. - MasterBLB 2011-11-21 11:34

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0