Személyes eszközök
Keresés

 

A InfoWiki wikiből

(Változatok közti eltérés)
(Felsorolás típus)
(A probléma)
102. sor: 102. sor:
és a programunk szövegének utólagos (vagy mások által történő) olvasgatása során a típusinformáció
és a programunk szövegének utólagos (vagy mások által történő) olvasgatása során a típusinformáció
nem ad támpontot a változók szerepének megértésében.
nem ad támpontot a változók szerepének megértésében.
 +
 +
== Felsorolt típus ==
 +
 +
Amire szükségünk lenne, hogy a fordítóprogramnak el tudjuk magyarázni, hogy mire is gondolunk mi.
 +
Erre van mód az '''enum''' kulcsszó segítségével:
 +
 +
<code lang="csharp">
 +
enum hangfekvesek { bariton, alt, tenor, szopran, mezoszopran };
 +
</code>
 +
 +
A fenti sorral megadhatjuk, hogy ''hangfekvesek'' alatt mi ezt az öt lehetséges értéket értjük a
 +
továbbiakban. A fenti kis kódrészben az ''enum'' szó foglalt szó, a többi azonban azonosítónak
 +
minősül, tehát mind a ''hangfekvesek'' szó, mind a ''bariton'', ''alt'' stb szavak mindegyike
 +
az azonosító névképzési szabályainak megfelelően képzendő (nincs benne szóköz, számjeggyel nem
 +
kezdődhet, ékezetes betűk használata elvileg nem tilos, stb).
 +
 +
A fenti kis kódban a '''hangfekvesek''' azonosító a továbbiakban egy új '''típust''' azonosít, a
 +
kapcsos zárójelbeli felsorolás ezen típusba tartozó értékeket ad meg. Ez a konstrukció nagyon
 +
hasonlít a matematikai halmaz esetéhez, ahol is a halmazbeli elemeket (véletlenül) szintén
 +
a kapcsos zárójelbe szoktuk felsorolni.
 +
 +
Mivel a ''hangfekvesek'' itt egy új típus lesz, ezért szabad ilyen típusú változót deklarálni:
 +
 +
<code lang="csharp">
 +
hangfekvesek enrico_caruso_hangja;
 +
</code>
 +
 +
Ezen típusú változó (mint látni fogjuk) csakis a fenti felsorolásban megadott értékek valamelyikét
 +
képes (majd) fölvenni.
 +
 +
== Tárolási jellemzők ==
 +
 +
Hány byte-ba kerül nekünk egy felsorolás alaptípusú változó? A szokásos 4 byte-os tipp megint bejön. Oka:
 +
a fenti változó valójában a háttérben '''int''' típusú lesz, és egy int mindíg 4 byte.
 +
 +
A háttérbeli kódolást ilyenkor a fordítóprogram végzi el helyettünk, ennek tényét maximálisan elrejtve
 +
előlünk. Némi kutakodás és gondolkodás után kideríthető, hogy a fenti kis ''enum'' felírás valójában
 +
majdnem teljesen egyenértékű a mi kódolási és konstansos kísérletünk eredményével.
 +
 +
Ennek megfelelően ami történik, az nem más, mint 5 darab konstans ''generálása'' a fordítóprogrammal,
 +
a fenti esetben a felsorolásbeli ''bariton'' kódja ténylegesen a nulla lesz, a ''alt'' kódja valójában
 +
egy, stb.
 +
 +
== Kódolás befolyásolása ==
 +
 +
Néha szükség van arra, hogy ne az automatikus kódkiosztást használjuk, hanem fizikailag adhassuk meg
 +
az egyes értékek kódjait. Ezt a felsorolás belsejébe elhelyezett értékmegadásokkal tudjuk befolyásolni:
 +
 +
<code lang="csharp">
 +
enum hangfekvesek
 +
{ bariton=10,
 +
  alt,
 +
  tenor=20,
 +
  mezoszopran,
 +
  szopran=40
 +
};
 +
</code>
 +
 +
A fenti felírás eredményeként az alábbi kódolást írtuk elő:
 +
<code lang="text">
 +
  bariton    = 10
 +
  alt        = 11
 +
  tenor      = 20
 +
  mezoszopran = 21
 +
  szopran    = 40
 +
</code>
 +
 +
Vagyis ahol mi állítottuk be fixen a kódolási értéket, ott az kerül felhasználásra, egyébként pedig
 +
az automatikus kódkiosztás során a következő szabad kódot adja a rendszer az egyes lehetséges értékeknek.
== Felsorolt típus ==
== Felsorolt típus ==

A lap 2009. december 17., 08:09-kori változata


A probléma

Az alapvető típusok (int, double, char, bool, stb) a programok és a további típusok alapvető építőkövei. Mivel nyelvi alaptípusok - a program szövegébe épített értékeiket (literálok alakja) a fordítóprogram felismeri.

Gyakori azonban az az eset, amikor ezen típusok által lefedett értékek halmaza túlságosan bő. Tegyük fel például, hogy egy énekkari kórustagok hangjának jellegét kívánjuk (sok más adatuk mellett) programban tárolni. A hangzástípusok csakis a bariton, alt, tenor, mezoszoprán, szoprán értékek közül kerülhet ki. Nincs olyan típus a C#-ban (és más nyelven sem valószínű), amely csakis ilyen értékeket fogad el.

Ilyenkor a szokásos eljárás, hogy az egyes lehetséges értékeket kódoljuk. Pl. bariton lesz a 0, alt az 1, stb. A típus amire szükségünk lesz, valamely egész szám típus, hiszen ebben tudjuk majd tárolni a tényleges értékek kódjait.

Egyrészt vegyük észre, hogy máris kompromisszumot kötöttünk - nem a tényleges értékeket tároljuk, hanem azok kódjait. Ezen még tudunk segíteni valamelyest a konstansok használatával (bár ki fog derülni, hogy nem sokat):

const int bariton = 0;
const int alt = 1;
const int tenor = 2;
const int mezoszopran = 3;
const int szopran = 4;

Ez máris mutatja, hogy amennyiben egy konkrét énekes konkrét énekhangját akarnánk tárolni, akkor az int típust (vagy valamelyik egész szám típust) tudnánk használni:

int enrico_caruso_hangja = tenor;

Vegyük azonban észre, hogy a fenti kód az alábbi módon is írható:

int enrico_caruso_hangja = 2;

Valamint vegyük észre, hogy az alábbi kód sem jelez szintaktikai hibát:

int enrico_caruso_hangja = -42312;

A szóban forgó változó fizikailag képes ezen lehetetlen érték tárolására, a fordítóprogramnak meg nem adtunk semmilyen támpontot hogy ellenőrízhesse, és kizárhassa ezt a logikailag hibás értéket. Szűkíthetnénk a lehetséges értékek halmazát az által pl, hogy nem az int, hanem egy kisebb típust használunk:


byte enrico_caruso_hangja = -42312; // hibás

A byte típus nem enged meg negatív értékeket, ez okozza a fenti kód szintaktikai hibáját, és nem az, hogy nincs ilyen hangfekvés-kód. A fordítónak semmilyen ötlete nincs arról, hogy mik a lehetséges hangfekvés kódok, e miatt a byte esetén is működne az alábbi kód:

byte enrico_caruso_hangja = 178;

Tovább bonyolítja a helyzetet, hogy programunkban más jellegű konstansokat is felvehetnénk:

// termék minőségek
const int megfelelt = 0;
const int turheto = 1;
const int jo = 2;
const int kivalo = 3;

Mivel ezek mind-mind egy egész számot neveznek el, a hangzások kódolása is egész számok segítségével történik, ezért az alábbi kódok nem hibásak a fordító szerint:

byte enrico_caruso_hangja = megfelelt; // gyak. a bariton kódja
if (enrico_caruso_hangja==turheto) {...} // hangja alt ??
while (enrico_caruso_hangja>0) {...} // ebből mi akar lenni??

