12.07.2015 Views

CES 2004 - Vitajte na stránkach www.einsty.hostujem.sk

CES 2004 - Vitajte na stránkach www.einsty.hostujem.sk

CES 2004 - Vitajte na stránkach www.einsty.hostujem.sk

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

P R O G R A M U J E M EProgramujeme v jazyku C#17. èasV tejto èasti seriálu o programovaní v C# u ukonèíme problematiku polí. Ako som s¾úbilminule, ukáeme si, ako pracova s po¾ami výluène pod¾a pravidiel objektovo orientovanéhoprogramovania. Väèšinou sa budeme odvoláva <strong>na</strong> triedu Array, ktorá v .NET Frameworkupredstavuje objekt po¾a (resp. jej inštancie).VYTVORENIE PO¼A. Na vytvorenie po¾a slúi statická metóda CreateInstance() triedyArray. Táto metóda existuje vo viacerých preaených verziách, tá základná jepublic static Array CreateInstance(Type, int);Táto verzia preberá ako prvý parameter typ elementov, ktoré bude pole obsahova, aceloèíselnú hodnotu vyjadrujúcu poèet elementov po¾a. Metóda vráti inštanciu triedy Array.Ïalšia preaená verzia tejto metódy preberá ako druhý parameter nie celé èíslo, ale poleceloèíselných hodnôt predstavujúce ve¾kosti jednotlivých dimenzií vytváraného po¾a, takeslúi <strong>na</strong> vytváranie multidimenzionálneho po¾a. Keby sme teda chceli vytvori trojdimenzio−nálne pole s ve¾kosami dimenzií postupne 4, 5 a 2, vytvorili by sme <strong>na</strong>jprv trojprvkové poles týmito ve¾kosami a následne ho pouili ako parameter metódy CreateInstance():int[] velkosti = new int[] {4, 5, 2};Array mdPole = Array.CreateInstance(typeof(int), velkosti);Ako vidíte, vytvorili sme trojdimenzionálne pole so iadanými ve¾kosami dimenzií, prièomjeho elementy sú typu int. Tu máte monos vidie pouitie operátora typeof(), ktorý predaný parameter vráti inštanciu triedy Type opisujúcu daný typ. Túto inštanciu pouíva metó−da CreateInstance() <strong>na</strong> urèenie, aký typ elementov bude pole uchováva.Ïalšie dve preaené verzie metódy CreateInstance() slúia <strong>na</strong> jednoduchšie vytváraniedvoj− a trojrozmerných polí a existujú len preto, aby nebolo potrebné pouíva v týchto prí−padoch uvedenú preaenú verziu tejto metódy <strong>na</strong> zjednodušenie práce s nimi. MetódaCreateInstance() pre dvojdimenzionálne polia preberá okrem parametra Type ešte dva celo−èíselné parametre vyjadrujúce rozmery jednotlivých dimenzií (v podstate rozmery matice).Preaená verzia metódy CreateInstance() pre trojrozmerné polia preberá ešte jeden celoèí−selný parameter <strong>na</strong>vyše, vyjadrujúci rozmer tretej dimenzie.Posledná preaená verzia metódy CreateInstance() slúi <strong>na</strong> vytváranie polí s explicitnýmindexovaním, teda prvky jednotlivých dimenzií nemusia by indexované od nuly. Sig<strong>na</strong>túratejto metódy vyzerá takto:public static Array CreateInstance(Type, int[], int[]);Prvý parameter špecifikuje typ ukladaných elementov, druhý ve¾kosti jednotlivých dimen−zií (podobne ako druhá uvedená verzia tejto metódy) a tretí špecifikuje poèiatoèné indexyjednotlivých dimenzií. Uvaujme predchádzajúci príklad s tým rozdielom, e chceme indexo−va v jednotlivých dimenziách od èísel 1, 7 a 3:int[] velkosti = new int[] {4, 5, 2};int[] dimenzie = new int[] {1, 7, 3};Array mdPole = Array.CreateInstance(typeof(int), velkosti, dimenzie);Táto verzia metódy CreateInstance() nám u po<strong>sk</strong>ytuje pomerne ve¾kú flexibilitu v tvorbepolí. Na zistenie <strong>na</strong>jnišieho a <strong>na</strong>jvyššieho indexu danej dimenzie môete poui metódyGetLowerBound() a GetUpperBound() triedy Array, prièom ako parameter jej odovzdáte indexdimenzie, ktorej hranice chcete zisti.PRÍSTUPOVÉ METÓDY. Take pole u vieme vytvori, ako teraz zapisova a èíta z jed−notlivých jeho prvkov? To si ukáeme v tejto kapitole.Na <strong>na</strong>stavenie hodnoty elementu (zápis do po¾a) slúi v triede Array metóda SetValue().Tá opä existuje v nieko¾kých preaených verziách, prièom všetky preberajú ako prvý para−meter odkaz <strong>na</strong> objekt typu object. V prípade, e pole ukladá primitívne dátové typy, je odo−vzdaná hodnota automaticky boxovaná <strong>na</strong> objekt svojej príslušnej triedy (pozri 9. èas tohtoseriálu). Prvé tri preaené verzie tejto metódy ešte k tomu preberajú postupne 1, 2 alebo 3celoèíselné hodnoty, vyjadrujúce v jedno−, dvoj− alebo trojrozmernom poli indexy elementu,ktorého hodnota má by modifikovaná. Keby sme <strong>na</strong>príklad chceli uloi v dvojrozmernompoli reazec "Test" do elementu s indexmi 2 a 5, urobili by sme to takto:pole.SetValue("Test", 2, 5);hodnotu, ktorou má by element modifikovaný, ale vracia hodnotu elementu ako odkaz <strong>na</strong>objekt typu object. Táto hodnota môe by v závislosti od kontextu automaticky odboxova−ná <strong>na</strong> príslušný dátový typ. Rozdiely medzi jednotlivými preaenými verziami GetValue() súobdobné ako pri metóde SetValue(). Prvé tri verzie preberajú postupne 1, 2 alebo 3 para−metre typu int v závislosti od toho, ko¾kodimenzionálne pole pouívate. Posledná verzia pre−berá ako parameter odkaz <strong>na</strong> pole s elementmi typu int, ktoré špecifikujú presné indexy ele−mentu v jednotlivých dimenziách po¾a. Pouitie je podobné ako v predchádzajúcej ukákepouitia metódy SetValue(). Na zí<strong>sk</strong>anie a vypísanie hodnoty elementu, ktorý sme <strong>na</strong>stavili<strong>na</strong> 55 v <strong>na</strong>šom predchádzajúcom príklade, môeme poui jednoduchšiu verziu metódyGetValue() preberajúcu tri celoèíselné parametre:Console.WriteLine(mdPole.GetValue(3, 8, 4));VYH¼ADÁVANIE V POLI. Trieda Array po<strong>sk</strong>ytuje aj nieko¾ko uitoèných metód <strong>na</strong>vyh¾adávanie v poli. Základnou metódou <strong>na</strong> vyh¾adávanie je statická metóda IndexOf(). Tejtometóde odovzdáte odkaz <strong>na</strong> vašu inštanciu po¾a, ktoré chcete preh¾adáva, a ako druhýparameter jej odovzdáte hodnotu, ktorú chcete vyh¾adáva. Táto hodnota je vo všeobecnos−ti odkaz <strong>na</strong> objekt typu object, ale môe by automaticky pod¾a potreby boxovaná. MetódaIndexOf() vráti index prvého elementu, ktorý obsahuje h¾adanú hodnotu. Ak taký elementneexistuje, je vrátená hodnota −1. Existujú ešte ïalšie dve preaené verzie metódy IndexOf(),prvá preberá <strong>na</strong>vyše ešte jeden celoèíselný parameter, ktorým môete špecifikova poèia−toèný index, od ktorého sa má zaèa v poli vyh¾adáva. Ïalšia preaená verzia umoòuje špe−cifikova nielen index, od ktorého sa zaène vyh¾adávanie, ale ïalším celoèíselným paramet−rom aj poèet prvkov, ktoré majú by preh¾adané.Trieda Array umoòuje takisto binárne vyh¾adávanie pomocou statickej metódy Bi<strong>na</strong>ry−Search(). Na jej pouitie treba, aby kadý z elementov implementoval rozhranie ICompa−rable, prípadne aby ste mali k dispozícii objekt implementujúci rozhranie IComparer. Toto jeu trošku komplexnejšia tematika, ktorej sa nebudeme v tejto èasti seriálu venova, ale ne−<strong>sk</strong>ôr sa k nej môeme v prípade záujmu vráti.PRECHÁDZANIE POLÍ. Polia reprezentované inštanciou triedy Array mono prechá−dza celé tak, e si zistíme poèet dimenzií, ich spodné a horné hranice a potom z nich zí<strong>sk</strong>a−vame hodnoty pomocou metódy GetValue(). Tento prístup je trošku akopádny, preto tuexistuje monos prechádza pole pomocou objektu implementujúceho rozhranieIEnumerator (tzv. enumerátor). Pokia¾ ste niekedy programovali v Jave, mono vám pomôeinformácia, e enumerátor v .NET Frameworku je obdobou javového iterátora. Trieda Arraypo<strong>sk</strong>ytuje metódu GetEnumerator(), ktorá vracia odkaz <strong>na</strong> objekt enumerátora. Tento objektpo<strong>sk</strong>ytuje vlastnos Current a metódy MoveNext() a Reset(). Vlastnos Current obsahujeaktuálny prvok enumerátora, MoveNext() sa posunie <strong>na</strong> <strong>na</strong>sledujúci prvok a Reset() vynulujeenumerátor (<strong>na</strong>staví pred prvý element). Prv ne prvýkrát zavoláte Current, musíte zavolametódu MoveNext(). Najjednoduchšie si pouitie enumerátora <strong>na</strong> poli ukáeme <strong>na</strong> príklade:IEnumerator e = mdPole.GetEnumerator();while (e.MoveNext()) {Console.WriteLine(e.Current);}Tento fragment kódu jednoducho prechádza celé pole a vypíše všetky jeho elementy dokonzoly. V prípade, e sa ho pokúsite vloi do nejakého svojho programu, nezabudnite <strong>na</strong>import priestoru názvov System.Collections.Metóda MoveNext() vracia logickú hodnotu true, pokia¾ objekt enumerátora bol posunu−tý <strong>na</strong> ïalší prvok, a false v prípade, e ïalší prvok neexistuje. Enumerátory môete rov<strong>na</strong>kýmspôsobom poui pre jednorozmerné, ako aj pre multidimenzionálne polia. Predstavujúve¾mi silný a univerzálny prostriedok <strong>na</strong> prechádzanie rôznych dátových štruktúr (kolekcií), apreto sa s nimi v <strong>na</strong>jblišom èase ešte párkrát stretneme.ZÁVER. V tomto pokraèovaní sme dokonèili prvú èas rozprávania o kolekciách, teda opoliach. Ukázali sme si nielen tradièný prístup k poliam, ale aj nové objektové poòatie polí.V ïalšej èasti sa zaèneme venova novej tematike, zostaneme však stále v obore kolekcií a ichimplementácie v .NET Frameworku. Dovtedy dovidenia.Andrej ChuPri modifikovaní hodnoty elementu v jednorozmernom a trojrozmernom poli by sme tedapostupovali podobne, iba poèet celoèíselných parametrov by sa menil v závislosti od poètudimenzií po¾a.Existuje však ešte jed<strong>na</strong> preaená verzia metódy SetValue(), ktorá preberá okrem novejhodnoty pre element len jeden ïalší parameter, a to pole typu int. Táto verzia slúi <strong>na</strong> <strong>na</strong>sta−venie hodnoty elementu v multidimenzionálnom poli, prièom jeho indexy sú postupne špe−cifikované v poli odovzdávanom ako parameter:int[] pozicia = new int[] {3, 8, 4};mdPole.SetValue(55, pozicia);Zí<strong>sk</strong>a hodnotu z po¾a mono prostredníctvom metódy GetValue(), prièom tá existuje tak−isto vo viacerých preaených verziách. Metóda GetValue() je (èo sa týka parametrov jejpreaených verzií) podobná metóde SetValue() s výnimkou toho, e (logicky) nepreberá2/<strong>2004</strong> PC REVUE 151

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!