Programujeme v jazyku C# - Diel 9. - Konštanty a enumerata

Michal Čižmár  /  12. 01. 2005, 00:00

Tento článok voľne nadväzuje na diel č. 4, ktorý bol o premenných. Preberieme si zaujímavé dátové typy, ktoré nám veľmi jednoduchým spôsobom umožňujú sprehľadniť zdrojový kód. Odporúčam prečítať.

>>Enumerata
Ak ste nečítali diel č.4 a ešte ste neprogramovali v nejakom inom programovacom jazyku tak ste sa možno s týmto slovíčkom ešte nestretli. Stretol som sa s tým, že veľa programátorov radšej používa český pojem a to : „výčtové typy.“

V objektovo orientovaných programovacích jazykoch sa používa veľa vecí, ktoré vznikli zoskupovaním príbuzných typov a premenných.

Jednoducho povedané, enumerata sú zoskupené množiny konštánt rovnakého
(alebo podobného) významu.

>>Nemali by sme si ešte niečo povedať o konštantách?

Mali! :-) Konštanty určite poznáte z matematiky. Napríklad PI, rýchlosť svetla c atď.
V programovaní sa konštanty používajú veľmi často. Dá sa programovať aj bez nich, keď použijete len jednoduché premenné. Napr.

int pocetRiadkov = 25 ;
Nie je to konštanta, niekde sa môže omylom zmeniť hodnota.

Konštanta je špeciálny typ premennej,
ktorej hodnota sa nedá meniť v priebehu programu alebo sa dá aspoň raz zmeniť (teda skôr nastaviť).

>>Syntax konštánt

Najlepšie je hneď uviesť príklad. Takže:

const
double rychlostSvetla = 2.99792458E08;
const
string meno = " Hadimrška";
rychlostSvetla
=rychlostSvetla*2; //chyba
meno
= " Kristián"; // a zas chyba

Konštantu je dobré si deklarovať niekde na začiatku bloku, triedy, kde sa bude používať. Niekedy sa môžete stretnúť s niečím podobným ako :

cenaNakupu = suma - suma * 0.3 ;

Keď to programátor programoval, možno vedel čo je to za číslo 0.3, ale možno o miesiac už nie. Takýmto číslam sa hovorí „magické čísla“ a sú známkou neprofesionálnosti programátora. Lepšie by to bolo:

const
float zakaznickyBonus = 0.3F;
cenaNakupu
= suma - suma * zakaznickyBonus;

Možno, že sa podobný výpočet so zákazníckym bonusom vyskytuje viac krát v programe. Ak by sme všade použili len číslo 0.3 a po roku keď budeme robiť novú verziu programu sa zákaznícky bonus znížil na 0.1, tak by sme museli toto číslo všade vyhľadať a zmeniť. Ak to máme zadeklarované ako konštantu stačí len jedna zmena a aj zdrojový kód bude čitateľnejší.

>>Premenné len na čítanie

Je to špeciálny typ konštanty, ktorej hodnota nemusí byť známa už počas kompilácie programu. Dá sa nastaviť až počas behu programu a to len raz, a to len v konštruktore triedy. Pretože triedy sme ešte nemali uvádzam len príklad, aby ste to mali pokope s konštantami a vysvetlené to bude neskôr. Hlavne si všimnite výraz readonly a to, kde ide použiť.

Príklad 9.1

using System;

class MainClass
{
  
public static void Main()
  {
  
Zlavy zlavy1 = new Zlavy(0.2);
  
zlavy1.NastavZlavu(0.5); //chyba
  
zlavy1.zakZlava=0.6; //chyba
 
}
}

class
Zlavy
{
 
public readonly double zakZlava; //!!!!!!

 
public Zlavy(double _zakZlava) // konstruktor
  {
       zakZlava = _zakZlava; // OK,LEN TU!!
 
}
 
 
public void NastavZlavu(double _zlava) //metoda
  {
        
zakZlava=_zlava//chyba
   }
   
}

>>Naspäť k enumeratám
Tak ako sme povedali enumerata sú skupiny konštánt rovnakého druhu. Príkladom môžu byť farby použite v programe. Napríklad v textovom programe je nastavená určitá farba pre písmo atď. Ja to vidím hneď na príklad, takže:

Príklad 9.2

using System;
public
enum Farba
{
  
modra, zelena, cervena, biela, cierna };//!!!
class
MainClass
{
 
public static void Main(string[] args)
  {
 
Farba farbPisma = new Farba();
 
farbPisma = Farba.cierna;
 
 
Console.WriteLine(" Farba pisma je {0}",farbPisma);
  }
}