Tehát ezen kódolásos megoldás fizikailag megoldja a gondjainkat, a programokban ezen a módon végül is tudjuk tárolni az énekesek hanját (ha nem rontjuk el), de a programunkban ezt a dolgot csakis a mi jó szándékunk tartja életben. A fordítóprogram nem segít nekünk ellenőrízni a kódunk helyességét, nem szól, ha hangfekvés jellegű változóinkba illegális értéket akarunk helyezni, és a programunk szövegének utólagos (vagy mások által történő) olvasgatása során a típusinformáció nem ad támpontot a változók szerepének megértésében.

Felsorolt típus

Amire szükségünk lenne, hogy a fordítóprogramnak el tudjuk magyarázni, hogy mire is gondolunk mi. Erre van mód az enum kulcsszó segítségével:

enum hangfekvesek { bariton, alt, tenor, szopran, mezoszopran };

A fenti sorral megadhatjuk, hogy hangfekvesek alatt mi ezt az öt lehetséges értéket értjük a továbbiakban. A fenti kis kódrészben az enum szó foglalt szó, a többi azonban azonosítónak minősül, tehát mind a hangfekvesek szó, mind a bariton, alt stb szavak mindegyike az azonosító névképzési szabályainak megfelelően képzendő (nincs benne szóköz, számjeggyel nem kezdődhet, ékezetes betűk használata elvileg nem tilos, stb).

A fenti kis kódban a hangfekvesek azonosító a továbbiakban egy új típust azonosít, a kapcsos zárójelbeli felsorolás ezen típusba tartozó értékeket ad meg. Ez a konstrukció nagyon hasonlít a matematikai halmaz esetéhez, ahol is a halmazbeli elemeket (véletlenül) szintén a kapcsos zárójelbe szoktuk felsorolni.

Mivel a hangfekvesek itt egy új típus lesz, ezért szabad ilyen típusú változót deklarálni:

hangfekvesek enrico_caruso_hangja;

Ezen típusú változó (mint látni fogjuk) csakis a fenti felsorolásban megadott értékek valamelyikét képes (majd) fölvenni.

Tárolási jellemzők

Hány byte-ba kerül nekünk egy felsorolás alaptípusú változó? A szokásos 4 byte-os tipp megint bejön. Oka: a fenti változó valójában a háttérben int típusú lesz, és egy int mindíg 4 byte.

A háttérbeli kódolást ilyenkor a fordítóprogram végzi el helyettünk, ennek tényét maximálisan elrejtve előlünk. Némi kutakodás és gondolkodás után kideríthető, hogy a fenti kis enum felírás valójában majdnem teljesen egyenértékű a mi kódolási és konstansos kísérletünk eredményével.

Ennek megfelelően ami történik, az nem más, mint 5 darab konstans generálása a fordítóprogrammal, a fenti esetben a felsorolásbeli bariton kódja ténylegesen a nulla lesz, a alt kódja valójában egy, stb.

Kódolás befolyásolása

Néha szükség van arra, hogy ne az automatikus kódkiosztást használjuk, hanem fizikailag adhassuk meg az egyes értékek kódjait. Ezt a felsorolás belsejébe elhelyezett értékmegadásokkal tudjuk befolyásolni:

enum hangfekvesek 
{ bariton=10, 
  alt, 
  tenor=20, 
  mezoszopran,
  szopran=40
};

A fenti felírás eredményeként az alábbi kódolást írtuk elő:

bariton     = 10
  alt         = 11
  tenor       = 20
  mezoszopran = 21
  szopran     = 40

Vagyis ahol mi állítottuk be fixen a kódolási értéket, ott az kerül felhasználásra, egyébként pedig az automatikus kódkiosztás során a következő szabad kódot adja a rendszer az egyes lehetséges értékeknek.

Felsorolt típus

Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp1/page560
Nézetek
nincs sb_3.137.192.3 cikk