POZOR! Za deklaráciou enumerát je bodkočiarka!!


Vnútorne sú enumerata reprezentované pomocou číselných konštánt. Takže napr. modra = 0, zelena = 1 , cervena = 2 atď. Keď ich ale dáme vypísať pomocou WriteLine, tak sa vypíše slovne meno konštanty a nie jej číslo. Všimnite si, že keď používame unumerata musíme ich kvalifikovať aj celým menom typu napr. Farba.cierna a nie len cierna ako by to išlo v C++. Možno sa to na prvý pohľad nezdá, ale znižuje to počet chýb v programe. Napríklad ak by ste porovnávali enumerata, prekladač kontroluje aj typy. Ak by ste v C++ napísali takéto niečo :
if ( farbPozadia == 5 ) prekladač by neohlásil chybu aj keď by farba z hodnotou 5 neexistovala.

Príklad 9.3 - Ukážka možných a častých chýb.
br>

using System;
public
enum Farba
{
  
modra, zelena, cervena,
biela, cierna
};

class
MainClass
{
 
public static void Main(string[] args)
  {
 
Farba farbPisma = new Farba();
 
Farba farbPozadia = new Farba();
 
farbPisma = Farba.cierna;
 
 
if(farbPisma == Farba.cierna//OK
 
farbPozadia=Farba.biela;
 
 
if(farbPisma == Farba.cervena) //OK
 
farbPozadia=Farba.zelena;
 
 
if(farbPisma == cervena)      //zle
 
farbPozadia=Farba.zelena;
 
    
if(farbPisma == 2 )           //zle
 
farbPozadia=Farba.zelena
   }
}

>>Výpis hodnoty enumerát
Stačí použiť pretypovanie na int. Pozrite v príklade.

Príklad 9.4

using System;
public
enum Farba
{
  
modra, zelena, cervena,
biela, cierna
};

class
MainClass
{
 
public static void Main(string[] args)
{

  Console.WriteLine(" Hodnota konstatnty pre ciernu je {0}",
                    (
int) Farba.cierna);
  }
}

>>Vlastné hodnoty enumerát
Niekedy nám nestačí pracovať iba s menami konštánt a ani nevystačíme s preddefinovaným číslovaním od 0 do N. Jednoducho si to môžete nastaviť v deklarácii unemerata.

Príklad 9.5

using System;
MainClass
{
class enum Rychlost
  
{ pomala = 40,
      stredna = 80,
      rychla = 130,
    };
   
public static void Main()
    {
       Console.WriteLine(" Pomala rychlot je do {0}Km/h",
                                   (
int) Rychlost.pomala);
     }
}

>>Počítanie s enumeratami
Aby ste mohli použiť operácie ako +, * atď. stačí pred deklaráciu napísať [Flags]. Je to potrebné použiť hlavne, keď si nastavíte aj vlastné hodnoty pretože potom +1 neznamená pripočítaj jednotku k hodnote enumerata, ale posuň sa na ďalší prvok. S niečím podobným sme sa ešte nestretli. Pozrite príklad.

Príklad 9.6

using System;
[
Flags] public enum Den
{
  
pondelok, utorok, streda,
  
stvrtok, piatok, sobota,
  
nedela
};

class
MainClass
{
 
public static void Main(string[] args)
  {
    
Console.WriteLine(" Den po pondelku je {0}",
                
Den.pondelok+1);
   }
}

>>Čo bude nabudúce?
Začneme sériu článkov o cykloch (for, while ....). Aj keď cykly sa už vyskytli v príkladoch, zatiaľ som ich podrobne nevysvetlil. Takže sa na to budúcu stredu určite pozrite.


>> Všetky príklady si môžete stiahnuť tu:
www.inet.sk/download/user/priklad9.1Enumerata.zip
www.inet.sk/download/user/priklad9.2Konstanty.zip
www.inet.sk/download/user/priklad9.3PorovnanieEnumerat.zip
www.inet.sk/download/user/priklad9.4HodnotaEnemerat.zip
www.inet.sk/download/user/Priklad9.5VlastneHodnotyEnumerat.zip
www.inet.sk/download/user/Priklad9.6pocitanieS_Enumeratami.zip

>>Predchádzajúce články :
Programujeme v jazyku C# - Diel 8. - Polia IV.
Programujeme v jazyku C# - Diel 7. - Polia III.
Programujeme v jazyku C# - Diel 6. - Polia II.

>>Všetky články :
www.inet.sk/cshapr  


Vaše otázky a pripomienky píšte do diskusie alebo na môj e-mail.

Michal Čižmár

micitn@orangemail.sk



SEE YOU!

Neprehliadnite: