Professional Documents
Culture Documents
za pomoci jazyka C#
Jii liei
Katedia infoimatiky Pl UJlP
Usti nad Labem
MMXlll (Beta s. ledna zc1I)
Ji Fier, 2013
Toto je piacovni veize skiipt. Je iena bez jakchkoliv zaiuk, co se te obsahu
i pouitelnosti.
Licence:
Creative Commons Uvete autora-Nezasahujte do dla 3.0 esko (CC BY-ND I.c),
viz http://creativecommons.org/licenses/by-nd/3.0/cz/
Pi sazb byly vyuity nasledujici open-souice ezy pisma
Linux Libertine
Linux Biolinum
DejaVu Sans Mono
Text byl vysazen za pomoci piogiamu X
L
A
T
l
X.
Ikony chyb
Zdiojov souboiy i fiagmenty kodu, ktei jsou uivany jako negativni pipady,
to jest obsahuji njakou chybu, jsou oznaeny nasledujicimi ikonami
syntakti yba
Kod s touto chybou nepjde ani peloit. Odhaleni tto chyby je pioto velmi snad-
n a iychl.
smanti yba (vjimen situace)
Tato smanticka chyba vede ke vzniku vjimky za bhu piogiamu. Pokud neni
vjimka zachycena, piogiam pedasn skoni. Detekce tto chyby je o nco na-
ionji, nebo kod, ktei ji obsahuje nemusi bt vbec pioveden (je-li napiklad
souasti netestovan vtve konstiukce if )
neoekvan i nedenovan ovn programu
Piogiam(i fiagment) nepiovadi oekavanou innost, piodukuje neoekavan v-
sledky (dsledn), nebo funguje jen pio uiit vstupy iesp. jen v uiitmkontextu.
Tento diuh chyb se odhaluje nejobtinji.
Obsah
1. Zklady objektov orientovanho programovn 7
1.1. Uiovn objektov oiientovanho pistupu . . . . . . . . . . . . . . . . . . . s
1.1.1. Objektov oiientovan pohled na okolni svt . . . . . . . . . . . . s
1.1.z. Obecn objektov oiientovan model . . . . . . . . . . . . . . . . . s
1.1.I. OOP piogiamovaci jazyk . . . . . . . . . . . . . . . . . . . . . . . . v
1.z. Zakladni pojmy OOP (na iovni objektovho pohledu na svt) . . . . . . . 11
1.z.1. Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.z.z. Tida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2. Zkladn objektov model C# 19
z.1. Zakladni tidy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zc
z.1.1. iseln tidy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zc
int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zc
double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1
z.1.z. Znakov a etzcov tidy . . . . . . . . . . . . . . . . . . . . . . . zz
z.1.I. Logick hodnoty . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1
z.1.1. asov okamiky . . . . . . . . . . . . . . . . . . . . . . . . . . . . z
z.z. lnteiakce s objekty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ze
z.z.1. Dotazovani na vlastnosti objekt . . . . . . . . . . . . . . . . . . . ze
z.z.z. Metody . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z
z.z.I. Opeiace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I1
Binaini aiitmetick opeiatoiy . . . . . . . . . . . . . . . . . . . . . I1
Dleni a zbytek po dleni . . . . . . . . . . . . . . . . . . . . . . . Iz
Unaini aiitmetick opeiatoiy . . . . . . . . . . . . . . . . . . . . . II
Opeiatoiy nad neiselnmi objekty a petovani opeiatoi . . . . I1
lndexace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I
z.I. Tidni metody a vlastnosti . . . . . . . . . . . . . . . . . . . . . . . . . . . Ie
z.1. Piomnn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Is
z.1.1. Denice a inicializace piomnnch . . . . . . . . . . . . . . . . . . 1c
Denice a inicializace piomnnch pio objekty hodnotovch tid . 1c
Denice a inicializace piomnnch pio objekty iefeiennich tid . 1z
z.1.z. Odkaz null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
I
z.1.I. Piazeni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1e
Vmna obsahu dvou piomnnch . . . . . . . . . . . . . . . . . . 1s
Petypovani pi piazeni . . . . . . . . . . . . . . . . . . . . . . . 1v
3. Konzolov programy 53
I.1. Zakladni stiuktuia piogiamu . . . . . . . . . . . . . . . . . . . . . . . . . . I
I.1.1. loimatovani piogiamu . . . . . . . . . . . . . . . . . . . . . . . . .
I.1.z. Jmenn piostoiy . . . . . . . . . . . . . . . . . . . . . . . . . . . . e
I.z. Pivni piogiam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
I.z.1. Vstup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
I.z.z. Zpiacovani . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ec
Opeiatoi iovnosti a neiovnosti . . . . . . . . . . . . . . . . . . . . e1
I.z.I. Vstup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e1
Konstiukce if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e1
I.I. Diuh piogiam Poitani slov . . . . . . . . . . . . . . . . . . . . . . . . . e
I.I.1. Hlavni algoiitmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . es
Cyklus foieach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c
Logick opeiatoiy . . . . . . . . . . . . . . . . . . . . . . . . . . . z
Roziujici metody . . . . . . . . . . . . . . . . . . . . . . . . . . .
Pikaz ietuin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I.1. Teti piogiam poet piacovnich dni v ioce . . . . . . . . . . . . . . . . . . v
I.1.1. Vstup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Relani opeiatoiy . . . . . . . . . . . . . . . . . . . . . . . . . . . . sc
Vjimen situace . . . . . . . . . . . . . . . . . . . . . . . . . . . . sz
I.1.z. Zpiacovani dat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sI
Cyklus while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s
I.1.I. Roziujici metoda JePiacovni() . . . . . . . . . . . . . . . . . . . . se
I.1.1. Vsledn piogiam . . . . . . . . . . . . . . . . . . . . . . . . . . . sv
I.1.. Piofesionalni iozieni . . . . . . . . . . . . . . . . . . . . . . . . . v1
4. Seznam zkladn kolekce 97
Asymptoticka sloitost . . . . . . . . . . . . . . . . . . . . . . . . . v
1.1. Seznam ListT~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1c1
1.1.1. Vytvoeni novho seznamu . . . . . . . . . . . . . . . . . . . . . . 1cI
1.1.z. Metody a opeiace nad seznamy . . . . . . . . . . . . . . . . . . . . 1ce
Poet pivk (vlastnost) . . . . . . . . . . . . . . . . . . . . . . . . . 1c
lndexace (opeiace) . . . . . . . . . . . . . . . . . . . . . . . . . . . 1c
Pidani/vloeni pivku . . . . . . . . . . . . . . . . . . . . . . . . . 1c
Pidani/vloeni vice pivk . . . . . . . . . . . . . . . . . . . . . . . 1cs
Vyjimani pivk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1cv
Hledani poloek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11c
Obsah
1.1.I. Piochazeni seznam . . . . . . . . . . . . . . . . . . . . . . . . . . 11z
Cyklus foi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.1. Selektivni vmaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11v
1.1.. Piazeni a duplikace . . . . . . . . . . . . . . . . . . . . . . . . . . 1z1
1.z. Piklady ioziujicich metod seznam . . . . . . . . . . . . . . . . . . . . . 1Ic
1.z.1. Nahodn peimutovani pivk v seznamu . . . . . . . . . . . . . . . 1I1
1.z.z. Test setidni seznamu . . . . . . . . . . . . . . . . . . . . . . . . . 1Ie
Vty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Iv
5. Uivatelsk tdy 149
.1. Denice nov tidy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Datov leny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Konstiuktoi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1I
Denice metody . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Pedenovani metody ToStiing . . . . . . . . . . . . . . . . . . . . 1e1
.z. Nova implementace (znovu a lpe) . . . . . . . . . . . . . . . . . . . . . . . 1e
Symbolick konstanty . . . . . . . . . . . . . . . . . . . . . . . . . 1I
Denice vlastnosti . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Sniovani zavislosti a zapouzdeni (nejen) v OOP . . . . . . . . . . 1sc
.I. Vyiovnavaci pam (cache) - kolekce, kteia zapomina . . . . . . . . . . . . 1s
.I.1. Navih iozhiani . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1se
.I.z. Datova iepiesentace . . . . . . . . . . . . . . . . . . . . . . . . . . 1vc
Automatick vlastnosti . . . . . . . . . . . . . . . . . . . . . . . . . 1vI
.I.I. lmplementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1v
Geneiatoiy nahodnch isel . . . . . . . . . . . . . . . . . . . . . . 1ve
Zkiacen vyhodnocovani logickch opeiatoi . . . . . . . . . . . . zc1
Podminkov opeiatoi . . . . . . . . . . . . . . . . . . . . . . . . . zcI
.I.1. Testovaci kod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zc
6. Slovnk 209
e.1. Zakladni opeiace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z11
e.1.1. Denice a naplnni . . . . . . . . . . . . . . . . . . . . . . . . . . . z11
e.1.z. Vyhledavani hodnoty podle klie . . . . . . . . . . . . . . . . . . . z1I
e.z. Vyuiti slovniku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1e
e.z.1. Databaze v pamti . . . . . . . . . . . . . . . . . . . . . . . . . . . z1
e.z.z. idk seznamy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zzc
N-tice (tuple) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zzz
e.z.I. Vyiovnavaci pam . . . . . . . . . . . . . . . . . . . . . . . . . . . zz1
e.z.1. ita vskyt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zz1
e.I. lnteini iepiesentace slovniku . . . . . . . . . . . . . . . . . . . . . . . . . . zze
e
7. Souborov orientovan vstup a vstup 233
.1. Bytov oiientovan vstup a vstup (binaini souboiy) . . . . . . . . . . . . zIe
.1.1. Bytov oiientovan vstup . . . . . . . . . . . . . . . . . . . . . . zIe
tida byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1c
konstiukce using . . . . . . . . . . . . . . . . . . . . . . . . . . . z1z
.1.z. Bytov oiientovan vstup . . . . . . . . . . . . . . . . . . . . . . . z11
Dokumentani poznamky . . . . . . . . . . . . . . . . . . . . . . . z1s
.z. Textov oiientovan vstup a vstup . . . . . . . . . . . . . . . . . . . . . . z1v
.z.1. Textov oiientovan vstup . . . . . . . . . . . . . . . . . . . . . . zc
.z.z. Textov oiientovan vstup . . . . . . . . . . . . . . . . . . . . . . . zI
StiingBuildei postupn vytvaeni etzc . . . . . . . . . . . . . ze1
.z.I. adkov oiientovan vstup a vstup . . . . . . . . . . . . . . . . . zee
A. Pehled syntaxe (EBNF) 271
A.1. Znaky a poznamky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zI
A.z. ldentikatoiy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1
A.I. Liteialy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z1
A.1. Viaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z
A.. Pikazy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z
A.e. Denice tidy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zs
A.. Piogiam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zsc
B. Pedvn parametr 281
B.1. Vstupni paiametiy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zs1
B.z. Obecn pedavani paiameti iefeienci . . . . . . . . . . . . . . . . . . . . zsI
C. Rozshlej programy 287
C.1. Vyiovnavaci pam (geneiicka veize nad slovnikem) . . . . . . . . . . . . . zs
C.z. Piogiam pio zjitni velikosti kolizni skupiny v hashovaci tabulce . . . . . zsv
1. Zklady objektov orientovanho
programovn
Objektov oiientovan piogiamovani je metodikou, kteia usnaduje implemen-
taci poitaovch piogiam, ktei modeluji iealn systmy iesp. poskytuji sloita
vizualni i multimedialni iozhiani.
Objektov oiientovan piogiamovani nepopisuje a neei vechny aspekty pio-
giamovani a v nkteich pipadech nelze tento pistup vbec aplikovat nebo jen s
obtiemi. Avak ji v dob, kdy se tato metodika popiv objevila (v jazyce Simula
v ioce 1ves), se ukazalo, e viazn usnaduje implementaci a pedevim spiavu
sloitjich piogiam.
Navic se piokazalo, e OOP lze kombinovat s nkteimi ji existujicimi pistupy
iesp. jej lze integiovat do ji existujicich piogiamovacich jazyk. Nap. ji Si-
mula je de facto objektov oiientovanm iozienim staiiho jazyka Algol[1vec]
s jeho pioceduialn-stiuktuiovanm pistupem. Objektov piogiamovani se tak
postupn stalo de facto standaidem pio modelovani a implementaci sloitjich
aplikaci. Podpoia OOP byla zahinuta do vtiny klasickch ( ped-OOP) piogia-
movacich jazyk vetn napiklad Fortranu, Cobolu, Pascalu a jazyka C. Navic v
pibhu asu vzniklo velk mnostvi jazyk, ktei ji od svch poatk podpoiuji
objektov piogiamovani (Smalltalk, Python, Java, Rubby).
Objektov oiientovan piogiamovani se vak neomezuje pouze na vlastni imple-
mentaci piogiam. Objektov oiientovan pistup se pouiva i ve fazi analzy a
navihu sofwaiovch systm a podstatnou ioli hiaje i pi jejich spiav. V za-
sad lze (z pohledu piogiamatoia) iozliit tyto iovn objektov oiientovanho
pistupu (od nejabstiaktnji k nejkonkitnji)
objektov oiientovan pohled na svt
obecn objektov oiientovan model
objektov oiientovan jazyk
8
1.1. rovn objektov orientovanho pstupu
1.1.1. Objektov orientovan pohled na okoln svt
Hlavni (i kdy nefoimalni) vchodisko objektov oiientovanho piogiamovani.
Z hlediska OOP je svt tvoen (dynamickmi) objekty, ktei spolu inteiaguji, pi-
em mohou mnit svj stav, vznikat a zanikat. Pouze piostednictviminteiakci se
piojevuje chovani objekt a manifestuji se jejich statick i dynamick vlastnosti.
Tento pohled na svt neni nikteiak ievoluni, nebo jej lid v zasad uivaji od
nepamti. Lidi vdy iozkladaji svt na jednotliv objekty, ktei dokai zkoumat
jen podle jejich inteiakci s okolim, bez toho, e by znali vnitni piiny tohoto
chovani iesp. vbec vidli do vnitku jednotlivch objekt.
Napiklad vtina lidi dokae zcela jednoznan odliit jednotliv dopiavni pio-
stedky (auta, vlaky), popsat jejich chovani a odhalit nktei jejich skiyt vlast-
nosti, bez toho e by byli je iozebiali do posledniho ioubku iesp. dokonce na
jednotliv elementaini astice, bez znalosti stiojniho inenistvi a kvantov me-
chaniky.
And he that breaks a thing to nd out what it is has le the path of wisdom.
Gandalf, Pan pisten
Pokud se vak chcete stat dobimi objektov oiientovanmi piogiamatoiy i do-
konce skvlmi analytiky, musite tuto velidskou schopnost iozvinout do vyi
dimenze, vidt objekty v novch souvislostech a pedevim vidt (bn) nevid-
n. Nesmite se nechat svazat konvennimi pohledy na pioblematiku i jazykem a
jeho pevn denovanmi pojmy.
1.1.2. Obecn objektov orientovan model
Tento model popisuje (sofwaiov) piostedky (iesp. jejich koncepce), s jejich
pomoci lze v pamti poitae modelovat objekty iealnho svta. Bohuel adn
skuten standaidni i dokonce univeizalni model neexistuje. Pesto vak na-
tsti existuji piostedky i mechanismy, ktei jsou podpoiovany vtinou OOP
jazyk iesp. je lze ielativn snadno nahiadit i opsat.
Mezi nejbnji pivky OOP modelu pati tidy, metody, dynamick polymoi-
smus, konstiuktoiy (inicializatoiy), objektov kolekce (kontejneiy), apod. Mezi
Zaklady objektov oiientovanho piogiamovani ,
mn ast pivky OOP pati iozhiani (inteiface), vlastnosti (piopeity) nebo tidni
(statick) metody.
Tyto spolen iysy lze vyuit pi navihu aplikace, jen tak nemusi bt vazan na
konkitni piogiamovaci jazyk nap. pomoci modelovaciho jazyka UML. Navic to
usnaduje ivot i piogiamatoim, nebo umouje jejich vzajemnou komunikaci
(napi OOP jazyky a platfoimami) a zjednoduuje ueni se novm OOP jazykm
(tj. pokud ji znate jin OOP jazyk je snadnji se nauit jin). Navic ielativn
velka skupina jazyk (Java, C#, PHP) pouiva i podobnou syntaxi pio zakladni
pivky modelu (napiklad pio volani metod).
1.1.3. OOP programovac jazyk
Piogiamatoi se s objektov oiientovanmpistupemsetkavaji pedevimna iov-
ni konkitnich piogiamovacich jazyk.
Objektov lze v zasad piogiamovat v libovolnm univeizalnim jazyce, napiklad
v jazyce C. Je to vak velmi naion a piogiamy jsou velmi nepehledn (a zcela
nevhodn pio zaateniky). Ne zcela vhodn jsou i jazyky, kde je OOP pouh
pilepek k ji existujicimu jazyku, jako je napiklad C++, PHP nebo Perl (i kdy i
v tchto jazycich lze vytvaet skuten OOP piogiamy).
Nejvhodnji skupinou jsou tak jazyky, ktei byly navihovany jako objektov, ale
sdileji iysy se zakladnimi s oblibenmi univeizalnimi jazyky (tj. pedevim s jazy-
kem C). Mezi tyto jazyky pati napiklad Java, C# nebo Python. U tchto jazyk je
implementace pvodniho navihu (v obecnm modelu) ielativn pimoaia a pln
podpoiovana jazykovmi konstiukcemi.
Na opanm polu jsou jazyky, ktei jsou ielativn vzdalen hlavnimu pioudu, je-
jich syntaxe je vak vytvoena pimo pio (nkdy ponkud extiavagantni) OOP
model. Klasickm pikladem je Smalltalk, ale existuji i novji ist objektov oii-
entovan jazyky (nap. Scala). Navic v tchto jazycich je tm nemon napsat
kod, ktei by nebyl objektov (nicmn mete stale pouivat nevhodn i do-
konce zcela patn objektov navih).
Nktei konstiukce klasickch OOP jazyk se vyskytuji i u jazyk, ktei nejsou
oznaovany jako objektov (nap. Go pouze s podpoiou iozhiani) iesp. jsou kla-
sikovany jako specialni pipady OOP jazyk (Javascript a Lua, ktei neobsahuji
pimou iepiesentaci OOP tid).
1o
Podpoia objektov oiientovanho pistupu u jednotlivch jazyk je schematicky
vyjadena na obiazku 1.1. Obiazek bohuel zobiazuje jen nktei jazyky, piem
vzajemna pozice jazyk neme bt vdy stanovena zcela objektivn. Vlevo jsou
jazyky podpoiujici jak tidy tak nktei z typ objektovho polymoismu (tj.
jazyky nabizejici odpoiu pevaujiciho OOP modelu).
C
Fortran (03)
Ada (98)
PHP 5
C++
Objective C
C#
Python
Java
ca!a
"a!!ta!#
$o
%&by
'&a
Javacri(t
Per!
#!a)ic#* OOP "ode! (Java) e+otic#* OOP "ode!
neobje#tov*
ja,y#
-i)t. obje#tov*
ja,y#
Obiazek 1.1. Objektov oiientovan piogiamovaci jazyky
Kiom pim podpoiy OOP v syntaxi jazyka je nezbytn, aby byli k dispozici i
objektov knihovny, ktei se snadno ioziuji a pokivaji, alespo zakladni po-
adavky soudobch aplikaci (GUl, inteinetov sluby, databaze). Navic by tyto
knihovny mly pln vyuivat potencial objektovho modelu pislunho jazyka.
Pokud napiklad poiovname standaidni knihovny jazyka C-- Java, zjistime, e ja-
vovsk knihovny jsou nejen mnohem iozsahleji, ale tak lpe vyuivaji potencial
OOP.
Na iovni piogiamovaciho jazyka je nutno zohlednit i efektivitu vslednho stio-
Zaklady objektov oiientovanho piogiamovani 11
jovho kodu (kad i sebeabstiaktnji piogiam je nakonec peloen do jednodu-
chch stiojovch instiukci piocesoiu). Me toti nastat situace, kdy i velmi do-
konal objektov model nelze napiogiamovat tak, aby aplikace mla iozumnou
odezvu.
U piogiamatoia v OOP jazycich se se tak pedpoklada, e jejich znalosti nejsou
omezeny pouze na objektov konstiukce, ale maji i zaklady algoiitmizace ( vy-
tvaeni a pouivani algoiitm), datov iepiesentace objekt (kliov je napiklad
uvolovani objekt z pamti) a efektivniho vyuivani haidwaiovch a systmo-
vch piostedk (tj. piostedk spiavovanch opeianim systmem). Pikladem
je vyuiti asynchionniho pistupu (napiklad pi pistupu k webovm seiveim)
i dokonce paialelismus (vyuivani vice piocesoi i jadei).
1.2. Zkladn pojmy OOP (na rovni objektovho
pohledu na svt)
1.2.1. Objekt
Zakladnim pojmem objektov oiientovanho piogiamovani je pekvapiv ob-
jekt. Na iovni objektov oiientovanho pohledu na svt me bt objektem li-
bovolna vc, veliina, oiganismus i lovk (iesp. pesnji jeho nefoimalni model,
ktei mame ve svch hlavach). Zakladnim atiibutem kadho objektu je jeho jed-
noznana identikace (vymezeni)
Pravidlo 1: Kad objekt je jednoznan identikovateln.
l kdy se toto piavidlo jevi jako tiivialni, opak je piavdou.
Nejdive je nutno ujasnit, co vlastn znamena identikace. Pio lovka je identi-
kace spojena s pojmenovanim, tj. kad objekt me bt opaten jmnem
pes Puntk, koka Hebkosrstka, etn Jana Novkov, kniha se signaturou N123586,
strom N56-1256 (piklady objekt identikovatelnch jmnem)
Dale poadujeme jedinenost identikatoiu (jinak bychom nebyli schopni odliit
jednotliv objekty). Jedinenost nemusi bt globalni (celovesmiina), nebo posta-
uje odliovat jen objekty, ktei se vyskytuji v popisovanm systmu. l tak me
bt identikace pomoci etzc pioblematicka (nap. ve im me bt nkolik
etnich se stejnm jmnem). Pio zjednodueni lze vak vdy pedpokladat, e
1:
identikatoiy jsou piiozenmi isly. ldentikace je pak vzajemn jednoznan
zobiazeni mezi objekty a libovolnou nepiazdnou podmnoinou piiozench isel.
To vak stale neni ten hlavni pioblm s identikatoiy.
Pedpokladejme napiklad, e chceme identikovat knihy. Budeme je identiko-
vat podle titulu (i pesnji lSBN) nebo budeme knihy identikovat podle jednot-
livch vtisk (tj. fyzickch objekt, viz piklad ve)` Podobn je mono identi-
kovat jednotliv domaci zviectvo nebo jen diuhy, pokud s nimi piacujeme jako
s abstiaktnimi objekty.
Na otazku neni jednoznana odpov, nebo identikace (a tim i vymezeni objek-
t) je dano zamenim vai aplikace (tj. pio koho a za jakm elem ji vytvai-
te).Pokud piete piogiam pio vydavatele nebo bibliogiai, pak je objektem vyda-
ni knihy a identikatoiem nap. lSBN. Naopak pio knihovny je objektem vtisk a
identikatoiem signatuia.
U zviatek je situace podobna. Pokud vytvaite piogiam pio chovatele nebo zv-
iolkae, pak je nutn identikovat jednotliva zviatka. Naopak pio vvojov bi-
ology je vhodnji piacovat s celmi diuhy (nap. jak je vvojov vztah mezi
psem ( pes jako diuh) a kokou). Tiochu matouci me bt situace v pipa-
d aplikace pio dopiavce, jen pepiavuje (mimo) jin i psy a vyaduje zaplaceni
jizdnho. Dopiavce nemusi samozejm identikovat psy jmnem, ale na diuhou
stianu nepepiavuje psy jako diuh, ale jednotliv psi individuality. Ve skutenos-
ti je zde objektem konkitni pepiavovan pes, ktei je identikovan napiklad
islem jizdenky. Pokud je stejn pes pepiavovan pozdji (na jinou jizdenku) je to
ji jin objekt (s jinm identikatoiem).
Dali zajimavou skupinu objekt tvoi napiklad penni astky. Penni astky
lze jako fyzick objekty inteipietovat jen pi omezeni na bankovky (nebo maji
sv identikatoiy siiova isla) a to jen ve velmi omezenm iozsahu aplikaci
(sbiatel, kiiminalist). Ve valn vtin pipad je penni astka iepiesento-
vana jen islem bez ohledu na fyzickou iepiesentaci (jinak eeno nap. vechny
hodnoty 1ccI K jsou neodliiteln a iepiesentuji tak jedin objekt). Podobn jsou
neodliiteln i hodnoty fyzikalnich veliin iesp. isel (i kdy otazkou je zda vbec
existuji dva stejn ale odliiteln iseln objekty nap. dv dvojky)
Nyni se podivame na dali kliov iys objekt piiozenho svta. Mylen mo-
del, kteim objekt iepiesentujeme v nai mysli je vdy viaznm zjednoduenim.
Toto zjednodueni (iozsah a zameni) neni absolutni, ale je opt dano cilovou
aplikaci modelu.
Zaklady objektov oiientovanho piogiamovani 1
Pravidlo 2: Objekt je zjednoduenm modelem reality
Klasickm pikladem jsou (mechanick iuikov) hodinky. Vtin uivatel ho-
dinek postauje model, ktei si vima jen polohy iuiek, kteiou lze (nejedno-
znan) mapovat na aktualni as. Model me bt samozejm o tiochu sloitji
(nap. zohledujici zpodni/pedbihani, monost nastaveni novho asu), ale z-
stava stale na povichu hodinek.
Dovnit hodinek se musime podivat, jen v pipad kdy jste hodinai. Ale i potom
je model zjednoduen. Kada jednotliva souast hodinek (koleka, piuiny, se-
tivaniky) je samozejm opt sloena z atom. Kvantov model hodinek je vak
ji v piaxi neiealizovateln (tj. je zbyten pokiaovat dale v iozkladu).
Podobn u zviatek vystaime s velmi jednoduchm modelem u dopiavni spole-
nosti (vejde/nevejde se do schiany), ponkud jinm (a miin sloitjim) u cho-
vatel (nap. daje o pvodu, poadovan kimeni) a zcela jinm (a nejsloitjim)
u biolog.
V objektov oiientovanm pohledu je pioto vdy kliov vnji chovani objektu
tzv. rozhran, zatimco vnitni stiuktuia a stavy (tzv. implementace objektu)
mohou (iesp. mly by bt) bt ukiyty.
Cel mechanismus, jen je oznaovan jako zapouzden (tj. ukiyti implementa-
nich detail) je opt v piincipu zcela tiivialni (lid si vci zjednoduuji neustale,
jinak by se zblaznili). Bohuel u iealnch model neni snadn poznat, kde je hia-
nice mezi vnjimiozhianima skiytou implementaci. Pokud objekt zjednoduime
pili, pak meme omezit jeho pouitelnost pio danou aplikaci, pokud ukaeme
pili mnoho z vnitku tak zvime zavislost okoli na tchto detailech. Pokud na-
piklad zveejnime polohy koleek v hodinovm stiojku (kalibiu), pak se nktei
zvidav pozoiovatel me nauit odeitat polohu koleek (ignoiuje bni iozhia-
ni), co se jevi jako iozumn a do okamiku kdy se stiojek zmni. Nestandaidni
uivatel, jen se stal zavislm na inteini iepiesentaci, pak me odeitat patn
as.
Pedchozi piklad je sice ponkud uml, ale lze nalzt i piaktitji piklady.
Pedpokladejme knihovnu, jeji knini sklad neni bn dostupn tenam. Po-
kud si chce tena objednat knihu, pak si napie jeji signatuiu a jde za knihovni-
kem. Ten knihu vyhleda ve skladu a peda ji tenai. Pedani listku se signatuiou
knihovnikovi je iozhiani objektu knihovny, vyhledani je implementaci. ktei ui-
vatel bn nezna (nikdy toti nebyl ve skladu).
Lin knihovnik se vak iozhodne, e je zbyten obtovat se chozenim do skladu
1
a tak vysvtli tenam, jak si knihu ve skladu vyhledat a necha je, aby si knihu
nali sami. Pioblm lenocha se zda vyeen a knihovnik ma as na svou (peima-
nentni) kaviku.
eeni vak ma pinai hned nkolik pioblm. Pivni je obdobou pioblmu ote-
vench hodinek. V okamiku, kdy se zmni mechanismus vyhledavani knih ve
skladu (nap. vmnou polic), musi se vichni tenai nauit nov systm (co je
asov naion a navic v mezidobi dochazi k selhanim). Diuh pioblm spoiva
v tom, e tenai mohou viacet knihy na patna mista a uvst tak sklad do nekon-
zistentniho stavu (mohou samozejm knihy i kiast, co by tena nikdy neudlal,
iesp. pinaet do skladu vlastni knihy, co je jet mn piavdpodobn). Vsledek
je zejm, knihovna bizy pestane fungovat.
Pi stanoveni iozhiani (tj. iovn detail) je nutno vychazet z chovani objekt,
jak se jevi (iesp. jak se bude v budoucnu jevit) jeho uivatelm. Uivatel doka-
i objekt chaiakteiizovat jen z jeho chovani (viz ve). Analytik i piogiamatoi
se musi vdy vit do iole budoucich uivatel, co jsou jini piogiamatoi ve v-
vojaskm tmu nebo piogiamatoi na celm svt, pokud je vytvaena veejna
knihovna. V adnmpipad neni v hodn pi navihu vychazet z inteiniho popisu
i algoiitmu (i kdy je sebelepi a napiosto genialni).
Posledni chaiakteiistika vychazi z omezen ivotnosti kadho objektu.
Pravidlo 3: Objekt m omezenou dobu ivota (tj. objekt vznik a po urit dob
zanik bhem n se stle mn
l toto piavidlo popisuje zcela zakladni chaiakteiistiku svta, kteiou chapeme zce-
la intuitivn od dtskch let. Samozejm existuji i objekty, jejich ivotnost je
neomezena a jsou zcela nemnn nap. isla nebo fyzikalni veliiny (zde ovem
zalei ponkud na inteipietaci), ale jen malo piogiam vytvai nap. matematick
tabulky.
U veho ostatniho je zejm, e ve vznika a zanika a pedevim se stale mni.
Vechny jsoucna (objekty) se pohybuji nic nezstava stale stejn
Vznik a zanik objekt nelze piiozen omezit pouze na jejich vznik a destiukci
(nap. v biologick slova smyslu). Objekt zanika i zmnou svho chaiakteiu nebo
oputnim systmu a podobnm zpsobem me i vznikat.
Zaklady objektov oiientovanho piogiamovani 1
Napiklad pokud student ukoni studium, zanika jako objekt student v iamci in-
foimaniho systmu koly (fyzicky natsti nai studenti vesms ukoneni studia
ve zdiavi peivaji). Pokud je absolvent bezpiostedn zamstnan na stejn kole,
vznika nov objekt zamstnanec (vazan na stejn fyzick objekt).
V nkteich pipadech nov objekt nezanika, vytvai se vak jeho nemodikova-
na i modikovana kopie. Napiklad pokud modelujeme vznik sloitjich objekt,
je mnohdy uitenji pedstava, e objekt nejdive vznikne jako kopie jinho ob-
jektu a nasledn je modikovan. Napiklad nov poita ( tj. jeho model, nap.
pio ely siov komunikace) me vzniknout vytvoenim kopie (klonu), ji exis-
tujiciho a naslednou modikaci konguiace (nap. zmnou etheinetov adiesy).
Pioblematika vzniku a zaniku objekt se stava jet sloitji na iovni obecnho
objektovho modelu a nasledn na iovni piogiamovaciho jazyka.
My se vak nyni podivame na diuh kliov pojem objektovch jazyk na tdu.
1.2.2. Tda
l ty nejjednodui systmy mohou potencialn obsahovat tisice i desetisice iz-
nch objekt. Napiklad pokud modelujeme dopiavni systm pak se v nm na-
chazi stovky spojeni, tisice automobil apod. Natsti lid maji schopnost najit
objekty se stejnm nebo podobnm chovanim a ty v jazyce oznait spolenm
pojmem.
Objektov piogiamovani postupuje podobn jednotliv modelovan objekty se
seskupuji do mnoin, ktei lze oznait jako tdy (objekt).
Tida obsahuje vechny objekty, jejich chovani je obdobn tj. ieaguji stejn (ne-
bo velmi podobn) pi inteiakci s okolim. Rozhodujici je zde dynamick chovani
objekt (pesnji jeho piojevy) nikoliv statick vlastnosti objekt.
Pravidlo 4 Tda je urena (dynamim) ovnm objekt nikoliv statiou vlast-
nost
Podivejme se napiklad na automobily. l kdy lze foimaln vytvoit tidu eive-
nch aut, je to ve vtin pipad zbyten, nebo kiom baivy se eivena auta
nelii od ostatnich aut. Neplatite za n vyi pojitni, neplati pio n specialni
dopiavni pedpisy (Zakaz vjezdu eivench aut) a nevyiabi se ve specialnich
tovainach. Naopak me zahinovat auta, kteia se svmv chovani dosti lii (nap.
eiven tiabant veisus eivena nakladni Tatia). Podobn neni iozumn vytvaet
tidy podle viobc aut (vjimkou jsou viobci vyiabjici jeden specializovan
1e
typ auta). Pokud vak vytvaime aplikaci pio piodejce aut, musime nkdy zohled-
nit izn piodejni podminky (ani to vak ve vtin pipad nevede k navihu
nov tidy).
Ponkud jina je situace u vlastnosti, ktei iozdluji objekty do skupin s iozdilnm
chovanim. Hmotnost auta napiklad viazn ovlivuje mechanismus placeni sil-
ninich poplatk. Automobily do I, tun plati poplatky pomoci dalninich zna-
mek. Auta s vyi hmotnosti plati mto (se zcela odlinm mechanismem platby).
Pokud tedy vytvaime aplikaci pio dopiavce nebo stat, je iozdleni do tid mon
(nikoliv vak nutn).
Tidy se, jak bylo ve uvedeno, velmi blii pojmm, je jsou uivany v lidskch
jazycich. lxistuje vak jeden zasadni iozdil
Pravidlo 5: Tdy nejsou absolutn konstrukce, mus se denovat pro kadou probl-
movou domnu a aplikaci zvl
Zatimco v jazyce jsou pojmy tm nemnn (jinak by nefungovala komunikace)
a tvoiba novch pojm je ielativn omezena, jsou tidy nov denovany pio ka-
dou aplikaci (v zasad je vytvoen nov svt s vlastnimi jazykem a pojmy, i kdy
samozejm velmi omezen).
Bohuel vichni piogiamatoi a analytici jsou lid a tak se nejdive nauili svmu
mateskmu jazyku a a pot se dozvdli o objektov oiientovanm piogiamo-
vani. Vichni tudi mysli ve xnim systmu svho jazyka, ani by si to vdom
pipoutli. Navic jsou nuceni tidy pojmenovavat slovy a teiminy piiozenho
jazyka (etiny nebo anglitiny), piem vtinou voli jednoslovn a stiun tei-
miny, ktei maji pevnou a tm nemnnou smantiku.
Pikladem jsou tidy se jmny Vlak, editel, Pota, Prodejna, Pes, apod. Tyto na-
zvy mohou samozejm oznaovat tidy, je jsou pio danou aplikaci optimalni.
asto vak jen ukazuji malou fantazii i odvahu autoia, iesp. pili zjednoduen
nebo neadekvatni objektov navih. Specializovan aplikace spie vyuivaji jmna
typu KolejovHromadnDopravnProstedek, InternZamstnanecSdcPravomoc,
SovloitSCentralizovanouSprvou, KoncovDistributorSProdejnPloou nebo
tak DomcZveSeSpecilnmPrvnmPostavenm. Tato jmna jsou bn nadmno-
inou pvodnich etablovanch pojm nebo naopak podmnoinou (specialnimpi-
padem). V nkteich pipadech vak mohou jit i napi bnmi pojmy.
Nejdive uveme uml, ale ilustiativni piklad. Pedstavte si vesnick dvi s di-
bei a diobnm zviectvem. Rozdleni jeho objekt do tid podle ivoinch diu-
h zvladne kad a jevi se jako nejpiiozenji (obiazek 1.z na nasledujici stian
Zaklady objektov oiientovanho piogiamovani 1,
koky
slepice
psi
klasick rozdlen do td
(jazykov termny)
aportujc zvtka
flegmatici
zvdavci
ad-hoc rozdlen do td
(podle chovn)
Obiazek 1.z. Objekty a tidy
18
nahoe). Mete vak zvolit i jin netiadini dleni. Pokud napiklad hodite kla-
cik, tak se zviata iozdli na apoitujici (klacik pinesou), zvdava (iozbhnou se
za klacikem) a apaticka (nijak neieaguji), viz piklad na obiazku 1.z dole. l kdy
toto iozdleni asten souvisi s iozdlenim na diuhy, mohou se objevit i pekva-
piv iozdily nap. apatick a zvdav koky (apoitujici koky jsou samozejm
vyloueny), i apoitujici slepice.
Pi navihu aplikace pio ciash-testy je vhodn denovat tidu piunch objek-
t s hmotnosti vice ne cckg (co jsou nap. automobily, sloni a vti klady).
Aplikace poskytovatele hiomadn dopiavy me denovat dopiavni piostedek
s dlouhm dojezdem (doletem) i piostedek s piomnnm potem pepiavova-
nch osob (co nemusi bt jen vlak, ale teba i skupina taxik).
Otazka k zamyleni Je tida objektem`
2. Zkladn objektov model C#
Pio vvoj sofwaiu ( poitaovch piogiam a aplikaci) je typick viazn kva-
litativni posun piojevujici se vznikem stale sloitjich datovch stiuktui a pio-
stedk komunikace (v nkolika vistvach abstiakci). Tento vvoj je podpoen i
stale sostikovanjimi a komplexnjimi piogiamovacimi jazyky.
Na diuh stian vvoj v oblasti haidwaiu (tj. pedevim) piocesoi je spie kvan-
titativni. Zatimco se piocesoiy ziychlily v adu desitek milion, zstava stiojov
kod v zasad nezmnn. lnstiukce tohoto kodu piacuji pouze s nkolika jedno-
duchmi iselnmi typy iozliujic stale celoiselnou iepiesentaci a iepiesentaci s
adovou aikou.
Z tohoto dvodu existuje i v modeinich objektov oiientovanch jazycich jen
nkolik tid, je jsou pimo podpoiovany piocesoiem (a vechny jsou v zasad
iseln nebo jednodue na isla zobiaziteln). Objekty ostatnich tid vznikaji skla-
danim z elementainich iselnch objekt (piem v souladu s piincipem zapouz-
deni tuto skutenost skivaji). Na obiazku z.1 je znazoinn piincip skladani gia-
ckho objekt z objekt elementainich iselnch tid. Zde jsou to objekty tidy
byte a double.
model
vagonu
model
lokomotivy
model
vlaku
double:5
double:4
barva: FF0000
2D bod
byte: FF
Bezierova
kivka
model
vagonu
seznam
Brush
Canvas
Obiazek z.1. Skladani z elementainich objekt
Jedinou vjimkou jsou objekty, ktei zapouzduji pistup k datm, je jsou spia-
1v
:o
vovany opeianim systmem a jsou iealizovany mimo opeiani pam. Pikla-
dem jsou napiklad objekty umoujici siovou komunikaci (tzv. sokety), objekty
GUl iozhiani (okna, idici pivky data jsou uloena v pamti giack kaity) ne-
bo souboiy (data jsou typicky na discich). Na naem ilustiativnim schmatu jsou
systmovmi objekty instance tidy Canvas (kieslici plocha) a Brush (objekt ie-
piesentujici baievn vpln). Tyto objekty zpistupuji piostedky poskytovan
giackou kaitou.
2.1. Zkladn tdy
2.1.1. seln tdy
int
Zakladni iselnou tidou jazyka C= je tida System.Int32 (jmno tidy obsahuje
piex jmennho piostoiu, viz dale). Tato tida se pouiva tak asto, e pio ni
existuje zkiatka int. Slovo int je odvozeno z anglickho teiminu integer (number)
cel islo a pouiva se ve vtin modeinich piogiamovacich jazyk.
Do tto tidy pati pesn z
Iz
objekt, co jsou vechna cela isla isla od z
I1
a do z
I1
1 vetn (adov cca -z miliaidy a z miliaidy). Tento iozsah je dan
velikosti objektu v pamti (1 byty) a bitovou iepiesentaci (tzv. dvojkov doplnk).
Vytvoeni novho objektu tidy int je snadn, postauje uvst zapis isla v de-
sitkov, osmikov nebo estnactkov soustav pimo v piogiamu. Pim zapis
objektu v piogiamu se oznauje teiminem literl.
literl hodnota (v destkovm zpise)
1z 1z
-1z -1z
c11 1z
cxB 1z
Oktalov (osmikov) zapis se pouiva ielativn zidka (nejastji v piogiamech
piacujicich s haidwaiem nebo pistupovmi piavy v Unixu), zaatenici by se
vak mly vyhbat zapism celch isel zainajicim nulou (vjimkou je samo-
zejm samotna nula).
Zakladni objektov model C= :1
double
Diuhou zakladni iselnou tidou je tida s ponkud matoucim nazvem System.-
Double (zkiacen double). Toto jmno je zkiacenim teiminu double precision o-
ating point number (islo v pohybliv adov aice s dvojitou pesnosti). isla
v pohybliv adov aice umouji iepiesentovat iacionalni isla v uiitm (ko-
nenm) inteivalu a s konenou pesnosti (tj. potem platnch desetinnch mist).
isla v dvojit pesnosti (opioti pvodni, avak stale pouivan jednoduch) doka-
i iepiesentovat isla v iozsahu cca 1c
Ics
a 1c
Ics
s pesnosti cca 1 desetinnch
mist.
lnteini iepiesentace ma tvai z
= s.I 1c
e
), 2e1 (zc, opt
odlin od celoiselnch 20)
A nkolik nepiaktickch liteial (vechny se vyhodnoti na stejn objekt tidy
double s hodnotou c) 0., .0, .0000, 0e5, 0e0, -0.0, -0e-0 (apod).
2.1.2. Znakov a etzcov tdy
Kiom isel dnes pati k zakladni tidam znakov a etzcov tidy. Objekty zna-
kovch typ jsou znaky tj. symbolick iepiesentace pismen, islic, diakiitickch
znamnek, apod. Kad znak je intein iepiesentovan islem (tzv. kodem znaku),
ktei je indexem do tabulky vech dostupnch znak (vlastni kod znaku vak ji
nehiaje pili velkou ioli a vyuiva se spie vjimen).
V minulosti existovalo velk mnostvi zabulek znak (znakovch sad), z nich
nejznamji je znakova sada ASCII (se 1zs znakovmi pozicemi). V souasnosti
je de facto i de iure standaidem znakova sada Unicode, kteia v nejnovji podob
(veize e.1) obsahuje 11c 1s1 znak. Tento standaid popisuje vlastnosti jednotli-
vch znak (diuh znaku nap. pasmeno, islice, matematick symbol, mezeiov
znak, apod.), vztahy mezi nimi (nap. identitu, zamnitelnost, apod.) a dopoiu-
uje i jejich giack znazoinni (to se vak me i dosti viazn liit v iznch
fontech).
Objekty tidy System.Char (zkiacen ar, z anglickho chaiactei znak) bohu-
el nepokivaji celou znakovou sadu Unicode, ale jen jeji ast oznaovanou jako
BMP (Basic Multilingual Plane). Ta obsahuje jen znaky, jejich kod lei v iozsahu
ceI (tj. mohou bt intein uloeny ve z bytech). Natsti tato sada obsahu-
je vechna abecedni pisma a bn symboly vetn matematickch a dokonce i
vechny bn pouivan insk znaky.
Poznmka:
Pistup k ostatnim Unicode znakm je mon pomoci tzv. nahiadnich
dvojznak (surrogate pair). Zpiacovani se vak viazn zkomplikuje
a vyuivano je jen v nkteich specializovanch aplikacich. Standaid
Unicode vak obsahuje i dali obtin paitie, na n mete naiazit pi
tvoib tzv. inteinacionalizovanch aplikaci, piem o dan pioble-
matice existuje jen malo liteiatuiy a kvalitnich zdioj.
Zakladni objektov model C= :
Objekt tidy ar vytvoime pomoci znakovho liteialu, co je v nejjednoduim
pipad samotn znak uzaven v apostiofech nap. a, (znak mezeiy), nebo
(omikion s ostim pizvukem a jemnm pidechem).
Tento zpsob je vak nepioblematick pouze u bnch latinkovch (anglickch)
pismen, islic a bnch symbol (vetn mezeiy). U ostatnich znak naiazime na
dva pioblmy (vtinou na oba zaiove)
inteipietace pimo vloench znak, je se nachazeji mimo ASCll znako-
vou sadu, zavisi na tom, v jakm kodovani uloime zdiojov souboi ( text
piogiamu). Pokud je stejn jako kodovani oekavan pekladaem, pak ma-
me asten vyhiano, nebo vstup piogiamu obsahuje oekavan znaky.
Bohuel to me bt jen dili vitzstvi, nebo poleme-li piogiam jinmu
piogiamatoiovi (v jin zemi i pio jin OS), me snadno dojit k neshod
(a vstupem jsou podivn, asto insk znaky). Pioto se bu snaime ja-
kchkoliv ne ASCll znak vyvaiovat, nebo pouit standaidni penositeln
kodovani UTl-s.
nktei znaky nelze v liteialu pimo pouit (odadkovani, apostiof, zptn
lomitko), iespektive jsou sice pipustn, ale nejdou jednodue vloit pomoci
klavesnice (u esk klavesnice nap. ve uveden omikion). Navic me bt
pioblm i s jejich zobiazenim (font v piogiamatoiskm editoiu jej nemusi
podpoiovat).
Oba pioblmy lze snadno obejit pomoci tzv. nikovch (escape) sekvenci, kte-
i zainaji znakem zptnho lomitka. Nejobecnji jsou nikov sekvence tvaiu
\uXXXX (kde X je libovolna estnactkova islice tj. c-v, a,b,c,d,e,f). Pomoci tto
sekvence lze vloit libovoln znak ze znakov sady Unicode BMP, pomoci jeho
kodu ( pozice v tabulce znakov sady, angl. codepoint). Kody jednotlivch zna-
k lze nalzt napiklad na stiankach konsoicia Unicode (nejpehlednji je foima
tabulek http://www.unicode.org/charts/).
Pio nktei netisknuteln (a obtin vloiteln) znaky z ASCll tabulky existuji
specialni nikov sekvence. V piaxi je nutn znat jenom escape sekvenci \n vy-
jadujici znak odadkovani a \t, co je znak tabulatoiu (tyto znaky se hodi nap.
pio foimatovani vstupu) a pedevim nikov sekvence pio apostiof \ a zptn
lomitko \\ (tyto znaky v liteialu jinak nelze zapsat).
Piklady znakovch liteial
'\u0158' (znak ),
'\u03A8' (znak ),
:
'\u000A' '\n' (znak odadkovani),
'\\' (zptn lomitko),
'\'' (apostiof)
chybn zapisy liteial
'\' (nedokonen liteial, chybi koncov apostiof),
'', 'ab' (v apostiofech musi bt piav jeden znak),
''' (apostiof uvnit musi bt zapsan jako nikova sekvence),
'\uFFFF' (neplatn Unicode znak)
Vtina piogiamovacich jazyk podpoiuje i objekty, ktei v sob uchovavaji cel
text tj. posloupnost znak. Objekty tohoto typu se ji nepamti (tj. cca od ioku
1vc) nazvaji etzce (angl. string). etzce mohou obsahovat tm libovoln
poet znak (od nuly do z
Iz
1).
Vpiogiamu lze etzce zapsat pomoci etzcovch liteialu sekvence znak v uvo-
zovkach. Znaky se zapisuji stejn jako u znakovch liteial vetn monosti vyu-
iti nikovch sekvenci. Pio zapis uvozovky uvnit liteialu je mono pouit ni-
kovou sekvenci \.
Piklady etzcovch liteial
"Gandalf"
"" / / jednoznakov etzec obsahujici mezeiu
"\u2C0D\u2C1F\u2C10\u2C21\u2C07\u2C20" / / dekodovani je domaci kol
"" / / piazdn etzec
"\"\"" / / etzec obsahujici dv uvozovky
2.1.3. Logick hodnoty
Posledni kliovou tidou jazyka C= je tida, jejimi instancemi (exemplai) jsou
pouze dva objekty oznaovan liteialy true a false. Objekt true symbolizuje piav-
du (piavdiv vsledek, piavdivou podminku, piavdiv pedpoklad), objekt false
nepiavdu (nepiavdivou podminku, vsledek, pedpoklad apod.)
Tida ma foimalni jmno System.Bool (lze psat zkiacen i bool). Toto podivn jm-
no (te se bu:l) je zkiatkou anglickho slova boolean (boolovsk), jim se oznauji
hodnoty foimalnimlogiky vytvoen matematikemGeorgemBoolem(ovemv ne-
foimalni podob znam ji mnohem mnohem dive).
Zakladni objektov model C= :
2.1.4. asov okamiky
Nezanedbatelna ast modeinich aplikaci piacuje s kalendanimi daty a asem.
Nejsou to jen izn kalendae a kolovniky, ale i etni aplikace, webov poi-
taly i hiy.
V .NlT jsou pio iepiesentaci asu vyuivany objekty standaidni tidy System.-
DateTime. Tyto objekty dokai iepiesentovat asov daj v iiokm iozsahu od
plnoci 1.1. ioku jedna p.K. do plnoci I1.1z vvvv s pesnosti, kteia dostauje pio
vtinu bnch aplikaci (1cc ns).
Poznmka:
Mapovani asovho daje na skuten asov okamik je ponkud
pioblematick. Objekt podpoiuje jen asten mechanismus asovch
pasem a jen jedin kalendani systm giegoiiansk (1.1. ioku jedna
se nov iok opiavdu neslavil). Pio data v iozsahu cca 1vcc a z1cc lze
pedpokladat cca minutovou pesnost (pokud je pouivana asova osa
bez pestupnch hodin vazana na iotaci Zem nap. UTC nebo UT1).
Kiatkodob (v iozsahu msic) je pesnost iepiesentace sekundova
(chyba me vzniknout vloenim pestupn sekundy, jen neni ob-
jekty DateTime podpoiovana). Detaily viz nap. http://en.wikipedia.
org/wiki/Coordinated_Universal_Time a http://en.wikipedia.org/wiki/Leap_
second.
Pio objekty asovch daj neexistuje v C= adn pim liteial a je nutno je vy-
tvaet pomoci tzv. volani konstiuktoiu
new System.DateTime(2012, 8, 9)
Zapis zaina kliovm slovem new za nim nasleduje jmno tidy a seznam pa-
iameti, ktei uiuji poateni stav objektu (zde je to nap. uieni konkitniho
asovho okamiku). V naem pipad je vytvoen objekt iepiesentujici plnoc
dne v.s zc1z.
Kiom konstiuktoiu se temi celoiselnmi paiametiy (iok, msic, den) existuje i
konstiuktoi se esti paiametiy umoujici uiit i okamik v pibhu danho dne
new System.DateTime(2012, 8, 9, 1, 37, 52)
/ / objekt iepiesentujici v.s. zc1z c1Iz
Mn piaktick je konstiuktoi s jednim paiametiem umoujicim zadat as jako
poet 1cc ns tik od poateniho data (1.1. 1 n.l).
:e
new DateTime(600000000000000000)
/ / objekt iepiesentujici Ic.1.1vcz 1c1ccc
Otzka: Paiameti konstiuktoiu v pedchozim pipad neni objekt tidy int. Pio`
Konstiuktoiy jsou nejobecnjim piostedkem pio vytvaeni objekt a v budouc-
nu se s nimi mnohokiat setkame (a blieji seznamime).
2.2. Interakce s objekty
Objekty OOP jazyk stejn jako objekty model iealnho svta mohou ieagovat
na podnty z okoli, mnit sv stavy nebo vytvaet nov objekty. Zakladni objekty
jsou velmi jednoduch a tudi i inteiakce s nimi je velmi jednoducha. Navic vech-
ny zakladni objekty jsou nemnn tj. nikdy nemni svj stav a to vetn instanci
tid string a System.DateTime.
2.2.1. Dotazovn na vlastnosti objekt
Nejjednoduim typem inteiakci s objekty jsou dotazy na jejich stav. Napiklad
etzec dokae viatit svou dlku tj. poet znak.
"Frodo".Length
Tento zapis v jazyce C= mete inteipietovat tak, e se ptame objektu tidy string
(iepiesentujici text liodo) na jeho vlastnost Length (dlka). Objekt ieaguje tak,
e vytvoi nov iseln objekt (tidy int) s poadovanou infoimaci. V naem pi-
pad je to tedy objekt iepiesentujici islo .
Obecn zapis pio zjitni vlastnosti objektu ma tedy tvai
objekt.Vlastnost
Vimnte se, e jmno vlastnosti zaina velkm pismenem (veizalkou). To sice
neni povinn (peklada to nekontioluje), ale je to bn zus, ktei by se ml
dodiovat. Rozhodn je dsledn dodiovan u vech tid standaidni objektov
knihovny, co je souboi tid, ktei jsou dostupn v kad instalaci .NlT a tvoi
zaklad vech .NlT piogiam.
Anglick teimin pio vlastnosti objekt je property.
Zakladni objektov model C= :,
2.2.2. Metody
Pokud vyadujeme od objektu naionji innost tj. bu zmnu stavu nebo vznik
novho objektu, ktei neni vyjadenim pouh dili vlastnosti objektu, zavolame
nad objektem tzv. metodu.
Metodu meme povaovat za hlavni piostedek inteiakce s objektem, za pokyn
aby objekt vykonal njakou (pesn denovanou) innost.
Metoda je vdy volana nad jednim konkitnim objektem (budeme jej dale ozna-
ovat jako adiesata metody), me vak mit jako paiametiy dali objekty, ktei
vsledek metody ovlivni.
Piklady
"Bilbo".Contains("B")
testuje zda objekt adiesat (zde je objekt tidy string tj. etzec Bilbo) obsahuje ja-
ko svou souast (pod)etzec B. Vsledkemje nov objekt tidy bool. Zde je to sa-
mozejm objekt true. Podobn je piavda vsledkemvolani "Bilbo".Contains("bo")
a dokonce i volani "Bilbo".Contains(""), nebo piazdn etzec je foimaln obsa-
en v kadm podetzci.
Poznmka:
Vyhledavani piazdnho podetzce se me jevit jako zcela okiajova
a tudi zanedbatelna monost (kdo kdy chce hledat piazdn pode-
tzec`). V piaxi vak vyhledavan etzec neni zadan pimo v pio-
giamu, ale uivatelem (nap. pomoci vstupniho pole v giack nebo
WWW aplikaci). Pokud napiklad vytvoime aplikaci pio telefonni
seznam a pouijeme metodu Contains pio vyhledavani jmen (Za-
dejte st jmna, a my vyhledme vena jmna, kter tento podet-
zec obsahuj ), pak piazdn vstupni pole pio vyhledavaci etzec vede
k vpisu vech jmen (vechna jmna obsahuji piazdn podetzec).
To se sice me jevit jako iozumn, ale neni tomu tak. Hiozi zahlceni
datovho pipojeni, nebo vsledek me mit nkolik MiB a ty nejsou
nap. datovm ioamingu zadaimo. Viazn to tak usnaduje zcizeni
dat.
Pio udieni kosmick iovnovahy jet nkolik pouiti metody Contains, ktei
viaceji nepiavdu
"Frodo".Contains("f") iozliuji se mala a velka pismena
:8
"Frodo".Contains("oo") podetzec musi bt v adiesatovi obsaen souvisle
Navic je nutno dodiovat poadovan tidy objekt (zde musi bt adiesat i paia-
meti objektem tidy stiing)
"Frodo".Contains('F') tento poadavek se me jevit jako iozumn, nebo lze
uvaovat, e znak (objekt tidy chai) je obsaen v etzci. Knihovna .NlT to vak
neumouje a dovoluje testovat jen pitomnost podetzc. Peklada tak oznami
chybu ji pi pekladu a nedovoli piogiam ani peloit (tj. ani jej nespustite).
Toto omezeni vak lze snadno obejit zapisem "Frodo".Contains("F"), ktei testuje,
zda je v etzci obsaen jednoznakov podetzec (tj. ponkud jin objekt, ktei
vak me v tomto kontextu znak zastoupit).
"1645".Contains(48) tento poadavek vak ji iozumn neni, nebo nema valn
smysl hledat v etzci islo. islo toti me bt iepiesentovano tm nekonen
mnoha texty. Me bt uvedeno v jin soustav (nap. jako Ic v estnactkov)
nebo islicemi jinch kultui (nap. jako XLVlll) nebo dokonce slovy.
Pioto se ani v tomto pipad nepodai piogiam peloit. Poita Vam tak dava
najevo, e jste zadali poadavek, kteimu neiozumi iesp. kteimu ani neme
iozumt.
eeni zavisi na tom co jste vlastn chtli. Pokud jste jen chtli najit vskyt dvou
znak islic v danm poadi, je eeni snadn. Jako paiameti pouijte pislun
dvojznakov etzec (tj. liteial v uvozovkach) tj. "1645".Contains("48"). Pokud jste
skuten mysleli islo (nap. v piogiamu, ktei hleda vskyt xni ceny v iamci
obchodnich smluv i piavnich dokument), musite napsat vlastni metodu, kteia
se vypoada se vemi Vaimi poadavky (nap. na jazyk dokumentu, foimatovani
apod.). Napsat kvalitni kod teba jen pio etinu vak neni tak snadn (a iozhodn
nevhodn pio zaateniky).
Pravidlo 6: Pi aplikaci metod a vlastnost je teba vnovat pozornost td objek-
tu adresta a tdm objekt ve funkci parametr (tj. tdm ve interagujc
objekt). Nkter kombinace nejsou vbec ppustn, nkter mohou vst k rznm
podivnm vsledkm.
Pipadem miin sloitji aplikace metody je nahiada podetzc
"tta".Replace("t", "m")
Vsledkem volani je nov etzec ( objekt tidy stiing), v nm jsou vechny
vskyty podetzce t (pivni paiameti) nahiazeny znakem m (diuh paiameti)
Zakladni objektov model C= :,
tj. etzec mama. Ostatni zastnn objekty-etzce (tata, t a m se nem-
ni).
Volani metod viacejicich nov objekty lze etzit. Metody jsou v tomto pipad
volany zleva dopiava
"Gandalf".Replace("an", "e").Replace("d","r").Replace("f", "t")
Pivni volani metody Replace vytvoi nov etzec Gedalf. Na tento nov et-
zec je volana metoda Replace s paiametiy d a i. Vsledkem je nov etzec
Geialf. Na ten je opt aplikovana metoda pio nahiadu podetzc, je vytvoi
cilov etzec Geialt.
Cel pioces je znazoinn na schmatu z.z na nasledujici stian. Vimnte si, e
i tak ielativn jednoduch inteiakce se astni deset iznch objekt (vechny
jsou tidy string).
Metodu Replace lze volat jen na objekty tidy string, nikoliv na isla nebo logick
hodnoty. Dvodem je skutenost, e objekty ostatnich nam znamch tid, nemaji
adnou vnitni stiuktuiu, kteia by mohla bt (asten) nahiazena.
Chybn poadavky 102.Replace("2``, "3") (islo neni posloupnost znak islic,
to je jen vnji iepiesentace), true.Replace("t", "") (logicka hodnota tak neni
etzcem znak).
lxistuji vak i metody, ktei lze volat nad objekty (tm) vech typ. Je to napi-
klad metoda ToString, kteia viaci bnou textovou iepiesentaci kadho objektu
(tj. text, ktei pokud mono jednoznan popisuje dan objekt). Vsledn objekt
je pouze vnji iepiesentaci, nikoliv samotnm objektem i jeho kopii (vjimkou
jsou samotn objekty tidy string).
2.ToString() / / z
/ / islo z je iepiesentovano textem s jedinou islici
0.0000002.ToString();
/ / zl-c (foimat isla se me zmnit opioti liteialu)
true.ToString()
/ / Tiue (piavdiva hodnota me bt iepiesentovana textem Tiue)
"Gondor".ToString()
/ / Gondoi (viati stejn text, a s nejvti piavdpodobnostni i stejn objekt)
(new DateTime(2013,1,5)).ToString()
/ / .1.zc1I ccccc
o
Gandalf
an
an
e
e
Replace
(dost o nhradu
podetzc)
parametry (dosti)
adrest (dosti)
reakce adresta
vytvoen novho o!"ektu tdy string
Gedalf
d
d
r
r
Replace
(dost o nhradu
podetzc)
parametry (dosti)
meziv#sledek
adrest (dosti)
reakce adresta
vytvoen novho o!"ektu tdy string
Geralf
f
f
t
t
Replace
(dost o nhradu
podetzc)
parametry (dosti)
meziv#sledek
adrest (dosti)
reakce adresta
vytvoen novho o!"ektu tdy string
Geralt
Geralt
vsledn objekt
Obiazek z.z. Zetzen volani metody
Zakladni objektov model C= 1
2.2.3. Operace
Pio objektov jazyky je typick volani metod ve tvaiu adrest.metoda(parametry)
(misto teky me bt v jinch jazycich odlin oddlova nap. dvojznak -~,
apod). Tento foimat volani ma dv vhody
adiesat je uveden jako pivni a je jasn oddlen od paiameti. To odpovida i
vtin piiozench jazyk, kde je adiesat tak bn uveden na zaatku a-
dosti nebo poadavku na innost (Pete, ukli to s poadim adiesat, pikaz
a paiameti to).
volani metody lze snadno etzit (nap. 123.ToString().Length)
Vnkteich specickch pipadech vak tento foimat volani neni optimalni. Tka
se to pedevim matematickch viaz, kde se bn pouivaji izn opeiatoiy
(opertor symbol vyjadujici opeiaci, typicky umistn mezi dvma hodnotami).
V ist objektovm jazyce by napiklad vpoet hodnoty z*(-1) mohl mit tvai
2.Vynasob(5.Pricti(1)), nebo z objektovho pohledu se jedna o adost, adiesova-
nou islu z, aby se vynasobilo s objektem-islem vzniklm aplikaci metody Pricti
na islo pt (s paiametiem 1). Vsledkem adosti je nov iseln objekt.
l kdy nktei objektov jazyky tivaji na tomto zapise (s anglickmi nazvy pi-
slunch metod), umouje vtina z nich i zapis blizk matematickmu (jen je
navic shodn s pvodnimi neobjektovmi jazyky jako Pascal i C). Z hlediska
OOP je vak pouiti opeiatoi jen zkiacenm a pehlednjim zapisem, ktei je
stale nutno inteipietovat objektov tj. jako aplikaci metod na objekty.
Binrn aritmetick opertory
Aiitmetick opeiatoiy v jazyce C= jsou v zasad beze zmn pevzaty z jazyka C.
Binaini opeiatoiy jsou vdy aplikovany na dva objekty.
operace znak priorita asociat.
sitani - 1 (nii)
odeitani - 1
nasobeni * I (vyi)
dleni / I
zbytek po dleni I
:
Posledni dva sloupce tabulky uiuji v jakm poadi se opeiatoiy vykonavaji, po-
kud se jich ve viazu vyskytuje vice. Ve valn vtin pipad se stai pamatovat,
e
opeiatoiy s vyi piioiitou se vyhodnocuji ped opeiatoiy s piioiitou nii.
Pokud jsou piioiity oznaeny iseln, pak se vtinou oznauji tak, e meni
islo vyjaduje vyi piioiitu (tj. opeiatoi s piioiitou z se vyhodnoti dive
ne opeiatoi s piioiitou I). Piioiita aiitmetickch opeiatoi je ve shod s
bnm matematickm zem.
pokud maji opeiatoiy stejnou piioiitu pak se vyhodnocuji podle tzv. aso-
ciativity bu zleva dopiava nebo zpiava doleva. Asociativita zleva dopiava
je zakladni (je ve smiu teni), opana je vjimkou.
poadi lze vdy zmnit nebo ovlivnit pomoci (kulatch) zavoiek. Zavoiky
se vak nkdy pouivaji i v pipad, kdy poadi nemni a to z dvod vyi
pehlednosti (pedevim v u sloitjich viaz nebo tehdy, kdy se stkaji
opeiatoiy, jejich ielativni piioiita neni veobecn znama).
Dlen a zbytek po dlen
Pesn vznam opeiaci dleni je dan tim, zda je opeiace aplikovana na objekty
celoiseln (tidy int), nebo s pohyblivou adovou aikou (double).
Pokud jsou oba opeiandy (tj. adiesat opeiace i paiameti) instancemi tidy int, pak
je dleni tzv. celoiselnm (oznaovano jako div) a zbytek po dleni lze vyjadit
vztahem = (), kde symbol vyjaduje celoiseln dleni, je dlenec,
dlitel a zbytek po dleni.'
Nkolik piklad
7 / 3 z ( cela ast zlomku /I)
7 % 3 1 (nebo - (I * z) 1)
-7 / 3 -z
-7 % 3 -1 (nebo - - (I * -z) - - e -1)
7 / -3 -z
7 % -3 1 (nebo - (-I * -z) - e 1)
'existuji i dali monosti denice zbytku po dleni, ktei lii pouze v pipad, e dlitel i dlenec
je zapoin. Piogiamovaci jazyky podpoiuji izn denice (tj. mohou poskytovat izn vsledky).
Pehled (s detailnim vysvtlenim pioblematiky) viz http://en.wikipedia.org/wiki/Modulo_
operation.
Zakladni objektov model C=
Celoiseln dleni se v piaxi vyuiva jen zidka (vjimkou jsou algoiitmy sou-
visejici s teoiii isel), zbytek po dleni je uitenji nap. pio testovani sudosti
i lichosti isla. Zbytek po dleni islem dva je u sudch isel samozejm c, u
lichch pak 1.
V pipad, e je alespo jeden z opeiand opeiace instanci tidy double, pak ope-
iatoi / znai bn dleni iacionalnich isel. Opeiatoi zbytku po dleni je zo-
becnn i pio iacionalni isla za pouiti stejnho vztahu jako ve.
Piklady
7.0 / 3.0 z.IIIIIIII (iepiesentace ma jen omezen poet desetinnch islic).
7.0 % 3.0 1.c (stejn jako u celch isel)
42.2 % 5 z.z (nebo 1z.z - * s z.z)
Tento zobecnn zbytek po dleni neni sice matematicky zcela koei, ale pio klad-
n opeiandy je v nkteich pipadech velmi uiten. Napiklad jej lze pouit pio
piavu obecnho hlu tak, aby leel v iozsahu c a Iec stup (nebo c a z).
456.25 % 360.0 ve.z
8 % (2*3.1416) 1.1es
Unrn aritmetick opertory
Kiom binainich opeiatoi existuji i opeiatoiy unaini tj. opeiatoiy aplikovan
na jedin objekt (jen je z objektovho adiesatem opeiatoiu-metody).
Zakladnim unainim aiitmetickm opeiatoiem je unaini minus, ktei viaci nov
iseln objekt s opanou hodnotou (pvodni objekt se nemni!)
-2 (zde je vak znak - souasti iselnho liteialu nikoliv opeiatoi, funkce je vak
obdobna)
-"x".Length je -1 (nejdive se ziska vlastnost Length etzce, co je objekt tidy int,
na nj se aplikuje unaini minus)
loimaln existuje i opeiatoi unaini plus, ten vak pouze viaci svj opeiand (iesp.
jeho kopii) a v piaxi se s nimpiavdpodobn vbec nesetkate. Me se vak objevit
v (po)chybnch zapisech nebo uebnicovch pikladech.
vimnte si, e znak - ma v jazyce C= nkolik vznamu je to binaini i unaini opeiatoi a tak me
bt pimou souasti iselnch liteial
1
- pivni pivek posloupnosti (vektoiu, n-tice)
V piogiamovacim jazyce nelze pouit dolni index, ale pouivaji se nahiadni zapi-
sy. V C= (a C, C++, Jav, Pythonu, PHP, atd.) se indexy zapisuji pomoci specialniho
opeiatoiu hianatch zavoiek.
e
"Frodo"[3]
Tento zapis vyjaduje volani opeiatoiu indexace na etzcov objekt. V C= se in-
dexuje od nuly tj. index I indexuje tvit pivek (pivni ma index c, diuh index z,
atd). etzec je posloupnost znak tj. jeho pivky jsou objekty tidy ar. Vsled-
kem indexaniho viazu je tedy objekt ar:d (tvit znak). Vizualni znazoinni
viz obiazek z.I.
F r o d o
0 1 2 3 4 -1 5
indexy
Obiazek z.I. lndexace v etzci
Pokud pouijeme index mimo meze, v naem pipad napiklad zapis
"Frodo"[5]
(tj. pistup k estmu znaku v ptiznakovmetzce) dojde k vjimen situaci, co
vede k pedasnmu ukoneni piogiamu se zpiavou System.IndexOutOfRange-
Exception: Array index is out of range (zaizeni , na nm je zpiava vypsana zavisi
na kontextu, nejastji to bva chybov okno)
Pravidlo 7: etzce a dal tzv. indexovateln kolekce jsou indexovny od nuly a
posledn prvek m index length-1.
O nco piaktitji piklad a dali pokus o vysvtleni OnZOVaV
"abcdefghijklmnopqrstuvwxyz"[3].ToString() + "abcdefghijklmnopqrstuvwxyz"[1]
Otazkou neni, jak je konen vsledek (co je vtinou snadn), ale jak opeiace
a metody se vykonavaji (a v jakm poadi), iesp. jak objekty pi tom vznikaji a
zanikaji. Dobi piogiamatoi to ve musi detailn znat.
2.3. Tdn metody a vlastnosti
Objektov piogiamovani je zameno pedevim na objekty a inteiakce mezi ni-
mi. Tidy hiaji jen pomocnou (i kdy dleitou) ioli. l tidy vak mohou mit vlast-
Odpov na Zakladni Otazku ivota, Vesmiiu a vbec
Zakladni objektov model C= ,
nosti a dokonce i metody. Pikladem jsou vlastnosti viacejici zajimav objekty
tidy, infoimace o vech instancich iesp. metody vytvaejici nov instance (kdy
ji liteialy a konstiuktoiy nestai).
V nkteich piogiamovacich jazycich (nap. v Pythonu nebo Ruby) lze tidy cha-
pat jako specialni objekty (iepiesentujici tidu jako takovou). V .NlT vak tidy
nejsou objekty a dokonce nejsou za bhu aplikace pitomny v pamti .
Natsti lze alespo foimaln volat metody nad tidami a ziskavat tidni vlast-
nosti. Tidni metody a vlastnosti se z histoiickch dvod oznauji jako stati
(angl. static).
Statick (tj. tidni) vlastnosti se pouivaji podobn jako vlastnosti nad objekty
(oznaovan jako instanni). Jen namisto objektu je ped tekou uvedena tida
(iesp. jeji identikatoi).
int.MaxValue
Tato vlastnost tidy int viaci objekt obsahujici nejvti iepiesentovateln islo tj.
z111sIe1 ( z
I1
1). Vimnte si, e vlevo od teky je jmno tidy nikoliv objekt.
Podobn existuje i vlastnost int.MinValue (viacejici -z111sIe1s). Stejn pojme-
novan vlastnosti existuji i u ostatnich iselnch tid (nap. double.MaxValue) a
jinch uspoadanch mnoin vetn bool, ar a System.DateTime.
Dleitou ioli hiaji statick vlastnosti u tidy DateTime, nebo jen pomoci nich
lze ziskat objekty iepiesentujici aktualni asov okamik ( systmov as) iesp.
plnoc aktualniho dne (kliov pio kalendani vpoty)
DateTime.Now / / aktualni asov okamik (nap. s.s.zc1z 1s11)
DateTime.Today / / plnoc aktualniho dne (nap. s.s.zc1z ccccc)
Mezi zakladni statick metody pati ty, ktei pevadji etzcovou iepiesentaci
hodnoty na pislun objekt (tj. jsou do jist miiy inveizni k metod ToString()).
Tyto metody se ve svmidentikatoiu obsahuji slovo parse ( piovst syntaktick
iozboi).
int.Parse("42") / / objekt int1z
dvodem je vyuiti kliovho slova static, pevzat z jazyka C--. Piimainim vznamem je uloeni
ve statick oblast pamti, tj. oblasti pamti, kteia se alokuje ji pi sputni piogiamu a jeji iozsah
se pot nemni (situace v C= je ponkud jina, ale i zde jsou staticka data uloena ve specialni oblasti
pamti).
8
Paiametiem metody je objekt etzce, vsledkem je nov objekt, jen je instanci
tidy, ji staticka metoda pati. Vimnte si, e si metoda dokae poiadit s peby-
tenmi mezeiami ped a za islicemi. Bohuel tim jeji inteligence koni
int.Parse("42000")
/ / skoni s chybou (vjimkou)
/ / System.loimatlxception lnput stiing was not in the coiiect foimat
Podobn skoni pokus o pevedeni textu, je obsahuje libovoln neiseln a ne-
mezeiov znak (pipustn je jen znak minus nebo plus ped pivni islici).
Metodu Parse podpoiuji vechny iseln tidy (vetn double), tida bool (ioze-
znava etzce tiue a false bez ohledu na velikost pismen tj. nap. i Tiue nebo
dokonce tiue).
Ponkud sloitji je situace u tidy DateTime. Jeji metoda DateTime.Parse ioze-
znava zapis v lSO foimatu (nap. zc1z-1z-z1) a ve foimatu aktualnich jazyko-
vch vlastnosti (tj. nap. pokud je nastavena etina, pak iozezna napiklad et-
zec z1.1z.zc1z). Pokud chcete nastavit i denni as dopoiuuji lSOfoimat (funguje
vdy a vude)
DateTime.Parse("2008-10-12T12:00")
Je vak podpoiovano i mistni nastaveni (funguje jen v esk iepublice a blizkm
okoli)
DateTime.Parse("24.12.200812:00")
2.4. Promnn
Piomnn (angl. variable) umouji pidlit objektm jmna, co viazn usnad-
uje manipulaci s objekty. Piomnn si meme pedstavit jako pojmenovan
schianky, ktei obsahuji bu pimo objekt nebo jednoznan odkaz na nj.
Jako piklad z iealnho ivota, lze uvst napiklad identikaci neznamch zviat
kupikladu koek. Pokud je chceme identikovat, pak mame v zasad dv mo-
nosti
Pivni monosti je vytvoit klece se jmny, do nich jednotliv koky zaveme (tj.
pojmenovana schianka obsahuje pimo objekty s nimi piacujeme). Tento pistup
samozejm funguje, ale ma dv nevhody
Zakladni objektov model C= ,
jedna se o tiani koek (co je vak pio OOP objekty natsti iielevantni)
pokud chceme identikovat nehomogenni skupinu (nap. libovolnch ivo-
ich) je obtin vytvoit univeizalni klece (nap. pio pivoky i plejtvaky)
Diuhou monosti je vytvoit pojmenovan schianky (nap. popsan obalky), v
ni je pouze jednoznan odkaz na objekt (nap. fotogiae koky, jeji DNA otisk
apod.) Tento pistup je sice ponkud komplikovanji je vak univeizalnji (a
tak levnji!).
Podobn, pokud si chce policie jednoznan pojmenovat auto, pak lze sice uvao-
vat gaia, v nich dan auto uzave (a na dvee vyvsi SPZ), ale levnji je vedeni
iegistiu, v nm je pod jmnem auta (SPZ) jeho jednoznana identikace (popis,
islo motoiu, apod.). Navic se tim nebiani v uivani auta (vytvoeni duplikatu je
pili asov i nann naion).
Podobn i u objekt je astji pipad, kdy piomnna obsahuje pouze odkaz na
objekt (tj. nap. jeho adiesu v pamti). Vhodou je exibilita (piomnna me
odkazovat i na objekty iznch velikosti), monost sdileni (objekt me bt od-
kazovan iznmi jmny a tak vyuivan ve vice kontextech) a spoia pamti (co
vyplva z monosti sdileni).
Pim uloeni je vhodn pouze pio velmi jednoduch objekty, u nich je mona a
snadna duplikace (vytvoeni identickch kopii). To plati nap. pio iseln objek-
ty, ktei jsou velmi mal (v pamti asto zaujimaji meni misto, ne by zaujimal
odkaz) a je mono vytvaet identick kopie.
V jazyce C= lze pioto tidy iozdlit na hodnotov a referenn. Objekty hodnoto-
vch tid jsou ukladany pimo do piomnnch. Mezi hodnotov tidy pati vech-
ny iseln typy (int, double a dali, ktei jet nezname), znakov a logick typ.
Refeienni tidou je i tida System.DateTime (intein je to jednoducha iselna hod-
nota).
Objekty iefeiennich tid jsou z piomnnch pouze odkazovany (tj. nejsou v pio-
mnnch pimo uloeny). Mezi iefeienni tidy pati valna vtina ostatnich tid,
i kdy piozatim zname jednu jedinou iefeienni tidu string.
Rozdil mezi iefeiennimi a hodnotovmi tidami se piojevuje ji v okamiku vy-
tvaeni piomnnch.
o
2.4.1. Definice a inicializace promnnch
Abychom mohli piomnnou pouivat, musime ji nejdive vytvoit. Zapis, ktei
piomnnou vytvai se nazva denice promnn.
Denice piomnn ma zakladni tvai
identifiktor-tdy tda identifiktor-promnn = vraz-vracejc-inicializan-
objekt,
ldentikatoi tidy specikuje objekty, ktei lze do piomnn ukladat, identikatoi
( nazev) pak jednoznan identikuje piomnnou a tim nepimo i objekt v ni
uloen.
Vtina piogiamovacich jazyk omezuje pipustn foimat identikatoi piomn-
nch. Nkteia omezeni jsou povinna (tj. musi bt dodiena jinak se piogiam ne-
peloi), jina jsou pouze dopoiuenimi (ktei byste vak mli dodiovat)
povinn omezen: identikatoi musi zainat pismenem ( znak, ktei je v Uni-
code oznaen jako pismeno) a me pokiaovat bu pismeny nebo islice-
mi (tzv. alfanumeiick znaky). V identikatoiech je mono pouivat i znak
podtiitko, ale v C= jej iadji nepouivejte. Tato omezeni plati v zasad pio
vtinu bnch piogiamovacich jazyk (PHP, Java, C, Python apod.)
doporuen: identikatoi by ml zainat malm pismenem a pokud je viceslov-
n pak by kad slovo (kiom pivniho) mlo zainat velkm pismenem.
Obecn je vhodnji pouivat pouze anglickou abecedu (a euioaiabsk isli-
ce). Nepouivejte iadji zkiatky (pokud nejsou zaveden nap. HTML nebo
HTTP je samozejm OK, zapisuji se vak spie ve tvaiu Html a Hp)
Piklady platnch (a dopoiuenihodnch) identikatoi piomnnch
pocetPrvku, optimalniDopravniProstredek, aktualniUzelSite, currentNetNode, ma-
ximum, seznamObrazku, gureList
Vytvoeni piomnn pak piobiha ve dvou fazich. Pibh tchto fazi se lii podle
toho, je-li tida piomnn hodnotova nebo iefeienni (tj. zda-li piomnna bude
obsahovat objekt i jen odkaz na nj)
Definice a inicializace promnnch pro objekty hodnotovch td
U hodnotovch tid je nejdive alokovano misto pio piomnnou. Toto misto je
vynulovano tj. obsahuje jen nulov byty. Do takto alokovanho mista se zkopiiuje
inicializani objekt (byte po bytu).
Zakladni objektov model C= 1
Vsledkem je pamov misto, je je inicializovano kopii inicializaniho objektu.
Nikdy tak neme vzniknout piazdna piomnna i piomnna s nedenovanou
hodnotou! Cel pioces si mete piohldnout na obiazku z.1.1 na pedchozi stia-
n.
inicializan
objekt
inicializan
objekt
uloen
objekt
definice a inicializace promnn hodnotov tdy
nov inicializovan promnn
nulov
objekt
koprovn
alokace
inicializace
Obiazek z.1. Denice a inicializace piomnn pio objekty hodnotovch tid
Piklad
int velikost = 5;
Tato denice vytvoi piomnnou se jmnem (identikatoiem) velikost. Nejdive
se v pamti vyhiadi misto pio objekt o velikosti 1 byt (co je velikost objekt
tidy int). Toto misto obsahuje nejdive nulov objekt (objekt tvoen nulovmi
byty), ten je vak ihned pepsan kopii inicializaniho objektu (zde je to objekt isla
).
Dali piklady denici piomnnch
double x = 2 * 3.14; / / sloitji inicializani objekt objekt, jen je vsledkem nasobeni
double y = x / 2;
char koncovyZnak = 'q';
bool vysledek = true;
DateTime konecSveta = new DateTime(2012, 12, 21);
lnicializani ast denice je nepovinna. Pokud neni inicializace pouita, je pio-
mnna inicializovana nulovm objektem (tj. je piovedena jen alokani ast) z ob-
iazku z.1. l v tomto pipad je piomnna inicializovana a vznikne nov objekt.
:
Nulov objekt iepiesentuje u iselnch tid nulu, u tidy bool objekt false (tiochu
pesimistick pohled na svt). U ostatnich hodnotovch tid me bt inteipietace
sloitji.
int pocet; / / piomnna obsahuje objekt c
double p; / / piomnna obsahuje objekt c.c
char zeroChar;
Posledni piomnna obsahuje po denici znak s kodem c. Tento znak je idici a
nema giackou iepiesentaci (iozhodn to neni znak c!). lxplicitn lze tento znak
napsat nap. pomoci nikov sekvence \ucccc nebo \c).
DateTime pocatek; / / nejmeni iepiesentovateln datum 1.1.ioku 1 ccc
l kdy jazyk C= denice bez explicitni inicializace pipouti (tj. neni to chyba pi
pekladu), je pouiti explicitni denice vdy pehlednji a bezpenji. To plati i
v pipad, e je piomnna inicializovana nulovm objektem.
Pravidlo 8: Promnn by mla bt v rmci denice vdy explicitn inicializovna.
Definice a inicializace promnnch pro objekty referennch td
Zapis denice tchto piomnnch se nelii, smantika je vak jina.
V pivni (alokani) fazi se v pamti vytvoi misto pio piazdn odkaz na objekt
(alokovan misto je vdy stejn velk, 1 nebo s byt podle toho, zda je systm Iz
nebo e1 bitov). Nasledn se do uloi odkaz na inicializani objekt (tj. jeho adiesa
v pamti). Nedochazi k adnmu kopiiovani a nevznika adn nov objekt (me
vak bt vytvoen v inicializanim viaze). Pioces je znazoinn na obiazku z. na
nasledujici stian.
string buh = "Mithra";
Zde se nejdive vytvoi nov objekt tidy string (v inicializanim viaze, jen ma
podobu liteialu). Pak se vytvoi piomnna (se jmnem buh) a vloi se do ni
odkaz na dive vytvoen etzcov objekt.
lnicializace piomnnch vak me bt i sloitji
string slabika = "bar";
string slovo = slabika;
string vystup = slovo + "" + slabika + slabika;
Zakladni objektov model C=
definice a inicializace promnn referenn tdy
inicializan
objekt
inicializan
objekt
odkaz na
objekt
przdn
odkaz
nov inicializovan promnn
alokace
inicializace
Obiazek z.. Denice a inicializace piomnn pio objekty iefeienni tidy
l v tomto pipad se nejdive vytvoi nov etzcov objekt (s textem bai). Od-
kazemna tento objekt je inicializovana piomnna slabika. Nasledn je tento odkaz
(nikoliv objekt!) zkopiiovan do nov denovan piomnn slovo. Ob piomnn
tak od tto chvile odkazuji na stejn objekt.
Posledni piomnna (vstup) je inicializovana odkazem na objekt, ktei vznikne in-
teiakci hned nkolika objekt. Nejdive je vytvoen doasn objekt, jen obsahuje
etzec tvoen jedinou mezeiou. Ten je nasledn paiametiem opeiace (metody),
kteia spojuje dva etzce. Adiesatem ( pivnim opeiandem) opeiace/metody je
objekt odkazovan piomnnou slovo. Vsledkem je nov etzec (s textem bai).
Tento objekt vstupuje do nov opeiace zetzeni a je spojen s objektem na nj
odkazuje piomnna slabika (co je jak ji vime stejn objekt jako u piomnn slo-
vo). To ve se jet jednou opakuje. linalnim vsledkem inicializaniho viazu je
nakonec objekt s etzcembai baibai. Na tento objekt zane ukazovat piomnna
vstup. Giack znazoinni naleznete na obiazku z.e na nasledujici stian.
Vimnte si, e i kdy v pibhu vykonavani ve uvedenho fiagmentu kodu
vznikne celkem est objekt, jen dva z nich jsou po ukoneni piovadni odkazo-
vany z piomnn (iesp. pesnji z alespo jedn piomnn). Jen tyto dva objek-
ty budou dostupn ve zbytku piogiamu. Ostatni ji nejsou poteba a mohou bt
uvolnny z pamti.
Pozoinji tenai si mona vimli, e o nco ve byl uveden podivn teimin
piazdn odkaz a nebyl naleit vysvtlen. Nyni se vak k nmu viatime.
uvolnni se vak nepiovede hned, ale a v okamiku, kdy dojde pam
.
(dvojita negace)
( )
.
(De Moiganv zakon)
( )
.
(De Moiganv zakon)
Poznmka:
V jazyce C= jsou vechny ielani opeiatoiy jen syntaktickou zkiat-
kou za volani metody CompareTo. Tu maji vechny tidy, u nich je
poiovnani denovano (foimaln musi implementovat iozhiani ICom-
parable).
Tato metoda viaci nulu, pokud neni adiesat metody ani vti ani men-
i (tj. je z hlediska poiovnavani ekvivalentni shodn z hlediska iov-
nostii). Je-li adiesat vti ne paiameti metody, pak metoda viaci
kladn (nenulov) islo. V opanm pipad (paiameti je vti ne
v nkteich specialnich pipadech vak mohou bt dva objekty ekvivalentni z hlediska poiovnani,
pesto vak nemusi bt shodn z hlediska iovnosti. Tato situace neni natsti pili asta.
8:
adiesat) je samozejm viaceno islo zapoin (tomuto stylu poiov-
navani se bn ika trojcestn porovnn ).
if(x.CompareTo(y) > 0 && t.CompareTo(x) <= 0)
je ekvivalentni podmince
if(x > y && t <= x)
Metoda CompareTo se pimo vyuiva jen zidka (ale napiklad v ge-
neiickm kodu je nezbytnosti)
Vjimen situace
Podminku ji mame a nyni musime piodiskutovat ieakci na chybn vstup. Nej-
jednoduim eenim je pedasn ukoneni piogiamu. Tento pistup znate i z
ivota zadali mi patn daje (patn pikazy, koly), nebudu iadji nic dlat.
Tato ieakce je v mnoha pipadech dostatena, mla by vak zahinovat pedani
infoimace o dvodech pedasnho ukoneni, tj. v naem pipad stiun text
popisujici dvod ukoneni iesp. i iadu jak data zadat spiavn.
Samozejm lze uvaovat i dali sloitji eeni nap. adost o nov zadani, pouiti
implicitni hodnoty apod.
Tim vim se vak piogiam me viazn zkomplikovat. Je to tim hoii, e do-
daten kod ei situaci, kteia je spie vjimenou (uivatel v zajmu piaktick
vyuitelnosti piogiamu budou zadavat pedevim platn vstupy). Navic, pokud
chceme na kod pouit v iznch aplikacich, mohou se poadavky na eeni liit
(nap. u WWW aplikace neni pedasn ukoneni iozumnm eenim).
Nejjednodui a zaiove nejlepi ieakci na vznik vjimen situace, je tzv. akti-
vace (hovoiov vyhozeni!) vjimky (angl. exception). Aktivace vjimky situaci
ve skutenosti neei. V zasad jen oznamuje, e vznikla vjimena situace, s ni
si nevime iady a doplnime tuto infoimaci o kiatk infoimani text. Piogiam je
doasn pozastaven a je hledan specialni kod, ktei na vjimku ieaguje a me
vjimenou situaci vyeit (tento kod me bt ve velmi vzdalen asti piogiamu
i dokonce v jin knihovn). Pokud neni nalezen, je piogiam ukonen s vypsanim
infoimaniho textu, co je, jak ji vime, tak eeni.
Pio aktivaci vjimky budeme pouivat nasledujici kod
throw new Exception("informativntext");
Konzolov piogiamy 8
Zatim nemusime pesn iozumt smantice tohoto viazu (vimnte si vak ale-
spo, e jadiem je vznik novho objektu tidy System.Exception). Stai znate jen
vsledek, ukoneni piogiamu a (nepovinn) vypsani infoimaniho textu.
Mechanismus vjimek je bn vyuivan i ve standaidni knihovn. Vjimka je
aktivovana pi paisovani nevalidniho etzce (nap. pokud v nm neni uloeno
islo), pouiti chybnho indexu, nepipustnm petypovani, volani metody nad
null hodnotou, apod. (uvedeny jsou piklady, na n jste ji mona naiazili)
=
Nyni ji mame ve pipiaveno pio implementaci cel vstupni asti piogiamu
int rok = int.Parse(Console.ReadLine());
if (rok < 2001 || rok > 2029) {
throw new Exception("Rokmimopodporovanmeze(2001-2029)");
}
3.4.2. Zpracovn dat
Pi eeni algoiitmickch pioblm je obas mono vychazet z bnch postu-
p, ktei by pio eeni zvolil bn lovk (tj, neinfoimatik, nematematik). Ten
by (doufam) vzal kalenda pislunho ioku, zaal by ho postupn piochazet od
1. ledna. Do kolonky pivniho piacovniho dne by napsal islo 1, do diuhho z a tak
dale a do konce ioku. Jen by si musel dat pozoi, aby peskoil vechny vikendy a
pedevimsvatky (co je ielativn snadn v pipad, e voln dny jsou v kalendai
jasn oznaeny). Po skoneni by posledni zapsan islo (v poslednim piacovnim
dnu) mlo vyjadovat poet piacovnich dni.
Nyni stai algoiitmus pefoimulovat do objektov pioceduialni podoby. Zakla-
dem je objekt tidy System.DateTime iepiesentujici konkitni kalendani datum.
Objekty tidy System.DateTime sice iepiesentuji asov okamik (kdekoliv v iam-
ci dne), ale mohou iepiesentovat i kalendani dny (nap. tim, e zlomky dne budou
nulov tj. den je iepiesentovan okamikem plnoci, ji zaina).
Vhodou tto iepiesentace je skutenost, e objekt DateTime obsahuje i zaklad-
ni kalendani vlastnosti a metody. Nejdleitji vlastnosti je DayOWeek, jen
umouje zjistit den v tdnu (tj. odliit soboty a nedle). Nejdleitji metodou
je metoda void AddDays(int n), kteia viaci nov datum o dn pozdji. Tida
System.DateTime bohuel nepodpoiuje statni svatky. Hlavnim dvodem je jejich
piostoiova a asova omezenost (statni svatky plati je v jedn zemi a pedevim i v
8
tto zemi se obas mni). Pioto budeme muset navihnout dali algoiitmus, ktei
umoni otestovat zda je pislun den svatkemi nikoliv (tento algoiitmus se hodi
i v jinch piogiamech) a napiogiamovat ji tak, aby se snadno pouivala.
Objekt tidy System.DateTime iepiesentujici 1. leden poadovanho ioku lze zis-
kat pomoci (tipaiametiickho konstiuktoiu), tento objekt nasledn uloime do
piomnn den (System.DateTime je hodnotova tida).
DateTime den = new DateTime(rok, 1, 1);
V konstiuktoiu jsou pouity dva objekty tidy int zadan liteialem (jsou vdy
iovny jedn), posledni je ji uloen ve vstupni piomnn rok.
Dale si pipiavime diuhou piomnnou, kteia bude uchovavat postupn iostouci
poet piacovnich. Tato piomnna bude tidy int a nazveme ji poetPracovnDn.
Na zaatku je tato piomnna iovna nule (podle piavidla vak pouijeme explicitni
inicializaci)
int pocetPracovnchDnu = 0;
Piomnn pio ukladani objekt ji mame pipiaveny, take meme nastinit cen-
tialni ast piogiamu (vlastnost JePracovni jet neni implementovana, ale ped-
pokladame, e bizy bude)
if( den.JePracovni ) {
pocetPracovnichDnu = pocetPracovnichDnu + 1; / / zvime ita potu piac. dn
}
den = den.AddDays(1); / / pesuneme s na dali den v ioce (z.1)
if( den.JePracovni ) {
pocetPracovnichDnu = pocetPracovnichDnu + 1; / / zvime ita potu piac. dn
}
den = den.AddDays(1); / / pesuneme s na dali den v ioce (I.1)
/ / a podobn pio dalich IeI dn (Ie1 v pestupnm ioce)
Stiuktuia piogiamu je spiavna, piogiam by vak byl zbyten dlouh (1*Ie a-
dek). Samozejm je mon pouit oblibenou kombinaci Ctil-C, Ctil-V, ale i to je
dost obtin. Navic plati dali (a zasadni) piogiamatoisk piavidlo
Pravidlo 11 Programtor nepouv klvesy Ctrl+C a Ctrl+V a to ani na vlastn
kd.
Pio by nemli piogiamatoi pouivat tak uiten funkce textovch editoi (vet-
n nejlepich vvojovch piostedi). Dvodem je konzistence kodu. Pedstavte si,
Konzolov piogiamy 8
e iozkopiiujete ast kodu na nkolik dalich mist. Pak v pvodnim textu najdete
chybu i ho miin ioziite. To vak bohuel znamena, e stejnou zmnu musite
aplikovat ve vech kopiich a to konzistentn. l zde sice mete pouit kopiiovani
a vloeni, ale je to sloitji a nachyln k chybam (asto napiklad zapomenete
opiavit jednu i vice kopii).
Natsti ve vtin pipad existuje mnohem jednodui eeni ne iozkopiiovani
i iuni opakovani. V naem pipad je to pouiti cyklu. Zname ji cyklus forea,
ale v tomto pipad je vhodnji vyuit nejobecnji cyklus while.
Cyklus while
Cyklus while naleznete tm ve vech pioceduialnich jazycich, piem jeho syn-
taxe a smantika se tm nelii. V C= ma tento tvai
while(podmnka) {
/ / tlo-cyklu
}
Zakladni smantika cyklu while je jednoducha. Nejdive je vyhodnocena pod-
minka (co musi bt viaz viacejici objekt tidy bool). Je-li podminka piavdiva
( objekt true), je vykonano tlo cyklu tj. pikazy uvnit bloku. To ve je obdo-
ba konstiukce if. U cyklu se vak po piovedeni tla znovu testuje podminka. Je-li
piavdiva, je opt vykonano tlo cyklu. Opakovani je ukonen a v okamiku, kdy
se podminka stane nepiavdivou.
Je zejm, e cyklus while pedpoklada, e uvnit tla se njak zmni objekty, ktei
jsou vyuivany v podmince cyklu, nebo jinak by byla podminka stale piavdiva a
cyklus by tak byl nekonen.
Specialnim pipadem je situace, kdy podminka neni splnna ani pi pivnim tes-
tovani. Tlo cyklu se v tomto pipad nepiovede ani jednou.
=
Pomoci cyklu while lze tlo naeho piogiamu nastinit takto (stale jet chybi im-
plementace vlastnosti JePracovni, fiagment tvoi tlo metody Main tidy MainC-
lass)
int rok = int.Parse(Console.ReadLine());
if (rok < 2001 || rok > 2029) {
8e
throw new Exception("Rokmimopodporovanmeze(2001-2029)");
}
int pocetPracovnichDnu = 0;
DateTime den = new DateTime (rok, 1, 1);
DateTime silvestr = new DateTime (rok, 12, 31);
while (den <= silvestr) {
if (den.JePracovni) { / / opakovana innost
pocetPracovnichDnu = pocetPracovnichDnu + 1;
}
den = den.AddDays (1); / / posun na dali den
}
Console.WriteLine (pocetPracovnichDnu);
Jadiem cyklu je podminka, kteia testuje, zda je postupn posouvan den stale
obsaen v pislunmioce. Piotoe poateni hodnota dne je 1. ledna a v tle cyklu
se vdy posune na nasledujici den, postauje testovat zda je aktualni den (tj. objekt
aktualn uloen v piomnn den) stale ped silvestiempislunho ioku iesp. zda
to neni silvesti sam (silvesti je samozejm souasti pislunho ioku a me bt
piacovnim dnem). Pio tento el je vyuita ielace meni nebo iovno mezi dvma
objekty tidy System.DateTime. Je zejm, e objekt tidy DateTime je meni ne
jin objekt DateTime, piav tehdy, kdy iepiesentuje divji as.
Vimnte si, e hianini objekt (iepiesentace silvestiu) je vytvoen ji ped cyklem
a uloen do piomnn. Timto je eliminovano zbyten vytvaeni novho objektu
pi kadm(opakovanm) vyhodnoceni podminky (tj. v kadmopakovani cyklu)
Na konci tla cyklu by mla bt vdy pipiavena pda pio dali testovani pod-
minky a pipadn dali piovedeni tla cyklu. V naem pipad je objekt uloen v
piomnn den nahiazen novm objektem iepiesentujicim nasledujici den. Objekt
tedy neni sam zmnn, ale je nahiazen novm objektem (dvodem je skutenost
e objekty tidy DateTime jsou vdy nemnn).
3.4.3. Roziujc metoda JePracovn()
Nyni pozoinost pesuneme k implementace vlastnosti JePracovn objekt tidy
System.DateTime. Tato vlastnost by mla viacet objekt true, je-li adiesat vlastnosti
ve skutenosti je to zbyten, nebo peklada C= je dostaten inteligentni, aby sam poznal, e
hianini objekt je nutno vytvoit jen jednou (pi tzv. optimalizaci). S pouitim pomocn piomnn
je vak piogiam dle mho nazoiu pehlednji.
Konzolov piogiamy 8,
piacovni den (adiesat je objekt, jeho vlastnost je zjiovana), v opanm pipad
pak objekt false.
Tuto vlastnost budeme implementovat jako ioziujici metodu. To bohuel zna-
mena, e pi volani budeme muset pouivat nadbyten kulat zavoiky tj. namisto
den.JePracovni bude nutno psat den.JePracovni(). Natsti je to jen diobn syntak-
tick detail.
Nejdive vytvoime pivni zkuebni veizi ioziujici metody. Tato veize bude bez
ohledu na adiesata metody ( objekt tidy DateTime iepiesentujici testovan den)
viacet objekt true (tj. jako by byly vechny dny piacovni). To sice neodpovida
poadovan smantice, ale lze tak snadno otestovat zda ji hotov asti piogiamu
funguji.
public static bool JePracovni (this DateTime den) {
return true;
}
Pokud ji mame hotov hlavni piogiam (vetn tidy MainClass a metody Main) a
impoitovan jmenn piostoi System, lze piogiam peloit a spustit. Pokud zadame
nepestupn iok (nap. zc11), pak by ml vypsat Ie (Ie dn bylo oznaeno jako
piacovnich) u pestupnch (nap. zc1z) hodnotu Ie1.
Pi vytvaeni sloitjich aplikaci je vhodn tzv. inkiementalni testovani, tj. pi-
bn ovovani zda ji hotov asti funguji. Pokud se pi dalim ioziovani pio-
giamu objevi chyba je velmi piavdpodobn, e nastala v pidan asti (a tudi se
snadnji hleda). Napiklad v naem pipad, mame oveno, e hodnota ioku byla
dobe petena a cyklus pioel vechny dny ioku. Oven je samozejm i vpis
vsledn hodnoty (ten je vak tiivialni).
Nyni ji meme pistoupit ke skutenmu oveni, zda je dan den piacovni, tj.
k vytvaeni tla ioziujici metody JePracovni.
Pi implementaci budeme vychazet z piincipu postupn detekce dn, ktei nejsou
piacovni. Zbvajici dny pak budou samozejm piacovnimi.
Nejsnadnji se detekuji soboty a nedle
if(den.DayOfWeek == DayOfWeek.Saturday ||
den.DayOfWeek == DayOfWeek.Sunday) {
return false; / / meme hned viatit, e nejsou piacovni
}
return true; / / ostatni jsou piacovni
88
Vlastnost DayOWeek viaci objekt tidy DayOWeek. Vimnte si, e se tida jme-
nuje stejn jako vlastnost. V C= je to bn a nevadi to, nebo podle kontextu je
vdy jasn zda myslime vlastnost nebo tidu.
Tida DayOWeek ma pouze sedm instanci (tj. objekt, ktei do ni pati). Ka-
d iepiesentuje jeden den v tdnu. Jednotliv objekty lze ziskat zapisem DayO-
Week.JmnoDne (jmno dne je samozejm anglicky a zaina velkm pismenem).
Tento zapis se pouiva u tzv. vtovch tid (zkiacen vt), u nich existuje
jen omezen poet instanci, z nich kadou lze vyjadit jednoznanm identika-
toiem. Obecn zapis je JmnoTdy.JmnoObjektu (tj. DayOWeek je zde jmnem
tidy nikoliv metody).
Podminku lze tudi inteipietovat takto
1. nejdive je volana vlastnost DayOWeek, kteia viati objekt tidy DayOWeek
z. tento objekt poiovnan s objektemDayOWeek.Saturday (co je jeden ze sed-
mi objekt tidy DayOWeek)
I. je-li poiovnani spn (tj. testovan den je sobota), je podminka splnna
a metoda viaci objekt false (den neni piacovni), diuha podminka nemusi
bt testovana, nebo pio platnost sloen podminky s opeiatoiem nebo (oi)
stai platnost jen jedn dili podminky
1. je-li poiovnani nespn (objekt neni objektem DayOWeek.Saturday tj.
den neni sobota), je opt volana vlastnost DayOWeek
. viacen objekt je poiovnan s objektem DayOWeek.Sunday (iepiesentuje
nedli)
e. pokud je poiovnani spn (objekty jsou shodn), je podminka splnna a
metoda viaci false (i nedle neni piacovnim dnem)
. pokud jsou ob podminky nepiavdiv, je den oznaen jako piacovni (zatim
neeime svatky)
Piogiamopt meme opt spustit a zjistit kolik je v danmioce dn mimo soboty
a nedle (pio iok zc1z mi vylo ze1).
Nyni budeme eit dny, ktei nejsou vikendovmi, ale zaiove nejsou dny piacov-
nimi (tj. svatky). Vechny svatky kiom velikononiho pondli lze identikovat
pomoci dne v msici (co je cel islo v iozsahu 1..I1) a islem msice (v iozsahu
1..1z).
Aby byla testovaci podminka o nco kiati, uloime si islo dne v msici a islo
msice do piomnnch s kiatkmi identikatoiy
Konzolov piogiamy 8,
int d = den.Day; / / den v msici
int m = den.Month; / / msic jako islo
Nyni ji meme zapsat podminku, kteia testuje zda je dan datumsvatkem(ovem
stale bez testovani velikononiho pondli)
if (m == 1 && d == 1 || / / Nov iok
m == 5 && (d == 1 || d == 8) || / / kvtnov svatky
m == 7 && (d == 5 || d == 6) || / / eivencov svatky
(m == 9 || m == 10) && d == 28 || / / sv Vaclav a Vznik SR
m == 11 && d == 17 || / / Den boje za svobodu a demokiacii
m == 12 && (d > 23 && d < 27) / / Vanoce
) {
return false; / / svatek
}
Tato podminka je tiochu sloitji, ale mla by bt snadno pochopitelna. Je opti-
malizovana pio esk svatky, vyuivajic nktei spolen vlastnosti svatk (dva
svatky v msici, dva svatky zs. a souvisl ti dny vanoc). Tato optimalizace sice
zkiacuje podminku, je vak obtin penositelna pio jin staty.
3.4.4. Vsledn program
Piotoe naim kolem je pouze zjitni potu piacovnich dn v ioce, mame ho-
tovo. Velikononi pondli nemusime zjiovat, nebo je vdy v pondli (a zaiove
neme bt adn jin svatek). Stai tedy od zjitnho potu dn odeist jedni-
ku.
Vsledn piogiam ma nasledujici tvai (valnou vtinu pouitho kodu jsme ji
uvedli)
using System; / / piacovnidny.c
static class DateTimeExtensions
{
public static bool JePracovni (this DateTime den)
{
if (den.DayOfWeek == DayOfWeek.Saturday ||
den.DayOfWeek == DayOfWeek.Sunday) {
return false; / / vikend
}
,o
int d = den.Day; / / den v msici
int m = den.Month; / / msic jako islo
if (m == 1 && d == 1 || / / Nov iok
m == 5 && (d == 1 || d == 8) || / / kvtnov svatky
m == 7 && (d == 5 || d == 6) || / / eivencov svatky
(m == 9 || m == 10) && d == 28 || / / sv Vaclav a Vznik SR
m == 11 && d == 17 || / / Den boje za svobodu a demokiacii
m == 12 && (d > 23 && d < 27) / / Vanoce
) {
return false; / / svatek
}
/ / TODO velikononi pondli
return true; / / piacovni den
}
}
class MainClass
{
public static void Main (string[] args)
{
int rok = int.Parse (Console.ReadLine ());
if (rok < 2001 || rok > 2029) {
throw new Exception ("Rokmimopodporovanmeze(2001-2029)");
}
int pocetPracovnichDnu = 0;
DateTime den = new DateTime (rok, 1, 1);
DateTime silvestr = new DateTime (rok, 12, 31);
while (den <= silvestr) {
if (den.JePracovni ()) { / / opakovana innost
pocetPracovnichDnu = pocetPracovnichDnu + 1;
}
den = den.AddDays (1); / / posun na dali den
}
pocetPracovnichDnu--; / / odeteme den za velikononi pondli
Console.WriteLine (pocetPracovnichDnu);
}
}
Konzolov piogiamy ,1
3.4.5. Profesionln rozen
Ve uveden piogiam piodukuje spiavn vsledky (iozhodn pio podpoiovan
iozhiani iok a za pedpokladu, e zakonodaici nezmni poet svatk). Ma vak
nkolik nevhod
1. nedokonen oeteni velikonoc (to se natsti diky pinavmu tiiku ne-
piojevuje, ale metoda JePracovni neviaci spiavn vsledek)
z. kod soustedn v metod MainClass.Main neni pouiteln v jin aplikaci
(nap. webovm planovacim kalendai)
I. testovani validity ioku je v hlavnim piogiamu, nikoliv v metod, kteia je
na validit ioku pimo zavisla (tj, metod JPracovni, kteia je pouitelna jen
v danm iozmezi)
Nejjednodui je eeni velikonoc. l kdy je algoiitmus vpotu velikononiho
pondli ielativn sloit, existuje na lnteinetu velk mnostvi ji existujiciho ko-
du, ktei stai jen zkopiiovat a miin upiavit (zkuste v Googlu dotaz eastei C=).
Zvolilo jsem hned pivni odkaz a upiavil jej do podoby ioziujici metody (a upia-
vil jmna piomnnch, kteia nesplovala stylistick poadavky). Metoda sice vy-
poitava velikononi nedli, ale to nam nevadi, nebo pondli je vdy nasledujici
den. Vimnte si, e v poznamce je uveden pvodni zdioj. Piogiamov kod je du-
evni vlastnictvi, a pioto je nutno dodiovat zakladni piavidla pi jeho kopiiovani
(tj. je-li veejn, ml by bt uveden minimaln jeho zdioj).
/ / pevzato a miin upiaveno
/ / z http://www.geekpedia.com/code68_Find-Easter-Sunday-of-any-year.html
public static DateTime VelikonocniNedeleRoku(this DateTime dayInYear)
{
int year = dayInYear.Year;
int a = year % 19;
int b = year / 100;
int c = year % 100;
int d = b / 4;
int e = b % 4;
int f = (b + 8) / 25;
int g = (b - f + 1) / 3;
int h = (19 * a + b - d - g + 15) % 30;
int i = c / 4;
int k= c % 4;
int L = (32 + 2 * e + 2 * i - h - k) % 7;
,:
int m = (a + 11 * h + 22 * L) / 451;
int month = (h + L - 7 * m + 114) / 31;
int day = ((h + L - 7 * m + 114) % 31) + 1;
DateTime dtEasterSunday = new DateTime (year, month, day);
return dtEasterSunday;
}
Uvnit ioziujici metody pak pidame nasledujici adky (po kontiole xnich svat-
k)
if ((m == 3 || m == 4) && den == den.VelikonocniNedeleRoku().AddDays(1))
{
return false; / / velikononi pondli
}
V zasad by staila jen podminka den == den.VelikonocniNedeleRoku ().AddDays
(1) (tj. testovan den je iovn dnu, jen je o jeden den pozdji ne velikononi
nedle ve stejnmioce jako testovan den). Je vak zbyten testovat vechny dny,
piotoe velikononi pondli me bt pouze v beznu a dubnu (pesnji mezi zI.I
a ze.1 vetn).
eeni diuhho pioblmu nepouitelnosti kodu pio vpoet potu dn v jinch
aplikacich, je sloitji. Aby byl kod opakovan pouiteln musi bt implemen-
tovan jako metoda (i obecn jako funkce, ale my myslime objektov). Otazkou
vak do jak tidy tuto metodu zaadime.
l kdy je toti kod volan nad celm islem (letopotem), neni vhodn jej imple-
mentovat jako ioziujici metodu tidy int. Objekty tidy int iepiesentuji isla bez
dodaten smantiky (tj. nikoliv letopoty, min jednotky, poty osob). Vechny
metody, by mly iespektovat tuto neutialitu.
Mezi pipustn metody tak kiom bnch aiitmetickch opeiaci pati nap. ist
matematick metody jako nap. JePrvoslo, NejmenSpolenDlitel a podobn.
Nepipustn jsou naopak metody JePestupn (islo neni pestupn, pouze iok v
nkteim z kalenda), DostatenKvrum (islo neni kvoium), JeZdanno (zdan-
no neni islo, ale zboi s danou cenou).
Metoda testujici poet piacovnich dn, by vak mohla bt metodou tidy Sys-
tem.DateTime. Z celho asovho daje by vak vyuivala jen infoimaci o ioce.
To je sice mon, avak nepili efektivni (zanedba se daj o msici, dnu, hodin,
minut a sekundach).
Konzolov piogiamy ,
Natsti existuje zajimav zobecnni, ktei mnohem lpe vyuiva potencialu ob-
jekt tidy System.DateTime. Je to metoda, kteia viaci poet piacovnich dn mezi
dvma libovolnmi daty vetn (v podpoiovanmiozmezi). Poet piacovnich dn
v ioce lze pomoci tto mnohemuniveizalnji metody snadno spoitat (je to poet
piacovnich dn mezi novm iokem a silvestiem danho ioku).
Signatuia tto univeizalnji pojat ioziujici metody bude nasledujici
int PracovniDnyDo (this DateTime pocatecniDatum, DateTime koncoveDatum)
Poateni datum bude metod pedavano jako adiesat metody (je oznaeno kli-
ovm slovem this), diuh jako paiameti metody. Z pohledu OOP se tedy ptame
jistho asovho daje (adiesat), kolik je piacovnich dn mezi nim a diuhm da-
tem (paiametiem).
Piklady obecnho pouiti
DateTime.Today.PracovniDnyDo(new DateTime(2012,12,21))
Viaci poet piacovnich dn do konce svta. Pokud (zaziakem) svt peije (ove-
no peil) a vy pot spustite piogiam pak viati vdy c (adn dny nezbvaji, tim
mn piacovni)
DateTime.Today.PracovniDnyDo(DateTime.Today)
Toto volani viaci hodnotu 1 pokud je dnes piacovni den jinak nulu. Pio testovani
zda je den piacovni je mnohem lepi vyuit nami ji implementovanou metodu
JePracovni tj. zapis DateTime.Today.JePracovni(). Pouiti zbyten sloit metody
pio jednoduchou innost je oznaovana idiomem kanon na viabce.
Kod tto ioziujici metody, je zaloen na pvodnim kodu metody Main. Mni
se pouze specikace poateniho a koncovho data. Ty ji nejsou odvozeny ze
zadanho ioku, ale jsou pouity paiametiy iozien metody.
Pio spoiu uveme iovnou cel kod s novou ioziujici metodou, kteia je vyuita
v novm hlavni metod
using System; / / pracdny2.cs
static class DateTimeExtensions
{
public static DateTime VelikonocniNedeleRoku(this DateTime dayInYear)
{
/ / viz stiana v1
,
}
public static bool JePracovni (this DateTime den)
{
if (den.Year < 2001 || den.Year > 2029) {
throw new Exception ("Rokmimopodporovanmeze(2001-2029)");
}
if (den.DayOfWeek == DayOfWeek.Saturday ||
den.DayOfWeek == DayOfWeek.Sunday) {
return false; / / vikend
}
int d = den.Day; / / den v msici
int m = den.Month; / / msic jako islo
if (m == 1 && d == 1 || / / Nov iok
m == 5 && (d == 1 || d == 8) || / / kvtnov svatky
m == 7 && (d == 5 || d == 6) || / / eivencov svatky
(m == 9 || m == 10) && d == 28 || / / sv Vaclav a Vznik SR
m == 11 && d == 17 || / / Den boje za svobodu a demokiacii
m == 12 && (d > 23 && d < 27) / / Vanoce
) {
return false; / / svatek
}
if ((m == 3 || m == 4) &&
den == den.VelikonocniNedeleRoku ().AddDays (1)) {
return false; / / velikononi pondli
}
return true;
}
public static int PracovniDnyDo (this DateTime pocatecniDatum,
DateTime koncoveDatum)
{
int pocetPracovnichDnu = 0;
DateTime den = pocatecniDatum;
while (den <= koncoveDatum) {
if (den.JePracovni ()) { / / opakovana innost
pocetPracovnichDnu = pocetPracovnichDnu + 1;
}
den = den.AddDays (1); / / posun na dali den
Konzolov piogiamy ,
}
return pocetPracovnichDnu;
}
}
class MainClass
{
public static void Main (string[] args)
{
int rok = int.Parse (Console.ReadLine ());
DateTime novyRok = new DateTime (rok, 1, 1);
DateTime silvestr = new DateTime (rok, 12, 31);
Console.WriteLine (novyRok.PracovniDnyDo (silvestr));
}
}
Piogiam zaiove ei i posledni pioblm, chybn umistni testu validity ioku.
Tento test je pesunut na zaatek ioziujici metody JePracovni, kam pati. Vjim-
ka tak bude vyvolana i v pipad, e ioziujici metoda bude pouita i v dalich
aplikacich (tyto aplikace se musi nasledn postaiat o jeji eeni).
Vimnte si tak, e hlavni metoda ma po piav jen tyi adky kodu. Navic polo-
vina tohoto kodu ei vstup daje a vstup vsledku, tj. innost, kteiou nemohou
piovadt univeizalni metody (ty musi bt pouiteln nap. i v GUl a webovch
aplikacich).
4. Seznam zkladn kolekce
Teimin kolekce oznauje objekty, ktei sloui pio ukladani jinch objekt (al-
teinativni teimin je kontejner). Modeini jazyky nabizeji velk mnostvi iznch
kolekci, ktei se lii zpsobem identikace objekt v kolekci a nabidkou optima-
lizovanch metod pio pistup ke kolekci.
Nazvoslovi jednotlivch kolekci neni bohuel sjednoceno a to ani v anglitin, tj.
stejn teimin me oznaovat izn kolekce (s diametialn odlinou chaiakte-
iistikou). Pioto je nutn alespo iamcov znat i datov stiuktuiy pouivan pio
implementaci kolekci. V pipad datovch stiuktui je nazvoslovi mnohem sjed-
nocenji a ve vtin pipad i piegnantnji.
Jet ne zanme popisovat nejbnji typy kolekci, musime pozoinost vno-
vat tzv. asymptotick sloitosti, co je uitena matematicka notace, umoujici
jednodue chaiakteiizovat asov a pamov naioky jednotlivch opeiaci nad
kolekcemi.
Asymptotick sloitost
Asymptoticka sloitost umouje chaiakteiizovat jakm zpsobem zavisi as i
pamov naioky na velikosti vstupnich dat tj. v naem pipad na potu pivk
kolekce.
Pedpokladejme napiklad, e vykonavame njakou opeiaci nad polokami
kolekce (nap. vyhledani poloky, nalezeni nejvti poloky, odstianni piostedni
poloky, apod.) s pivky. Dale pedpokladejme, e (pimin) as vykonavani
zavisi piimain na potu poloek
=
()
lunkce
po-
nkud jina (asy budou adov polovini). Navic funkce nemusi bt jednodue
v
,8
vyjaditelna pomoci polynom a jinch bn uivanch matematickch funkci
(tj. nelze ji jednodue symbolicky zapsat)
Abychomodstianili zavislost na konguiaci a zjednoduili zapis, pedpokladejme,
e existuje jina (typicky jednodui) funkce pio ni plati
1
.
z
>c
>
c
()
1
()
()
z
()
Potom meme psat, e () = (()).
Tento zapis lze peist minimaln dvma zpsoby
1. asova sloitost opeiace (funkce
a zaiove
()
[
1
}
krok.
Tlo cyklu je tak piovedeno
|
[
-kiat.
Napiklad u cyklu foi(int i11, i1cc, i-I) nabva idici piomnna hodnot 11, 11,
1, zc, zI, , vs a tlo cyklu se vykona
|
1cc11
I
[
Ic-kiat.
U zapoinho kioku je iole hoini a dolni meze zamnna
for(int i = hornMez; i > dolnMez, i-=krok)
Navic na iozdil od kladnho kioku je hoini mez do zahinuta do vytvaen po-
sloupnosti isel a dolni nikoliv. Tento cyklus ma stejn poet iteiaci, ale geneio-
vana isla jsou miin odlina
hornMez, hornMezkrok, ,hornMez
\
|
[
1
}
krok.
Seznam zakladni kolekce 11,
Ve zdanliv opanm cyklu for(int i=100; i > 11; i-=3) nabva piomnna
hodnot 1cc, v, v1, ,1e, 1I.
Pokud bychom chtli pomoci indexace piojit vechny sloky seznamu od pivni
do posledni, stai pouit zakladni tvai cyklu
for(int i=0; i < mereni.Count; i++) {
Console.WriteLine( mereni[i] ); / / vypi i-tou poloku
}
Stejnho efektu lze samozejm dosahnout i pomoci cyklu forea (viz ve). Cyk-
lus forea je navic mnohem pehlednji a stiunji (a tm stejn iychl).
V cyklu for vak lze naopak jednodue mnit hodnoty poloek seznamu
for(int i=0; i < mereni.Count; i++) {
mereni[i] = 0.0; / / vynuluje vechna meni
}
Dokonce lze snadno odkazovat sousedici poloky a nasledn je zamovat
List<int> seznam = new List<int>();
...
for(int i=0; i < seznam.Count-1; i++) {
if(seznam[i+1] < seznam[i]] {
int p = seznam[i+1]; / / zamnime
a
+1
seznam[i+1] = seznam[i];
seznam[i] = p;
}
}
To bohuel nese nebezpei mn siozumitelnch a k chybam nachylnm piogia-
mm. Napiklad u naeho fiagmentu piogiamu neni na pivni pohled zejm ko-
nen efekt. Pio pln pochopeni funkce cyklu je vhodn giack znazoinni
seznamu a (pelivm) iozboi jednotlivch elementainich kiok algoiitmu (kde
vmnu meme povaovat za elementaini kiok). Velikost seznamu zvolime co
nejmeni, piem se vak idime nasledujicim piavidlem
Pravidlo 15 (linmal is keinmal) Pi testovn algoritmu je nutno zvolit takov
vstupn data, aby se kad (klov) operace provedla alespo dvakrt.
linmal ist keinmal, k si Tom nme slov.
Co se udje jen jednou, jako by se nestalo nikdy.
118
Sm-li lovk t jen jeden ivot, je to jako by neil vbec.
Milan Kundeia, Nesnesitelna lehkost byti
To v naem pipad znamena, e musime zvolit alespo tipivkov seznam (aby
se piovedli alespo dv vmny).
Potom si peliv popieme jednotliv kioky (vyhodnoceni podminek, zmny pio-
mnnch, vmny) a iozkieslime jednotliv stavy seznamu. Seznam navic na za-
atku naplnime (nahodnmi) hodnotami. Celek by se ml podobat obiazku 1.I.
3 2 1
i=0 i+1
if(seznam[i+1] < seznam[i])
2 < 3 => vmna
2 3 1
i=1 i+1
if(seznam[i+1] < seznam[i])
1 < 3 => vmna
zatek 1.iterace
zatek 2.iterace
i++
1 < 2 (i < seznam.!"nt # 1)$ %!&m'nka c(k)" *e s%)nna
i++
2 < 2 (i < seznam.!"nt # 1)$ %!&m'nka nes%)nna$ c(k)"s k!n'
i = 0 (inicia)izace)
0 < 2 (i < seznam.!"nt # 1)$ %!&m'nka c(k)" *e s%)nna
k!nen stav 2 1 3
Obiazek 1.I. Cyklus foi, iozboi piovadni
Rozboiem obiazku snadno zjistime, e
se piovede deset elementainich opeiaci (vmnu poitame jako jedinou
opeiaci). Je navic zejm, e asova asymptoticka sloitost je lineaini (pokud
se dlka seznamu zvi o jedniku, pibudou tyi opeiace)
Seznam zakladni kolekce 11,
vechny pouit indexy jsou platn (tj. neukazuji mimo seznam). To je do-
saeno miinou modikaci pokiaovaci podminky cyklu. Misto bnho i <
seznam.Count (indexy bi od pivniho do posledniho) je pouita podminka
i < seznam.Count - 1 (indexy bi od pivniho do pedposledniho). D-
vodem, je skutenost e spolu s piochazenm pivkem odkazujeme i jeho
naslednika. Pokud bychom piochazeli i posledni pivek, byl by odkazovan i
neexistujici pivek za nim!
vsledkem piovadni je pesun nejvtiho pivku na konec seznamu. Nej-
vti pivek je vdy vymnn ze svm naslednikem a piobubla tak na konec
seznamu. To neni samo o sob zajimav (nejvti pivek, lze ziskat i snadnji)
je to vak pivni kiok k setidni seznamu. Nyni toti stai aplikovat stejn
algoiitmus na seznambez posledniho pivku, co zajisti pesun diuhho nej-
vyiho pivku na pedposledni pozici, nasledn na seznam bez poslednich
dvou pivk (teti nejvyi piobubla na teti pozici od konce) a tak dale do-
kud nam nezbude dvoupivkov seznam na zaatku (zde stai jen piohodit
pivky, pokud jsou patn uspoadany).
Tento algoiitmus tidni se nazva Bubble sort (bublinkov tidni). asto
se vyuuje na kuisech piogiamovani, nebo je snadno pochopiteln. V pia-
xi je vak pili pomal, a to jak pio mal seznamy (vyaduje pili mnoho
vmn), tak pio seznamy velk (jeho asova sloitost je (
z
)). Detaily viz
http://en.wikipedia.org/wiki/Bubble_sort.
4.1.4. Selektivn vmaz
Selektivni vmaz je navenek velmi jednoduchou opeiaci odstianni vech pivk
seznamu, ktei spluji uiitou podminku.
Piklady selektivniho vmazu zname i ze ivota (omezime se samozejm jen na
data)
vmaz souboi, ktei spluji jistou podminku (nap. jsou vti ne limit, i
jsou vlastnny neopiavnnm uivatelem)
odstianni zastaialch poloek z databaze (nap. student, ktei ji spn
ukonily studium, bvalch patel z adiesae)
odstianni evidentn chybnch daj z meni (tj. daj leicich mimo
mon i pipustn meze)
1:o
Vimnte si, e opeiace selektivniho vmazu (piomazani) se dje pimo nad sezna-
mem (databazi, souboiovm systmem, apod), ktei se jejim piovedenim zmeni,
piem odstiann poloky zmizi se systmu. Tim se lii od ltiovani, kdy jsou
ze seznamu kopiiovany poloky splujici jistou podminku (nap. v e-obchod je
zobiazeno jen levnji zboi). liltiovanimse seznam(databaze, souboiov systm,
apod.) nemni a adn poloky neopoutji systm.
My budeme pio jednoduchost piomazavat pouze iseln seznamy a budeme vy-
uivat tiivialni podminky (nap. budeme chtit odstianit vechny zapoina isla).
Je zejm, e pio selektivni vmaz musime pouit cyklus for (nikoliv forea), ne-
bo se mni pimo seznam (nikoliv objekty v nm uloen).
Zkusme nejdive algoiitmus, ktei se jevi jako pimoai a nejjednodui eeni.
Piochazejme postupn seznam (za pomoci index) a nalezen kandidaty odstia-
me pomoci metody RemoveAt (zname toti jejich index)
List<int> m = new List<int>(){5, -1, 3, -2, 6};
for(int i=0; i < m.Count; i++) { / / cyklus pes indexy vech pivk
if( m[i] < 0 ) { / / podminka vmazu
m.RemoveAt(i); / / vymaeme i-t pivek
}
}
Pokud tento fiagment vloite do piogiamu (postauje do hlavni metodyMainC-
lass.Main) a doplnite o vpis vsledn podoby seznamu (za pomoci cyklu s vpi-
sem kad poloky zvla) a nasledn peloite a spustite, tak se mete zdanliv
iadovat. Piogiam by ml vypsat jen kladn poloky (zapoin byly piomazany).
Bohuel Vae iadost je pedasna (avak nepiopadejte panice)
Pravidlo 16: Pokud V algoritmus i program funguje, neznamen to bohuel jet,
e je sprvn. Naopak asto to znamen, e jste jet neodhalily veny jeho yby.
Kde je vak chyba` Zkuste miin pozmnit testovaci seznam napiklad takto (na-
misto I je I a namisto e je e)
List<int> m = new List<int>(){5, -1, -3, -2, -6};
Po peloeni a sputni nas eka nepijemn pekvapeni, piogiam vypie , I
a e. Je to podivn. Nkteia zapoina isla byla odstianna a nkteia ne. Me
se dokonce zdat, e piogiam si njak zapamatoval pvodni podobu seznamu a
zapoina isla vypisuje, piotoe byla dive kladna (to u by byla skuten eina
magie).
Seznam zakladni kolekce 1:1
Pioblmje natsti jinde. Objevit ho lze detailnimiozboiemalgoiitmu (s vyuitim
giackho zobiazeni seznam a index), viz obiazek 1.1. Pi hodnot indexu = c
se nic zajimavho nedje, islo je kladn a tak se jen pejde na nasledujici pivek
seznamu. lndex je nyni ioven 1. Diuha poloka (m[1]) je zapoina tj. je odstianna
(viz stav vpiavo od diuh ipky). Potom je znovu zven index (=z). Tento index
vak nyni ukazuje na teti poloku zkiacenho seznamu (tj. na poloku, kteia by-
la v pvodnim seznamu a tvita tj. na hodnotu z). Poloka s hodnotou I byla
peskoena, tj. nebude u nikdy odstianna. Podobna situace nastane u posledni
poloky (pedchozi poloka je odstianna, index se tak posune a za konec sezna-
mu). Pioblm je nyni jasn, diky chyb v algoiitmu nejsou odstianny vechny
zapoin poloky, ktei jsou v souvisl sekvenci zapoinch poloek na sudch
mistech (po odstianni bezpiostedn pedchazejici poloky jsou peskoeny).
5 -1 -3 -2 -6 i = 0
if( m[0] < 0 ) -- nesplnno
i++ => i=1
if (m[1] < 0 ) -- splnno
removeAt(1)
i++ => i=2
if(m[2] < 0) -- splnno
removeAt(2)
i++ => i=3
c!l"s !on#$% ne&o'
i < m()o"nt nen$ splnno
5 -1 -3 -2 -6
5 -3 -2 -6
5 -3 -2 -6
5 -3 -6
5 -3 -6
0 1 2 3 *
Obiazek 1.1. Chybn algoiitmus selektivniho vmazu
1::
eeni je navenek velmi jednoduch. lndex budeme posouvat jen tehdy, pokud
nebyla aktualni poloka odstianna (v opanm pipad se index zdanliv posou-
va diky odstianni pivku a pesunu zbvajicich poloek vpiavo). Vlastni imple-
mentace je vak sloitji, nebo posun indexu je zajiovan inkiementaci, je je
zahinuta v cyklu foi a musi bt tudi piovedena po kad iteiaci (ne jen tehdy,
kdy se nam to hodi).
Jednou z cest je naviat k cyklu while (tam meme inkiementaci idit sami). Po-
kud chceme zachovat pouiti cyklu foi, pak je zdanliv dobim eenim eliminace
nevhodn inkiementace piotiakci tj. dekiementaci.
for (int i=0; i < m.Count; i++) {
if (m [i] < 0) {
m.RemoveAt (i);
i--; / / piotiakce
}
}
Toto eeni funguje, je vak nepehledn a ponkud extiavagantni. Pi vmazu je
index nejdive snien a bezpiostedn na to zven (ve vsledku tedy neni posu-
nut, ale to neni z piogiamu zcela zejm). Navic je naiueno jedno z piogiama-
toiskch piavidel
Pravidlo 17: Hodnota dc promnn cyklu foi, by nemla bt v tle cyklu mnna.
Jakakoliv zmna idici piomnn uvnit tla cyklu, toti naiuuje piavideln (ekvi-
distantni) kiok, ktei je pio tento cyklus typick (navic nemusi bt zejm jak a
kdy je tato piavidelnost naiuena). Po naiueni nemusi navic platit zakladni vztah
o potu iteiaci, jeho platnost viazn usnaduje kontiolu spiavnosti cyklu. Navic
v nkteich jazycich neni zmna idici piomnn vbec dovolena.
Matouci chaiaktei zmny idici piomnn, lze ilustiovat na piaktickm pikla-
d. Piavideln chod cykl for se podoba chodu ozubench koleek ve stiojich.
Zmna idici piomnn je obdobou zmny potu zub bhem otaeni ozubenho
koleka. To je sice v zasad mon, viazn to vak komplikuje a znepehleduje
konstiukci.
Nezbva tedy, ne pokiaovat v hledani spiavnho eeni (pokud vbec njak
takov existuje). Zamysleme se v em tkvi piina naeho pioblmu s indexaci.
Pi odstianni pivku se jako vedleji efekt mni indexy vech nasledujicich pivk
s seznamu. Obiazn eeno, podezavame si pod sebou vtev.
Seznam zakladni kolekce 1:
Pedstavte si, e potebujete odiznout velkou (vodoiovnou) vtev, a z piostoio-
vch dvod musite na tto vtvi pi ezani sedt. Navic budete vtev ezat po
astech (napiklad o dlce jeden meti). Na algoiitmus odpovida situaci, kdy na
zaatku sedite u kmene a eete vdy mezi kmenem a Vami. U pi pivnim ezu
se tak piojevi nepijemn vedleji efekt, vyplvajici ze zmny stavu ezan vtve
(piiovnani tiochu kulha, nebo u naeho pikladu neni naiueni zcela fatalni a
pioto se mete pokouet o ezy na dalich mistech).
Jak je spiavn eeni ezaciho pioblmu` Je zejm, e stai ezat vtve z diu-
h stiany (tj. co nejdale od kmene) a navic nikoliv mezi Vami a kmenem, ale na
diuh stian. Co z toho plyne pio na piomazavaci algoiitmus` Pi vmazu je
poteba piochazet seznam v opanm smiu (od poledniho k pivnimu pivku). Pi
odstianni pivk se posun index tka jen pivk, je nasleduji za odstiaova-
nm (ty jsou vak natsti ji zpiacovany). My v dali iteiaci postupujeme vpiavo
( k niim indexm), pesnji k pivku, jen pedchazi odstiann. Jeho index se
pi odstianni samozejm nezmnil.
for (int i=m.Count-1; i >= 0; i--) {
if (m [i] < 0) {
m.RemoveAt (i);
}
}
To je mnohem lepi eeni. Je pehledn a v tle se nemni hodnota idici piomn-
n. (avak pozoi zptn cyklus neni tak tiivialni jako pim, vimnte si mezi a
ielaniho opeiatoiu v podmince!).
S timto algoiitmem meme bt spokojeni, a na jeden meni pioblm. Jeho aso-
va sloitost je (
z
). Piovadi se toti vmaz (kde (c. 1] je podil necht-
nch pivk), piem kad vmaz ma sloitost (), piotoe vyaduje pesun
pivk na uvolnn misto. To neni tak patn, ale u vtich seznam a astjiho
piomazavani to me bt pioblm.
Pokud mate dostatek pamti mete zvolit elegantni a pitom velmi iychl eeni.
Namisto smazani pivk lze pesouvat ty peivi do novho seznamu (tj. pevst
vmaz na ltiovani). Pot stai pesmiovat odkaz z pvodniho na nov a nikdo
nic nepozna. Navic lze pouit cyklus forea (pvodni seznam se nemni, jen se
nakonec zahodi)
List<int> filteredM = new List<int>(m.Count);
/ / piazdn s kapacitou dostatenou pio vechny pivky pvodniho
foreach(int item in m) {
1:
if(item >= 0){ / / negace pvodni podminky (zachovame nezapoin)
filteredM.add(item); / / pidame do novho
}
}
m = filterM; / / pesmiujeme na nov a stai zahodime
Sloitost je pouze (), ale bohuel ne vdy lze toto eeni pouit, nebo musime
bt schopni pesmiovat odkaz (nelze jej pioto napiklad vyuit pio implementaci
ioziujici metody s postiannimefektem). Navic nutnost vyuiti dostateni pamti
nemusi bt akceptovatelna.
Poznmka:
Take stale nemame to skuten dokonal (tj. iychl, nenaion a
vdy pouiteln) eeni. To samozejm existuje, musime vak vyu-
it vestavnou metodu a syntaxi tzv. lambda viaz. Lambda viazy
nam toti umouji pedat podminku jako paiameti. Seznamime se
vak s nimi a pozdji. Ale u nyni si meme ukazat to idealni eeni
m.RemoveAll( item => item < 0);
Jak snadn, mil Watsone. Zapis item => item < 0 je lambda viaz, ie-
piesentujici funkci o jedn piomnn, kteia sloui jako vymazavaci
podminka. Zavola se na kadou poloku a pokud viati true, je po-
loka nemilosidn odstianna. asova sloitost je pouze () (podle
dokumentace).
Otazka Jak se podailo dosahnout lineaini sloitosti`
4.1.5. Piazen a duplikace
Seznamy jsou modikovateln iefeienni tidy (pivni s nimi jsme se seznami-
ly). Spojeni modikovatelnosti a odkaz pinai nkolik nepijemnch pioblm,
ktei lze natsti eliminovat, ale musite o nich vdt.
Hlavni pioblm si ukame na malm (maximaln jednoduchm) piklad
List<int> a = new List<int>();
List<int> b = a; / / a odkazuje na stejn objekt jako b
b.Add(0);
/ / vpis a c
/ / vpis b c
Seznam zakladni kolekce 1:
Pokud dobe chapete, co jsou piomnn a iefeienni tidy, je ve jasn a nepioble-
matick. Piomnna a i b odkazuji na stejn objekt-seznam a tak neni pekvapiv,
e po jejich vypsani ziskame stejn vsledek (vypisujeme dvakiat tot). Pekva-
piv to me bt pouze v pipad, pokud mate pedstavu, e a i b jsou identika-
toiy objekt (tj. ikate seznam a nebo seznam b). Pi tomto (chybnm) pohledu se
pivek pidan do seznamu a zazian objevi i v seznamu b.
Bohuel i ti, ktei chapou podstatu pioblmu, mohou bt nkdy pekvapeni. Peda-
me-li napiklad seznam do metody jako paiameti, nedojde k jeho zkopiiovani, ale
je pedan pouze odkaz. Jakakoliv zmna piovedena uvnit metody nad (zdanliv
lokalnim) seznamem se piojevi i ve volajicim kodu (pestoe metoda u davno
skonila).
Obecn plati, e kdykoliv nkomu pedame seznam (mnoinu daj), tak si nem-
eme bt jisti, e nam jej nezmni (nepida pivek, i naopak njak neodstiani).
Samozejm, dokumentace me nemnnost seznamu zaiuit, ale ne vdy je tato
infoimace explicitn zminna (v opanm pipad nezbva ne doufat).
Pokud si chcete bt jisti, e se seznamnikdo nezmni, nebo pokud nechcete sloit
kontiolovat kolik piomnnch sdili jedin seznam, pak musite seznam duplikovat
(pouiva se i teimin klonovat). Pi duplikaci se vytvoi nov objekt seznamu a do
nho se zkopiiuji vechny pivky pvodniho seznamu. Oba seznamy jsou oddlen
tj. zmna v jednom se nepiojevi v diuhm (i kdy to neplati zcela absolutn, viz
nie).
Nejjednodui monosti duplikace seznamu byla ji zminna konstiuktoi s pa-
iametiem tidy List.
List<int> c = new List<int>(a);
Piomnna c odkazuje na svou vlastni kopii seznamu s vlastnimi kopiemi objekt
(objekty hodnotovch tid zde int se kopiiuji). Jakakoliv zmna vetn zmn po-
loek se tak nepiojevi v pvodnim seznamu. Vyi bezpenost a nii psychick
zatieni piogiamatoi vak neni zadaimo. Klonovani samozejm zvyuje pam-
ov naioky (kad duplikat vyaduje alokaci dali pamti) a zpomaluje piogiam
(kopiiovani ma asovou sloitost ()).
Zajimavji situace vznikne, pokud seznam obsahuje poloky modikovatelnch
iefeiennich tid. Pio piklad si uveme seznam seznam
List<List<string>> maticeSlov =
new List<List<string>>() {
1:e
new List<string>(){"Frodo", "Bilbo"}, / / 1. adek
new List<string>(){"Gandalf", "Radagast"}}; / / z. adek
List<List<string>> duplikat
= new List<List<string>>(maticeSlov); / / duplikace
/ / pidame nov adek
duplikt.Add(new List<string>(){"Aragorn","Boromir"}); / / I. adek
/ / pidame nov sloupec
duplikt[0].Add("Samved"); / / pidani poloky do 1.adku
duplikt[1].Add("Saruman"); / / pidani poloky do z.adku
duplikt[2].Add("Faramir"); / / pidani poloky do I.adku
Nyni meme vypsat jednotliv matice (nap. pomoci dvou vnoench cykl).
Matice duplikat ma nasledujici obsah (nikoliv pekvapiv)
liodo Bilbo Samvd
Gandalf Radagast Saiuman
Aiagoin Boiomii laiamii
Podoba pvodni matice vak me bt ponkud pekvapiva
liodo Bilbo Samvd
Aiagoin Radagast Saiuman
Je zejm, e pidan adek neni sdilen (pidal se jen do duplikatu), pidan slou-
pec vak sdilen je (alespo ve sv asti). Jak k tto situaci dolo`
Nejdive se podivejme na obiazek zobiazujici poateni stav ( 1. na nasledujici
stian). Piomnna odkazuje na seznam nejvyi iovn. Ten obsahuje dvojici od-
kaz na podizen seznamy (adky). Kad z podizench objekt opt obsahuje
dva odkazy na objekty etzc. Celkov jsme tedy v iamci jedn denice vytvoili
sedm objekt (ti volani konstiuktoi pomoci new a tyi etzcov liteialy) .
Nyni seznam zduplikujeme (volanim konstiuktoiu s oiiginalnim seznamem jako
paiametiem) a odkaz na duplikat uloime do piomnn duplikt.
V tto fazi tedy mame dva seznamy, ktei vak sdileji sv poloky (seznamy jsou
iefeiennimi tidami a pi kopiiovani v iamci duplikace vnjiho seznamu se ko-
piiuji odkazy). K duplikaci podseznam a samozejm ani etzc nedojde. Stav
je zobiazen na obiazku 1.e
Seznam zakladni kolekce 1:,
0 1
maticeSlov
0 1 1
string:Frodo
0
string:Bilbo
string:Gandalf
string:Radagast
Obiazek 1.. Kopiiovani objekt s vice iovnmi odkaz (poateni stav)
0 1
maticeSlov
duplikt
0 1
0 1 1
string:Frodo
0
string:Bilbo
string:Gandalf
string:Radagast
Obiazek 1.e. Kopiiovani objekt s vice iovnmi odkaz (stav po duplikaci)
1:8
Pot pidame do seznamu, je je odkazovan piomnnou duplikat (na obiazku
umistn v dolni asti), nov pivek, v podob odkazu na nov vytvoen podse-
znam (vimnte si volani konstiuktoiu pomoci new). Tento pivek se samozejm
neobjevi v oiiginalni seznamu (a neni tudi ani sdilen). Od tto chvile jsou oba
seznamy nejen oddlen, ale i odlin, viz obiazek 1..
0 1
maticeSlov
duplikt
0 1 2
0 1 1
string:Frodo
0
string:Bilbo
string:Gandalf
string:Radagast
0 1
string:Aragorn
string:Boromir
Obiazek 1.. Kopiiovani objekt s vice iovnmi odkaz (stav po pidani adku)
Nasledn postupn pistupujeme k jednotlivm polokam duplikovanho sezna-
mu. Ten obsahuje ti podseznamy, z nich dva jsou sdilen s oiiginalnim sezna-
mem a jeden je soukiom. Do kadho objektu ( podseznamu) pidame nov
pivek ( objekt tidy string). Pivni dva se pidaji do sdilenho objektu a tak se
jejich pidani nepimo piojevi v obsahu oiiginalni matice. Teti je pidan do sou-
kiom poloky a nebude tudi sdilen. Vsledn stav je zobiazen na obiazku 1.s.
Vsledn systm obsahuje 11 dilich objekt, ktei jsou alespo asten sdileny
dvma seznamy nejvyi iovn. U takto sloitch objekt (iesp. objekt jet
sloitjich) je tk denovat identitu objekt a obtin zabianit nepijemnm
postiannim efektm.
Pravidlo 18: Nepouvejte objekty, kter sdlej s ostatnmi objekty systmu st
sv modikovateln podobjekt.
piavidlo neni absolutni, existuji situace, kdy je to naopak optimalni stav, ale tyto situace jsou jasn
Seznam zakladni kolekce 1:,
0 1
maticeSlov
duplikt
0 1 2
0 1 2 1
string:Frodo
0 2
string:Bilbo
string:Samvd
string:Gandalf
string:Radagast
string: Saruman
0 1 2
string:ragorn
string:Boromir
string: Faramit
Obiazek 1.s. Kopiiovani objekt s vice iovnmi odkaz (konen stav)
Pokud chceme toto piavidlo dodiet musime bu
pouivat pouze nemodikovateln objekty (sdileni nemodikovatelnch ob-
jekt nevadi, nikdo je toti neme zmnit a tak nikdy nevznikne adn
vedleji efekt), nebo
je nutn objekty dsledn duplikovat, piem nemusi stait kopie jedn
iovn tzv. mlka kopie [angl. shallow-copy] (tj. v naempipad je to dupli-
kace pomoci konstiuktoiu). Je nutno dsledn vyuivat tzv. hlubokou kopii
(angl. deep-copy), kdy jsou kopiiovany objekty na vech iovni (s vjimkou
nemodikovatelnch).
Vytvaeni hlubokch kopii neni zcela elementaini opeiaci. Je nutno zohlednit iz-
n typy sloench objekt, nemusi to bt jen seznamy a jin kolekce. Navic odkazy
mohou bt cyklick (nap. A odkazuje na B, B odkazuje na C a C odkazuje na A).
Z tohoto dvodu nelze napsat univeizalni kod, a hlubok kopiiovani se musi eit
ad hoc.
vymezen (nap. topologick stiuktuiy)
1o
Poznmka:
Platfoima .NlT obsahuje mechanismus tzv. serializace, co je pio-
stedek uloeni objekt (vetn sloench) do pioudu byt (nap. do
souboiu) a samozejm i deseiializace, co je konstiuovani objekt
z uloench bytovch dat. Nejjednodui implementaci hlubokho
kopiiovani je tudi seiializace a nasledna deseiializace (deseiializaci
vznika nov objekt dokonal duplikat). Seiializace vak byla vy-
tvoena pio jin ely (dlouhodob ukladani objekt v souboiech a
databazich) a neni optimalizovana pio duplikace (je nap. dosti po-
mala).
Pio na konkitni a jednoduch piklad je vak hlubok kopiiovani ielativn jed-
noduch (je nutno kopiiovat jen dv iovn, etzce jsou nemnn, a mohou tak
zstat sdileny)
List<List<string>> hlubokDuplikat =
new List<List<string>>(maticeSlov.Count);
foreach(List<string> radek in maticeSlov) {
hlubokyDuplikat.Add( new List<string>(radek) ); / / duplikat adku
}
Ukol Nakieslete si giaf objekt v pamti.
Poznmka:
Pi pouiti LlNQ a lambda viaz se ve jet zjednodui
var dupl = maticeSlov.Select(
row => new List<string>(row)).ToList();
4.2. Pklady roziujcch metod seznam
Na zavi sekce vnovan seznamm si vytvoime ti ioziuji funkce. Tyto funkce
nejsou pouze instiuktivni, ale mohly by bt i uiten. Pio jednoduchost budeme
vytvaet metody, ktei piacuji jen nad seznamy celch isel. Pouit algoiitmy
vak na tid poloek (tm) nezavisi a lze je vyuit i pio metody nad seznamy
objekt jinch tid. V poznamkach na konci podsekci si navic ukaeme eeni,
kteia podpoiuji seznamy tm libovolnch objekt, vyuivajic tzv. polymorsmu.
Seznam zakladni kolekce 11
4.2.1. Nhodn permutovn prvk v seznamu
V mnoha sofwaiovch aplikaci potebujeme imitovat nahodnost. Nejsou to jen
heini automaty, ale i izn simulace i vizualizace. Knihovny .NlT poskytuji za-
kladni geneiatoi pseudonahodnch isel, ale timjejich podpoia koni. Zcela chybi
i tak zakladni opeiace jako je nahodn piomichani pivk uiitho seznamu iesp.
foimalnji nahodna peimutace pivk uspoadan mnoiny. V anglitin se nefoi-
maln pouiva teimin (random) shuing.
Pomoci nahodnho peimutovani lze modelovat napiklad iozmistni osob v mist-
nostech nebo asovou naslednost objednavek v obchod (co je objednano jako
pivni, diuh atd.).
Pio nahodn piomichani pivk v kolekcich existuje jednoduch, ale efektivni
algoiitmus oznaovan jako Durstenfeldv algoiitmus, ktei je specialnim pi-
kladem staiiho algoiitmu Fisherova-Yatesova (viz http://en.wikipedia.org/wiki/
Fisher-Yates_shuffle).
Popis tohtoto algoiitmu pevzat z anglick Wikipedie je velmi jednoduch, neni
vak zapsan v jazyce C=, ale v tzv. algoiitmickm pseudokodu, je spojuje Pascal
a bnou anglitinu
To shuffle an array a of n elements (indices 0..n-1):
for i from n 1 downto 1 do
j random integer with 0 j i
exchange a[j] and a[i]
Po pekladu do etiny dostavame (specikace cyklu v pascalsk notaci neni pe-
loena)
Prohzen prvk n-prvkovho pole a (s indexy 0..n-1):
for i from n 1 downto 1 do
j nhodn cel slo, pro n plat 0 j i
zmna a[j] a a[i]
Je zejm, e v C= iepiesentaci tohoto algoiitmu pouijeme cyklus for, nebo do-
chazi k zamn pivk a iteiace je zptna (od posledniho pivku k pivnimu). Pio
geneiovani nahodnho isla z inteivalu [c. ] pouijeme metodu Next nad objek-
tem tidy Random (v piogiamu na ni odkazuje piomnna g). Jen si musime dat
1:
pozoi na to, e volani g.Next(a, b) viaci islo v iozsahu [. ) tj. hoini mez ne-
ni zahinuta. Pioto musime hoini mez zvit o jedniku. Pio zamnu vyuijeme
klasick algoiitmus vyuivajici pomocnou piomnnou.
for (int i = a.Count - 1; i >= 1; i--) {
int j = g.Next(0, i + 1); / / nahodn islo z inteivalu [c, i]
/ / zamna a[i] a a[j]
int p = a[i];
a[i] = a[j];
a[j] = p;
}
Abychom vak mohli algoiitmus otestovat, musime jej nejdive zahinout do ioz-
iujici metody (metoda Shue nad objektem tidy List<int>). Piotoe budeme
potebovat i vpis (piomichanho) seznamu doplnime jet jednoduchou iozi-
ujici metodu pio vpis seznamu do konzole (metodu oznaime identikatoiem
Print).
using System; / / shue.cs
using System.Collections.Generic;
static class ListExtensions {
static Random g = new Random(); / / staticka inicializace geneiatoiu
public static void Shuffle(this List<int> a) {
for (int i = a.Count - 1; i >= 1; i--) {
int j = g.Next(0, i + 1); / / nahodn islo z inteivalu [c, i]
/ / zamna a[i] a a[j]
int p = a[i];
a[i] = a[j];
a[j] = p;
}
}
public static void Print(this List<int> a) {
for (int i=0; i < a.Count; i++) { / / pio kad index seznamu
Console.Write(a[i]); / / vypi pivek
if (i < a.Count - 1) { / / neni-li pedposledni
Console.Write(","); / / vypi oddlova
}
}
Console.WriteLine(); / / a nakonec odadkuj
Seznam zakladni kolekce 1
}
}
class MainClass {
public static void Main(string[] args) {
/ / testovaci seznam
List<int> test = new List<int>(){1,2,3,4};
for (int i=0; i<48; i++) { / / 1s-kiat
test.Shuffle(); / / piomichej
test.Print(); / / a vypi
}
}
}
Nejzajimavji asti plnho piogiamu je denice piomnn g odkazujici objekt
pio geneiovani nahodnch isel. Pivotn jsem denici umistil na zaatek meto-
dy Shue. Pio kad volani piomichavaci metody se tak vytvaela nova instance
tidy Random. To nesniuje efektivitu piogiamu, nebo vytvoeni novho gene-
iatoiu je iychl a nevyaduje adn zvlatni piostedky. Piogiam fungoval, ml
vak jeden nepijemn nedostatek, obsah seznamu se pili nepiomichaval. N-
ktei kombinace se tm piavideln opakovaly a jin se naopak vbec neobjevily.
Dvodem tohoto podivnho (i kdy nikoliv zcela neoekavanho) chovani je me-
chanismus inicializace geneiatoiu. Ten toti vyaduje nastaveni jedinen poa-
teni hodnoty a v bnm poitai existuje pouze jedin univeizalni zdioj unikat-
nich isel hodiny iealnho asu. Tento zdioj neni zcela idealni, nebo se mni jen
ielativn pomalu, v adu setin sekundy. Pokud bhem tto zdanliv velmi kiatk
doby vytvoime vice geneiatoi, pak jsou vechny nastaveny stejn a poskytu-
ji stejnou posloupnost nahodnch isel. Tato situace nastala i zde, nebo dobu
piovedeni metody Shue lze vyjadit v mikiosekundach. Pivky se tudi sice pio-
michavaly, ale pokad za pouiti ti stejnch vmn. Neni divu, e se jednotliv
peimutace zaaly opakovat.
Jak jsem tento pioblm (a jeho eeni) odhalil` Pomohly mi m dlouholet zkue-
nosti, ktei vak piavdpodobn nemate. Co vak mete udlat u dnes, je pio-
studovani dokumentace. Dokumentace imy Microso neni obecn pili kvalitni,
ale tento pioblm natsti zmiuje
e default seed value is derived from the system clo and has nite resolution.
As a result, dierent Random objects that are created in close succession by a call
to the default constructor will have identical default seed values and, therefore, will
1
produce identical sets of random numbers. is problem can be avoided by using
a single Random object to generate all random numbers. ( zdioj MSDN, Random
Constructor pio .NlT 1., http://msdn.microsoft.com/en-us/library/h343ddh9.aspx).
eeni je tudi jasn, vyuiti jedinho objektu tidy Random pio vechna volani
piomichavaci metody. Zde je vyuit statick (tidni) datov len uvnit pomocn
tidy ListExtensions, ktei je inicializovan jen jednou a to ped pivnim volanim
ioziujici metody. Statickm datovm lenm budeme vnovat pozoinost poz-
dji, zde si je meme pedstavit jako piomnn, ktei existuji celou dobu vyko-
navani piogiamu (a jsou tudi jen jednou inicializovany) a ktei jsou dostupn
jen v iamci metod dan tidy (vetn metod statickch a tudi i ioziujicich).
Ostatni asti piogiamu by Vam mly bt zejm. Pio vpis seznamu (ioziujici
metoda Print) je vyuit cyklus for, nebo zpiacovani posledniho pivku se od ostat-
nich miin lii, nebo za poslednim pivkem nemusi bt vypsan oddlova (zde je
to aika a mezeia). V cyklu forea nelze jednodue zjistit, zda je piochazen pi-
vek posledni i nikoliv.
Poznmka:
Jak jsemzminil na zaatku tto sekce, musime jet piodiskutovat po-
uitelnost naich ioziujicich metod pio seznamy, jejich polokami
jsou jin tidy. Nae implementace pedepisuje, e adiesatem obou
metod (Shue a Print) je seznam isel tidy int. Pio jin seznamy je
tak nelze pouit. Pokud se vak pokusime vytvoit obdobn metody
pio jin tidy poloek, snadno zjistime, e jsou tm identick. Lii
se jen v zamn identikatoiu tidy poloek v hlavikach metody a v
denici pomocn piomnn v kodu zamny. Jako piklad si meme
uvst veizi pio seznamy etzc
public static void Shuffle(this List<string> a) { / / 1. zmna
for (int i = a.Count - 1; i >= 1; i--) {
int j = g.Next(0, i + 1); / / nahodn islo z inteivalu [c, i]
string p = a[i]; / / 2. zmna
a[i] = a[j];
a[j] = p;
}
}
public static void Print(this List<string> a) { / / 3. zmna
for (int i=0; i < a.Count; i++) { / / pio kad index seznamu
Console.Write(a[i]); / / vypi pivek
Seznam zakladni kolekce 1
if (i < a.Count - 1) { / / neni-li pedposledni
Console.Write(","); / / vypi oddlova
}
}
Console.WriteLine(); / / a nakonec odadkuj
}
Modeini jazyky, k nim C= pati, pioto podpoiuji i tzv. polymorfn
metody. Polymoifni metody jsou schopny pevzit a zpiacovat objek-
ty vech tid, jejich iozhiani podpoiuje vekei metody a opeiace,
ktei jsou nad nimi v tle metody volany. V pipad naich iozio-
vacich metod to mohou bt seznamy s libovolnmi polokami, nebo
v metod Shue neni nad objekty poloek volana adna metoda a
v metod Print je to pouze metoda ToString, je je dostupna u vech
objekt v systmu.
Jazyk C= podpoiuje dva typy polymoismu. Tzv. stati polymor-
smus je zastoupen geneiickmi metodami. Statick polymoismus
ei iozdily mezi tidami ji v dob pekladu. Ve skutenosti dla auto-
maticky tot, co jsme ve piovadli iun. Pio kadou tidu poloek
vytvoi automaticky novou veizi metody, v ni nahiadi obecn jm-
no tidy za jmno skuten. Nasledujici fiagment piogiamu ukazuje
geneiickou veizi metody Shue. Ta se od bn metody lii uvedenim
jmen tzv. geneiickch typ v lomench zavoikach (zde je pouit jedi-
n geneiick typ oznaen identikatoiem T). Tyto typy neoznauji
konkitni tidy, jsou pouze jejich zastupci. Ve vsledn specializova-
n veizi metody budou nahiazeny identikatoiem skuten tidy (tj.
nap. tidou int nebo string). Zastupn jmno je pouito jak v oznae-
ni tidy paiameti, tak i v denici piomnn (je zejm, e piomnna
musi mit stejn typ jako poloky seznamu).
public static void Shuffle<T>(this List<T> a) {
for (int i = a.Count - 1; i >= 1; i--) {
int j = g.Next(0, i + 1); / / nahodn islo z inteivalu [c, i]
T p = a[i];
a[i] = a[j];
a[j] = p;
}
}
1e
Diuh typ polymoismu je oznaovan jako dynami. Pi pouiti
tohoto typu polymoismu, se o skutenm tid objekt iozhodne a
za bhu. Aby dynamick polymoismus fungoval, musi existovat in-
kluzivni ielace mezi tidami (tj. uiita tida je podtidou jin tidy) a
iozhodnuti o tom jaka veize metody se pouije musi bt piovedeno
a v okamiku jejiho volani. V objektovch jazycich se vyuiva me-
chanism ddinosti, iozhiani a pozdni vazby, kteim se budeme v-
novat pozdji. Piozatim si ukaeme, jak by vypadala pln polymoifni
veize metody Print (tentokiat s vyuitim dynamickho polymois-
mu). ldentikatoi IList oznauje iozhiani, ktei spluji vechny se-
znamy bez ohledu na typ poloek (a nejen seznamy, ale i dali podob-
n kolekce). Ty vechny lze pouit jako paiameti metody.
public static void Print(this IList a) {
for (int i=0; i < a.Count; i++) { / / pio kad index seznamu
Console.Write(a[i]); / / vypi pivek
if (i < a.Count - 1) { / / neni-li pedposledni
Console.Write(","); / / vypi oddlova
}
}
Console.WriteLine(); / / a nakonec odadkuj
}
Metodu Print by bylo mono polymoifn zapsat i pomoci statickho
polymoismu. To vak ji necham na Vas.
4.2.2. Test setdn seznamu
Seznam budeme oznaovat jako setidn (iesp. seazen) pokud plati
a)
cz
+1
(seznam iostouci nebo s konstantnim pibhem)
b)
cz
+1
(seznam klesajici nebo s konstantnim pibhem)
Specialnim pipadem jsou piazdn a jednopivkov seznamy, ktei meme pova-
ovat za setidn. Dokonce i dvoupivkov seznamy jsou vdy setidn (spluji
vdy bu podminku (a) nebo (b)).
Algoiitmus pio seznamy s vice ne dvma pivky je jednoduch a piiozen. Po-
iovnate pivni dva pivky a zjistite, ktei z nich je vti. Tim zjistite, jak smi
(iostouci i klesajici) by ml mit zbytek seznamu. Tento smi budete ovovat
Seznam zakladni kolekce 1,
i pio nasledujici (pekivajici se) dvojice pivk (diuh s tetim, teti s tvitm,
atd.). Tj. je-li
c
<
1
, pak musi pio vechny ostatni pivky platit
+1
(ios-
touci seznam), naopak je-li
c
> , pak musi platit
+1
(klesajici seznam).
Bohuel me nastat i situace, kdy
1
=
z
. Pak nememe iozhodnout o pi-
bhu seznamu (seznam me bt iostouci, klesajici, konstantni a samozejm i
nesetidn).
Tuto situaci lze eit dvma zpsoby
1. hledanim pivni odlin dvojice, kteia nam uii pibh, dale v seznamu. Po-
kud neni adna takova dvojice nalezena, ma seznam konstantni pibh (a
tudi je setidn). V opanm pipad je nutno ovit zda vechny nasle-
dujici dvojice dodiuji stejn pibh. (evolun een )
z. iozienim mnoiny stav o stav konstantni a pizpsobenim ovovacich
piavidel (revolun een )
Vhodou diuhho eeni je sjednoceni pistupu pio vechny pivky (neni nutno
hledat pivni neshodnou dvojici). Navic podminky ovujici zachovani stavu jsou
jen miin sloitji
1. Pokud je pibh pio pivnich pivk konstantni, pak v pipad, e
<
+1
zmnime stav pibhu na iostouci, pio
>
+1
na klesajici. Jinak se stav
nemni, nebo seznam ma stale konstantni pibh.
z. Je-li pedchozi pibh po pivcich iostouci, pak musi platit
+1
(stav
se nemni). Vopanmpipad je seznamnesetidn a metoda me skon-
it (ostatni pivky u neni poteba kontiolovat)
I. Podobn je-li pedchozi pibh po pivcich klesajici, pak musi platit
+1
(stav se nemni). V opanm pipad je seznam nesetidn a metoda
me skonit (ostatni pivky u neni poteba kontiolovat).
Na poatku (dokud jet neni zpiacovan adn pivek), by ml bt stav nastaven
na konstantni (neme pedjimat ani iostouci ani klesajici pibh).
Pokud piogiam spn zkontioluje vechny pivky, pak plati, e je setidn. V
opanm pipad by metoda skonila pedasn pi nalezeni pivk s opanm
pibhem.
Zakladni funkce algoiitmu je piesentovana na obiazku 1.v na nasledujici stian.
ipky (nad seznamem) znazoiuji aktualni pibh, ielani opeiatoiy (pod sezna-
mem pak zjitnou ielaci). Znazoinny jsou ti typick piklady (iostouci, klesa-
18
jici, nesetidn). tvitou monosti je seznam s jedinou opakovanou hodnotou
(konstantni pibh).
1 1 2 3 3
3 3 3 3 2
1 1 2 4 3
x
=
zjitn relace
prbh (po teston!"
= = = #
zjitn relace
prbh (po poronn!"
set$!%n&
set$!%n&
zjitn relace
prbh (po poronn!"
neset$!%n&
=
'
Obiazek 1.v. Test setidni seznamu (typy pibh)
Tim konime algoiitmick iozboi a meme pejit k iepiesentaci dat i kodu.
Piomnna udiujici pibn stav (pibh) me nabvat ti hodnot. Neme
tudi uchovavat hodnoty tidy bool (existuji jen dva objekty tto tidy). Stavy
vak lze iepiesentovat piostednictvim jinch tid
int: nap. pomoci hodnot c (konstantni pibh), 1 (iostouci pibh) a -1 (klesa-
jici pibh), ielativn intuitivni a efektivni, nachyln k chybam, nebo do
piomnn lze vloit i jin celoiseln hodnoty.
string: nap. pomoci etzc konstantni, iostouci a klesajici. Neefektivni (vi-
ce ne zcbyt na objekt), siln nachyln k chybam (mete vloit jakkoliv
etzec, z nich mnoh se mohou jevit jako iozumn nap. ioste). lntui-
tivni jsou navic jen pio echy (a i pio n jen omezen).
Seznam zakladni kolekce 1,
Ostatni nam znam tidy pinaeji stejn pioblmy (ar, double), nebo jsou s-
manticky zcela nepouiteln (System.Datetime).
Natsti nam jazyk C= nabizi vhodnji eeni piostednictvim tzv. vtov tdy
(vtovho typu)
Vty
Vty jsou specializovan tidy, ktei maji pesn denovan poet monch in-
stanci. Tento poet je ve vtin pipad velmi mal, maximaln desitky. Uivatel
me vytvaet vlastni vtov tidy, piem specikuje vechny potencialni ob-
jekty dan tidy vtem jejich symbolickch jmen (identikatoi).
enum Barva {
Modra,
Cervena,
Bila
}
Timto zapisem (denici) vznikne nova vtova tida, kteia me mit ti izn in-
stance (piozatimse vak adna instance nevytvoi). Kada instance ma symbolick
jmno, ktei musi bt v iamci vtu unikatni.
lnstance vtov tidy si mete vytvoit kdekoliv v piogiamu pomoci zapisu
JmnoTdy.JmnoObjektu, nap. Barva.Modr.
lnstance vtovch typ se pouivaji jako symboly, ktei nemaji adnou vnitni
stiuktuiu a nepodpoiuji adn metody, vlastnosti a opeiace kiom vzajemnho
poiovnani (testu iovnosti).
Objekt Barva.Modr tak napiklad nelze inteipietovat jako popis baivy (nap. uve-
denimjeji pozice v baievnmpiostoiu RGB), ani jako etzec pti znak (tj. otazka,
jakm znakem symbol zaina nema adn smysl). Baivy nelze samozejm sitat
i nasobit ani zjiovat, jaka z nich je vti i meni.
Jedinou spiavnou inteipietaci, je chapani objektu jako jedinen entity, kteiou
lze jednodue a jednoznan odliit od vech ostatnich objekt vtu. Tj. v naem
pipad je modia baivou, o ktei nic nevime, ale dokaeme ji jednoznan odliit
od baivy bil a eiven (jin baivy v naem modelu nejsou).
Nasledujici fiagment piogiamu ukazuje vechny opeiace, ktei lze bn s objek-
tem vtovho typu piovadt
1o
Barva b = Barva.Modra; / / vytvoeni a uloeni v piomnn
...
if(b == Barva.Modra) { / / test iovnosti identity
/ / zde bude kod zavisl na hodnot piomnn vt. typu
}
Console.WriteLine( b.ToString() ); / / vpis symbolickho jmna
Vpis instance vtu (iesp. jeho symbolick iepiesentace) by se navic ml vyui-
vat jen pio ely ladni (tj. jen ve fazi vvoje piogiamu a jen pio piogiamatoiy).
Symbolick oznaeni vtovch objekt je toti stejn jako jmna piomnnch i
tid pouze inteinim oznaenim a pio koncov uivatele musi bt tiansfoimovano
do popisnch etzc (nejlpe v jazyce uivatele), i jet lpe do jin (netextov)
iepiesentace (zde napiklad obaivenim vizualniho pivku na modiou baivu).
Poznmka:
Vtov tidy (typy) jsou bohuel v C= pouivany i k jinm elm,
ne k zavadni mnoin jednoznanch symbol. Navic se navenek
piojevuje i jejich inteini iepiesentace pomoci celoiselnch konstant.
Vsledkemje situace, kdy lze snadno napsat syntakticky spiavn kod,
ktei je vak vice ne pochybn (tj. nelze jej iozumn inteipietovat)
Barva b = (Barva)42; / / ` nedenovana baiva
Barva b1; / / implicitn symbol s iepiesentaci c (nejasteji pivni uveden) zde Modia
Barva b2 = Barva.Bila;
if (b1 < b2) {...}
/ / piavdiva podminka, ale jen z dvod vnitni iepiesentace
b2 = b1 + 1; / / bz je ceivena, ale pio`
b2 = b1 * 10;
/ / ` nesmyslna opeiace, jejim vsledkem je nedenovana baiva
Nkdy se vak celoiselna iepiesentace hodi. Tyto pipady je vak
nutno stiiktn odliovat od vyuita vtovch tid jako mnoin sym-
bol! Syntakticky je to stejna konstiukce, ale smanticky je to nco
pln jinho.
Seznam zakladni kolekce 11
Vtov typ jako mnoina sel se symboliou representaci
enum Hodnoceni {
Negativni = -1, / / hodnoty symbol jsou explicitn uvedeny
Neutrlni = 0,
Pozitivni = 1;
}
Hodnoceni h; / / implicitn c tj. neutialni
if(h >= Hodnoceni.Neutralni) / / alespo neutialni
Hodnoceni h2 = -h; / / opan hodnoceni
h++; / / zlepeni hodnoceni o stupe
/ / ale to neni zcela koei, pio Pozitivni neni denovano!
U vt tohoto typu je vhodn explicitn denovat iepiesentovan
iseln hodnoty. Pokud se neuvedou, pak je pivni poloka iepiesen-
tovan nulou a ostatni maji iepiesentaci o jedniku vyi ne pedcho-
zi poloka (a u je dana explicitn i nikoliv). A na zcela vjimen
pipady by mly bt pouit iseln hodnoty v iamci vtu jedinen.
Vtov typ jako mnoina bitov pznak
Bn objekty i hodnoty nemohou nikdy zaujimat mn ne byte
pamti. Repiesentace objekt vtovch typ (shodna s iepiesentaci
isel tidy int) zaujima dokonce byty tyi.
Pokud se vak v iepiesentaci symbolickch konstant omezime pou-
ze na hodnoty obsahujici v binaini (dvojkov) iepiesentaci jedinou
jedniku (tj. mocniny dvou), je mono uloit vice tchto hodnot do
vicebytov inteini iepiesentace. Objekt vtovho typu pak ji ne-
iepiesentuje jedinou hodnotu, ale mnoinu hodnot (z nich kada je
navic iepiesentovana symbolickm jmnem).
Pio manipulaci s jednotlivmi hodnotami je nutno vyuit tzv. bito-
vch opeiaci tj. logickch opeiaci, ktei se piovadji mezi jednotli-
vmi bity iepiesentace isla. Maximalni poet iepiesentovatelnch
hodnot je dan potem bit tto iepiesentace, implicitn je to Iz hod-
not ( poet bit ve 1 bytech). V nasledujicim pipad je to z hodnot
(len lviopsk unie).
1:
[Flag]
enum EUMembers {
Austria = 0x00000001, / / 1
Belgium = 0x00000002, / / z
Bulgaria = 0x00000004, / / 1
Cyprus = 0x00000008, / / s
Czechia = 0x00000010, / / 1e
Denmark = 0x00000020, / / Iz
Estonia = 0x00000040, / / e1
...
Sweden = 0x04000000, / / e1csse1
UK = 0x08000000 / / 1I1z1zs
}
EUMembers visegrad_group =
EUMembers.Czechia | EUMembers.Poland |
EUMembers.Slovakia | EUMembers.Hungary;
EUMembers euro_zone =
EUMembers.Austria | EUMembers.Belgium |
... | EUMembers.Spain;
/ / pidani pivku
euro_zone |= EUMembers.Estonia;
/ / zkiatka za euiozone euiozone lUMembeis.lstonia,
/ / vyjmuti pivku
euro_zone &= ~EUMembers.Greece;
/ / pinik mnoin
EUMembers euro_visegrad = visegrad_group & euro_zone;
/ / testovani pislunosti
if( EUMembers.Czechia & euro_zone ) {
...
}
Console.WriteLine( visegrad_group.ToString() );
/ / vypie seznam jmen stat oddlen svislitkem
Vimnte si pouiti zapisu [Flag] ped hlavikou vtovho typu. Je
to piklad tzv. atributu, pomoci nho lze dodat dodaten infoima-
Seznam zakladni kolekce 1
ce (metadata) ke tidam (a tak napiklad i metodam). Tento atiibut
je uloen do vslednho bytovho kodu a me bt vyuivan pio-
giamem i exteinimi nastioji. Atiibut Flag je zde vyuivan metodou
ToString, kteia pi jeho uvedeni spiavn inteipietuje sloen hodnoty
(pi absenci piznaku by vypisovala jen nepehledna isla).
Konverze z etzce a globln operace s vtovm typem
Zakladni opeiace s vtovm typem lze piovadt pimo s objektem
vtovho typu (petypovani na celoiselnou hodnotu a pevod na
etzec). Pio dali opeiace je vak nutno vyuit tidni metody tidy
System.Enum (nikoliv tedy tidni metody jednotlivch vt!). Ti-
da System.Enum nema adn vlastni instance-objekty, poskytuje vak
pomocn (statick) metody pio instance vech vt a je foimaln
pedkem v hieiaichii ddinosti pio vechny vty (ddinosti se bu-
deme zabvat a pozdji)
using System;
enum Vlak {
Os,
R,
Ex
}
Vlak vlak = Enum.Parse(typeof(Vlak), Console.Readline());
/ / opeiatoi typeof viaci objekt iepiesentujici tidu,
/ / je je jeho aigumentem
foreach(Vlak vlak in Enum.GetValues(typeof(Vlak))){
Console.WriteLine( vlak ); / / iteiace pes vechny instance vtu
}
foreach(string jmenaTypuVlaku in Enum.GetNames(typeof(Vlak))){
/ / iteiace pes etzcov iepiesentace
}
=
Nyni se viatime k naemu piogiamu. Nejdive vytvoime kostiu piogiamu s ti-
dami a metodami (zatim bez vlastniho kodu).
using System;
using System.Collections.Generic;
1
enum Prubeh {
Klesajici,
Konstantni,
Rostouci
}
static class ListUtil {
public static bool JeSetriden (this List<int> seznam) {
/ / zde bude kod ioziujici metody
return true;
}
}
class MainClass {
public static void Main (string[] args) {
/ / zde bude testovaci kod
}
}
Kod ioziujici metody vychazi z algoiitmu uvedenho na zaatku podsekce (sti.
1Ie). Jadiem je cyklus piochazejici vechny pivky seznamu. Zvolen je cyklus for,
nebo umouje souasn pistup ke dvma pivkm(u nas jsou to pivky
a
+1
).
V zasad lze pouit i cyklus forea a pamatovat si pedchozi pivek (nevhodou
vak je nutnost specialniho zpiacovani pivniho pivku a piazdnho seznamu).
Prubeh prubeh = Prubeh.Konstantni;
for (int i=0; i < seznam.Count-1; i++) {
if (prubeh == Prubeh.Konstantni) {
if (seznam[i] < seznam[i + 1]) {
prubeh = Prubeh.Rostouci;
} else {
if (seznam[i] > seznam[i + 1]) {
prubeh = Prubeh.Klesajici;
}
/ / jinak zstava pibh nezmnn
}
} else { / / nekonstantni pibh
if (prubeh == Prubeh.Klesajici && seznam[i] < seznam[i + 1]
||
Seznam zakladni kolekce 1
prubeh == Prubeh.Rostouci && seznam[i] > seznam[i + 1])
return false;
}
}
return true; / / je setidn
Kod metody zaina nastavenim poateniho pibhu (na zaatku neni znam sku-
ten pibh, pioto je zvolen neutialni tj. konstantni ). Cyklus piochazi vechny
pivky kiom posledniho (posledni pouit index je seznam.Count-2). Pokud by
byl piochazen i posledni pivek, dolo by k peteeni indexu pi pistupu k nasle-
dujicimu ( + 1) pivku.
Nejdive je een pipad, kdy je piozatimni pibh konstantni. Pak je jsou ti mo-
nosti (pioto je nutn v tto vtvi pouit dva vnoen cykly if, jedno if umouje
vyeit pouze dv monosti)
<
+1
pibh se mni na iostouci
>
+1
pibh se mni na klesajici
jinak (tj.
=
+1
) pibh se nemni (tj. neni teba vykonat
nic, pioto chybi ast else ve vnoenm if )
Pokud je piozatimni pibh nekonstantni (ast else vnjiho podminnho via-
zu), pak testujeme, zda jej nenaiui dali pivek (s indexem i-1). Naiueni me
nastat pouze ve dvou pipadech
=
<
+1
nebo
=
>
+1
Pokud tato situace nastane, je ioziujici metoda ukonena s vsledkem false (se-
znam neni setidn).
V opanm pipad se nic nedje (opt chybi ast else) a piogiam pokiauje dali
iteiaci (tj. testovanim daliho pivku).
Vokamiku, kdy jsou spn (tj. bez pedasnho ukoneni) zkontiolovany vech-
ny pivky, je cyklus ukonen a metoda viaci (a po skoneni cyklu!) hodnotu true.
Algoiitmus je ielativn jednoduch, miin matouci vak me bt sple navzajem
vnoench podminek. V oiientaci Vam me pomoci diagiam aktivit (nastupce
dive pouivanch vvojovch diagiam).
Algoiitmus neni zcela tiivialni a pioto musi bt dsledn otestovan. Testovaci kod
umistn do metody MainClass.Main obsahuje pt testovacich seznam.
1e
prubeh=Rostouci
prubeh=Kl esaj i ci
seznam je neusporadany
test naruseni prubehu test predchozi ho prubehu
[ prubeh = Rost ouci && x[ i ] > x[ i +1]
| | prubeh = Kl esaj i ci && x[ i ] < x[ i +1]
[ j i nak]
[ prubeh! =Konst ant ni ]
[ x[ i ] =x[ i +1] ]
[ x[ i ] >x[ i +1] ]
[ x[ i ] >=x[ i +1] ]
[ x[ i ] <x[ i +1] ]
[ prubeh=Konst ant n ]
Visual Paradigm for UML Community Edition [not for commercial use]
Obiazek 1.1c. Logika vtveni v tle cyklu (test setidnosti)
Seznam zakladni kolekce 1,
List<int> t1 = new List<int>(){1, 1, 3, 3, 5, 8};
List<int> t2 = new List<int>(){1, 1, 3, 5, 3, 8};
List<int> t3 = new List<int>(){1, 0};
List<int> t4 = new List<int>(){1, 0, 1};
List<int> t5 = new List<int>(){0, 0, 0, 0};
Console.WriteLine(t1.JeSetriden());
Console.WriteLine(!t2.JeSetriden());
Console.WriteLine(t3.JeSetriden());
Console.WriteLine(!t4.JeSetriden());
Console.WriteLine(t5.JeSetriden());
Seznam t1 je iostouci (a tudi setidn). Seznam t2 je nesetidn (je pevan
iostouci, ale po islu nasleduje I). Seznam t3 je klesajici ( setidn), na iozdil
od seznamu t4 (ten je nejdive klesajici pak vak ioste). Seznam t5 obsahuje jen
nulov pivky, je tudi setidn (konstantni pibh).
Pi testovani vypisujeme pimo vsledek volani metody, pokud oekavame, e
bude ioven true (tj. pozitivni). Pokud vak oekavame vsledek negativni (false)
vypieme jeho negaci. Na vstupu by se tedy ml objevit ptkiat etzec Tiue.
Ve uvedena implementace viaci pio testovan seznamy spiavn vsledky, to
vak bohuel stopiocentn nezaiuuje, e je spiavna. Nelze toti vylouit, e pio
jin (netestovan) etzec metoda sele. Piotoe jsme vak otestovali vechny ty-
py pibhu, je tato piavdpodobnost velmi mala (navic k naiueni setidni do-
chazi na iznch pozicich a nktei seznamy obsahuji sekce s konstantnim pi-
bhem).
Otazka Jak se metoda vypoada s piazdnm i jednopivkovm seznamem`
Poznmka:
l u tto metody se zamime na polymoismus. Je zejm, e i metoda
pio kontiolu setidnosti me bt polymoifni vzhledemk tid polo-
ek. Setidnost lze kontiolovat i pio seznamy etzc nebo asovch
daj. Na iozdil od piomichavaci metody je vak tento polymois-
mus miin omezen. Setidni toti nelze kontiolovat u poloek, pio
n neni denovano uspoadani (tj. ielace je meni iesp. vti ne).
Nepoiovnateln jsou napiklad seznamy (C= nedenuje ielaci uspo-
adani mezi seznamy).
Z tohoto dvod se implementace polymoifni veize miin kompli-
kuje. U statickho polymoismu je nutno specikovat, e poloky lze
18
poiovnavat (pesnji eeno, e jejich tidy sdileji spolenou metodu
pio poiovnavani). V C= natsti existuje iozhiani IComparable<T>,
jeji metodu CompareTo sdileji vechny poiovnateln objekty (poiov-
nani je ale omezeno na hodnoty stejnho typu!). lmplementace vak
neni ji tak pimoaia (nestai nahiadit jmna tidy za geneiick pa-
iameti).
public static bool JeSetriden<T>(this List<T> seznam)
where T:IComparable<T> {
Prubeh prubeh = Prubeh.Konstantni;
for (int i=0; i < seznam.Count-1; i++) {
if (prubeh == Prubeh.Konstantni) {
if (seznam[i].CompareTo(seznam[i + 1]) < 0) {
prubeh = Prubeh.Rostouci;
} else {
if (seznam[i].CompareTo(seznam[i + 1]) > 0) {
prubeh = Prubeh.Klesajici;
}
/ / jinak zstava pibh nezmnn
}
} else {
if (prubeh == Prubeh.Klesajici &&
seznam[i].CompareTo(seznam[i + 1]) < 0 ||
prubeh == Prubeh.Rostouci
&& seznam[i].CompareTo(seznam[i + 1]) > 0)
return false;
}
}
return true; / / je setidn
}
Geneiick paiameti je pomoci konstiukce where omezen jen na tidy
implementujici iozhiani IComparable<T> tj. na vechny tidy, pio je-
jich objekty existuje uspoadani. V tle metody jsou vechna poiov-
nani iealizovana metodou CompareTo, nebo jen tu si vynucuje ioz-
hiani. Podpoia ielanich opeiatoi je opioti tomu nepovinna. Volani
a.CompareTo(b) viaci zapoin islo je-li < , nulu jsou li objekty
shodn a kladn islo je-li > .
5. Uivatelsk tdy
Hlavnim piostedkem a cilem OOP piogiamovani je vytvaeni vlastnich tid, je-
jich objekty (instance) spiavn inteiaguji s ostatnimi tidami a okolim (lov-
kem, inteinetovmi slubami, apod.) iesp. dostaten modeluji zvolen fyzick
objekt v dan pioblmov domn.
Nov uivatelsk tidy se nikdy nevytvaeji na zelen louce tj. pimou specikaci
binaini iepiesentace a elementainich metod (jako je nap. poiovnani), ale vdy s
vyuitim existujicich tid. Dje se to pomoci ty zakladnich mechanism
skldn (composition) objekty novch tid vznikaji sloenim dvou a vice ob-
jekt ji existujicich tid. V tomto pipad je pevzata datova iepiesentace
objekt-komponent a intein lze vyuivat i jejich metod. Vnitni objekty
vak nejsou navenek pimo pistupn. Rozhiani objekt nov tidy musi
bt denovano zcela nov, stejn jako implementace metod, ktei zajiuji
funknost iozhiani.
Mechanismus skladani je pouivan i v bn pouivanch modelech a tim i
konstiukcich vytvoench lovkem. Auto je tvoeno souastkami, ma vak
vlastni iozhiani, ktei neni zajitno adnou konkitni souastkou (nap.
schopnost pevaet osoby, spotebovavat palivo, stat se objektem dan i
pojitni, apod.) Navic souastky nejsou pimo pistupn tj. nelze je vyu-
ivat mimo auto. Dleit pitom neni njak skuten stav, ale modely,
ktei mate ve sv hlav. V iamci vtiny tchto model napiklad neped-
pokladate, e zastavite a vnujete nkomu motoi svho auta nebo zddite
lev blatnik ddekova auta.
adaptace objekt pvodni tidy je vyuivan jako jedin iepiesentant stavu nov
tidy, je vak opaten novm iozhianim (pomoci nov implementovanch
metod). Pvodni objekt je uvnit novho objektu skiyt vyuivan (ve sku-
tenosti musi zajistit vekeiou zakladni funknost), neni vak zveni pimo
pistupn (tzv. model pan a otiok). Adaptace je v zasad specialnim pipa-
dem skladani (nov objekt je tvoen jedinm komponentem).
V bn pouivanch modelech neni adaptace tak dobe viditelna jako skla-
11v
1o
dani. Pikladem je napiklad model/konstiukce multimedialniho centia za
pomoci (univeizalniho) poitae. Nov centium nabizi specializovan slu-
by, pvodni iozhiani poitae (vetn nap. monosti sputt kancelask
sofwaie) neni vyuivano iesp. neni dostupn. Vimnte si, e poita se pi
adaptaci fyzicky nemni (mni se pouze model jeho vyuivani).
agregace objekt doasn shiomauje a vyuiva dili objekty. Tyto objekty si
vak zachovavaji svou nezavislost a jsou pimo pistupn. Navic mohou
existovat i po zaniku agiegatoia. Typickmpiklademagiegaci jsou kolekce
(u nich pevauje aspekt shiomaovani). Stejn jako u pedchozich dvou
metod ma nov objekt (agiegat) zcela nov iozhiani (a tim i implementaci).
Nalezeni piiozench model neni jednoduch, nebo se vtinou nepio-
mitaji do sfiy piogiamovani (tj. nejsou mapovany na agiegaci v modelu
piogiamu). Podnik by se napiklad mohl jevit jako typick agiegat, nebo
pivky (piacovnici) nejsou jeho souasti a existuji i mimo nj. V pipad
sofwaiovch model vak nemodelujeme lidi (biologick iesp. spoleensk
entity), ale jejich aspekt zamstnance (ioli ve im, tok penz, apod.). Tak-
to modelovan objekt je pak spie komponentou objektu imy (vn imy
nema adn smysl). Dokonce i u kolekci je otazkou, zda se jedna o agiegace
(je pidani pivku do seznamu vytvoenimnovho objektu nebo jen zmnou
stavu`)
ddinost (inheritance) ddinost je ielativn sloit mechanismus (ukivaji-
ci v sob i skladani iesp. adaptaci). Ddinosti se pioto budeme detailnji
zabvat a pozdji. Piozatim stai vdt, e
1. ddinost je vztahem mezi tidami (tj. ddi se ze tid nikoliv objekt).
Nema tedy tm nic spolenho nap. s biologickou ddinosti (ta je
ddinosti mezi individui tj. objekty). Objekty nov tidy automaticky
ziskavaji metody z denice jin tidy (nova tida vak musi splovat
uiit podminky, jeji objekty musi bt nap. stiuktuialn podobn)
z. zddn iozhiani nelze modikovat (jen ioziit), implementace me-
tod poskytujicich toto iozhiani vak lze nahiadit jinmi (musi vak v
zasad zajiovat podobn chovani)
I. v jazyce C= ziskavaji objekty vech tid (vetn zakladnich) metody ze
tidy System.Object iesp. zkiacen object (object je jmno tidy!). Pioto
lze vechny objekty poiovnavat (metoda Equals) nebo tiansfoimovat
na etzce (metoda ToString).
Uivatelsk tidy 11
Nyni vak opusme teoiii a podivejme se na piaktick piklad vytvoeni nov tidy
dokument.
5.1. Definice nov tdy
Denice tidy plni pt zakladnich funkci
1. zavadi jmno tidy
z. denuje z jakch podobjekt budou sloeny instance tidy (pomoci dato-
vch len)
I. pomoci konstiuktoiu uiuje jak budou nov metody inicializovany
1. denuje a implementuje jednotliv metody tidy tj
a) denuje iozhiani tidy (tj. pomoci jakch metod lze s objekty dan
tidy inteiagovat)
b) uvadi implementaci jednotlivch metody iozhiani
Jedinou skuten povinnou ast je zavedeni jmna tidy. My budeme vytvaet ti-
du iepiesentujici denni asov daj (s minutovou pesnosti) a pioto tidu nazveme
Dennas (iesp. DenniCas).
class DenniCas {
Datov leny
Denni as lze iepiesentovat pomoci pouhch dvou isel potu hodin od plnoci
a potu minut od poatku hodiny.
Podobjekty jsou ve svm iodii obsaeny bu pimo (jsou-li instanci hodnotov
tidy), nebo jsou z iodie jen odkazovany (instance iefeiennich tid). Lze si pioto
pedstavit, e kad objekt je sloen z pamovch mist podobnch piomnnm,
ktei se oznauji jako datov leny (anglicky vak eld). Stejn jako piomnn
maji datov leny jmna (identikatoiy) a pedem uienou tidu objekt, je jsou
v nich uloeny nebo odkazovany.
Tyto datov leny existuji ve zvlatni (oddlen) kopii v kad objektu, ktei je
vytvoen jako instance dan tidy.
1:
Pikladem ze ivota je napiklad faktuia. To je sloen objekt, jen obsahuje po-
jmenovan asti, ktei bu obsahuji pimo objekty (napiklad iseln), nebo od-
kazuji objekty mimo vlastni faktuiu (nap. osoba platce faktuiy). Kada instance
faktuiy ma vlastni souboi pojmenovanch asti (tj. vlastni a nesdilen kolonky),
ktei vak mohou odkazovat stejn (tj. potencialn sdilen objekty). Chceme-li
uiit konkitni daj jednoznan identikovat musime uiit nejen identikatoi
asti faktuiy, ale i konkitni faktuiu (nap. platce faktuiy z-e1s).
V naem pipad bude kad objekt denniho asu obsahovat dva datov leny, v
nich bude uloen poet hodin (tida int hodnotova) a poet minut (opt podob-
jekt tidy int).
private int hodina;
private int minuta;
Kliov slovo private uiuje, e datov leny nebudou viditeln vn metod tidy.
To znamena, e nelze zamnit podobjekt za jin (stejn tidy) a dokonce podobjekt
dokonce nelze ani ziskat. Bohuel to vak u objekt iefeiennich tid nezabiani
jejich modikaci, a to v pipad, e nkdo jin vn objektu vlastni jin odkaz na
podobjekt. Tato situace by vak nemla bt zneuivana (iesp. by mla bt elimi-
novana vytvoenim vlastni nesdilen kopie objektu).
Vechny datov leny by mly bt piivatni (a z okoli nemniteln), a to ze dvou
(vzajemn piovazanch) dvod
1. ukiyti inteini stiuktuiy ped okolim v iamci zapouzden (objekt by ml
inteiagovat jen pomoci metod iozhiani). To sniuje zavislosti mezi objekty
iznch tid a umouje dali vvoj implementace tidy bez naiueni intei-
akce s okolim (iozhiani se nemni i je ioziovano se zachovanim zptn
kompatibility)
z. pi skladani a adaptaci je zajitno vyhrazen podobjekt tj. podobjekty
jsou pouivany jen v jednom sloenm objektu. To zabiauje negativnim
postiannim efektm (zmna podobjektu v iamci jednoho kompozita me
negativn ovlivnit jin sdilejici sloen objekt). U agiegace a ddinosti je
situace sloitji, ale i zde je nesdileni dobimvchodiskem. Oznaeni dato-
vho lenu jako soukiomho vyhiazeni ( nesdileni) nezaiuuje, umouje
vak dosaeni a kontiolu tohoto stavu (je to tedy nutna avak nikoliv po-
staujici podminka)
Specikace private je v C= v zasad nadbytena, nebo vechny pivky tidy jsou
implicitn soukiom (pesnji maji maximaln stiiktni omezeni pistupu). To
Uivatelsk tidy 1
vak neplati ve vech OOP jazycich s mechanismem omezenho pistupu a pioto
je vhodn modikatoi pistupu uvadt dsledn.
Pravidlo 19: Veny datov leny by mly bt oznaeny jako privtn.
Konstruktor
Pi vytvoeni objektu jsou datov leny neinicializovan tj. objekty hodnotovch
tid obsahuji nuly. To me bt akceptovateln, jako napiklad v naem pipad,
ale iozhodn ne dopoiuenihodn. Datov leny iefeiennich tid obsahuji hod-
notu null (co je tm vdy chybou). Pioto je tm nezbytnou asti denice tzv.
konstruktor, ktei se musi postaiat o inicializaci kad nov vytvoen instance
tidy
public DenniCas(int hodina, int minuta) {
this.hodina = hodina;
this.minuta = minuta;
}
Konstiuktoi je denovan podobn jako metoda, s dvma kliovmi iozdily
1. identikatoi konstiuktoiu je shodn s identikatoiem tidy (tj. DenniCas je
konstiuktoi objektu tidy DenniCas)
z. konstiuktoi nesm mit uveden typ naviatov hodnoty (ani specikaci void).
Konstiuktoi neni volan jako bna (tidni) metoda, ale pomoci opeiatoiu
new. Nic pimo neviaci, pouze inicializuje nov objekt.
Valna vtina konstiuktoi pejima paiametiy, ktei pomahaji denovat i zpes-
ovat poateni stav objektu. V nkteich pipadech (vetn toho naeho) nesou
paiametiy konstiuktoiu pimo poadovan podobjekty nov vznikajiciho objek-
tu. V tomto pipad je funkce konstiuktoiu zcela tiivialni kopiiuje pedavan
objekty do pislunch datovch len. U objekt hodnotovch typ postauje
piazeni paiameti do datovch len (objekt se de facto kopiiuje z jedn pio-
mnn do diuh).
Pi pistup k datovmlenmnov vytvaenho objektu se vyuiva namji dobe
znama tekova notace this.identifiktor-datovho-lenu, kde kliov slovo this
oznauje objekt, k jeho datovmu lenu pistupujeme (je to obdoba zapisu typu
objekt.piopeity). Uvnit konstiuktoiu oznauje slovo this nov vytvaen objekt.
Z hlediska konstiuktoiu je to adiesat, tj. objekt pio nj je konstiuktoi volan.
1
Pouiti kliovho slova this v konstiuktoiech a metodach tid se viazn lii od
pouiti stejnho slova v hlavice ioziujicich metod (i kdy vyjaduji podobn
piincip). U ioziujicich metod je adiesat metody pedavan jako bn paiameti
(piem paiameti me mit libovoln jmno) a kliov slovo this sloui pouze k
odlieni adiesata metody od ostatnich paiameti. Uvnit ioziujici metody se ji
nepouiva a k objektu se pistupuje stejn jako k ostatnim objektm, tj. piosted-
nictvim bn piomnn a pouze k veejnm lenm objektu.
U konstiuktoiu (a ostatnich vlastnich metod tidy) se adiesat pedava skiyt (ne-
ni uveden v seznamu paiameti) a uvnit metody je pistupn piostednictvim
specikace this. Ta ma funkci jaksi pseudopiomnn obsahujici odkaz na objekt
adiesata iesp. na nov vytvaen objekt. Syntakticky se tento pistup nelii od
vyuiti piomnn, ve vtin pipad vak mame vti piava tj. meme pistu-
povat i k (neveejnm) datovm lenm (to vak neni dano pouitim specikace
this, stejna ioziena piava mame ke vem objektm dan tidy).
Specikaci this lze navic ve vtin vynechat, nebo se pouije u vech identi-
katoi, ktei neoznauji lokalni piomnn nebo paiametiy dan metody (tzv.
implicitni this). V pipad datovch len lze vak dsledn uvadni specikato-
iu this dopoiuit, nebo je to ve vtin pipad pehlednji.
Vnaempipad je navic specikatoi this povinn, nebo paiametiy konstiuktoiu
se jmenuji stejn jako odpovidajici datov leny. Pi pouiti nekvalikovanho
jmna by byl zmaten nejen piogiamatoi, ale i peklada.
hodina = hodina;
Piotoe paiametiy (a lokalni piomnn) maji uvnit metod pednost ped dato-
vmi leny, je tento zapis pekladaem inteipietovan jako piazeni piomnn
(paiametiu) do stejn piomnn (co je piazdn pikaz, ktei se ani nevykona-
va).
Zapis se specikatoiem this je ji jednoznan (pio lovka i peklada)
this.hodina = hodina;
Objekt uloen v paiametiu (tj. pedan konstiuktoiu pi vytvaeni objektu) je
zkopiiovan do (stejnojmennho) datovho lenu (pedpokladame hodnotovou s-
mantiku). Diky tomu bude tento objekt (pesnji kopie objektu) existovat i po
ukoneni vykonavani konstiuktoiu (na iozdil od objektu v paiametiu, ktei tm
ihned zanikne). V datovm lenu bude existovat a do zaniku iodiovskho objek-
tu.
Uivatelsk tidy 1
Vznik novho objektu je detailn ilustiovan obiazkem .1.
DenniCas d = new DenniCas(15,40);
15 40
hodina minuta hodina
minuta
15
40
this
15
40
formln parametry
0 0
hodina minuta
skuten parametry
15 40
hodina minuta
d
kd
konstruktoru
Obiazek .1. Vznik objektu (s podobjekty hodnotovch tid)
Nov objekt tidy DenniCas lze vytvoit volanim jeho konstiuktoiu, nap. takto
DenniCas d = new DenniCas(15,40);
Vlastni vznik objektu piobiha ve tech fazich
1. (ppravn) Nejdive jsou vytvoeny objekty, ktei se stanou paiametiy
konstiuktoiu (tzv. skuten paiametiy). V naem pipad jsou vytvoeny
na zaklad pislunch liteial (a jsou tudi tidy int). Pak je volana iuti-
na pio vytvoeni objektu, kteia vytvoi v pamti nov piazdn objekt podle
denice tidy DenniCas. Tento objekt ji obsahuje misto pio vechny datov
leny, ty jsou vak piozatim nulov.
z. (inicializan = dokonen konstrukce) Tuto ast piovadi uivatelsk kod kon-
stiuktoiu. Nejdive jsou stejn jako u vech metod zkopiiovany skuten
paiametiy do lokalnich paiameti (lokalnich piomnnch vytvoench na
zaatku piovadni metody). Pak jsou piovedena piazeni v tle konstiuk-
toiu tj. objekty jsou znovu kopiiovany. Tentokiat jsou pesunuty z foimal-
nich paiameti do datovch len nov vytvaenho objektu. Tento objekt
1e
je uvnit konstiuktoiu odkazovan specialnim jmnem this. loimalni paia-
metiy na konci konstiuktoiu zanikaji (spolu s objekty, ktei jsou v nich
uloeny). Natsti jejich kopie jsou ji uloeny v nov vytvaenm objektu.
I. (nalizan ) Nov vytvoen objekt vak peije jen tehdy, pokud na nj
odkazuje alespo jedna piomnna. Piotoe vechny uivatelsk tdy jsou
referenn, stai do piomnn umistit odkaz na nov vytvoen objekt tj.
nedojde k adnmu kopiiovani. Bhem celho piocesu se piacuje jen s jed-
nim timt objektem tidy DenniCas. V naem pipad je odkaz umistn do
nov vytvoen piomnn s identikatoiem d.
Poznmka:
Teiminologie v oblasti konstiuktoiu neni zcela ustalena. Nktei pio-
giamatoi (a piogiamovaci jazyky) davaji pednost oznaeni iniciali-
zatoi, nebo konstiuktoi objekt nevytvai, ale pouze inicializuje (je-
t ped volanim konstiuktoiu se pio objekt vyhiadi pamov misto
a vyplni se poatenimi nulovmi hodnotami). Je vak otazkou, kdy
vlastn objekt vznika. Pokud pedpokladame, e objekt existuje a od
okamiku, kdy ma pesn denovan a pln platn stav, pak je ob-
jekt zkonstiuovan a na konci konstiuktoiu (pedtimje to spie jaksi
objektov embiyo). Tento diobn smantick iozdil je nejlpe vidt
u konstantnich objekt ( objekt u nich se nepipouti adna zm-
na po vytvoeni). l tyto objekty je nutno nastavit a to v konstiuktoiu
ped skutenm vznikem objektu.
Na zavi sekce vnovan konstiuktoiu dv piavidla.
Pravidlo 20*: Konstruktor by ml bt oznaen jako veejn (klovm slovem public
pouitm v hlavice konstruktoru).
Aby bylo mono snadno vytvaet nov objekty uivatelsk tidy musi bt jeji
konstiuktoi veejn, nebo alespo jeden ( pivni) objekt tidy musi bt vytvoen
v metod jin tidy. Toto piavidlo neni absolutni, nebo existuji pistupy, ktei
naopak vyaduji neveejn (tj. soukiom) konstiuktoiy. S tmi se vak seznamime
a pozdji.
Pravidlo 21: Konstruktor by ml ve svm tle inicializovat veny datov leny, a to
tm, e vytvo veny podobjekty svho objektu.
Toto piavidlo je iozienim piavidla o povinn implicitni inicializaci piomnnch
(viz podsekce na stian 1c). Je vak mnohem stiiktnji (opiavdu neexistuji adn
Uivatelsk tidy 1,
iozumn vjimky). Navic pedpoklada, e vechny podobjekty jsou vyhiazen (tj.
tvoi komponentu jen jednoho sloenho objektu).
Definice metody
Dali nezbytnou souasti denice tidy jsou denice metod. Nae ukazkova tida
bude mit jen dv metody. Pivni metoda bude poiovnavat dva objekty denniho
asu a zjiovat, ktei z nich je umistn pozdji v ase (pedpokladame, e oba
se tkaji stejnho dne a ve stejnm asovm pasmu). Napiklad okamik 11Ic je
iozhodn pozdji ne 111.
Piotoe se bude jednat o instanni metodu tidy DenniCas, bude jeden z asovch
okamik hiat ioli adiesata (tj. objektu nad nim je metoda volana) a diuh bu-
de pedan jako paiameti metody. To se piojevi jak pi volani (pouiti, aktivaci)
metody, tak v jeji implementaci.
Volani bude mit nasledujici tvai
DenniCas d = new DenniCas(14,30);
if ( d.JePozdejiNez(new DenniCas(11,15)) {...}
Ziekapitulujme si tidy (typy) vech zastnnch objekt
adrest objekt tidy DenniCas
parametr objekt tidy DenniCas
vsledek (naviatova hodnota) bool (System.Boolean)
Piotoe adiesatem je objekt tidy DenniCas, musi bt denice metody umistna
uvnit denice tto tidy. Je zde sice jet monost denovat ji jako ioziujici
metodu, ale to je v pipad uivatelskch tid ve vtin pipad zbyten.
Adiesat neni pedavan jako (viditeln) paiameti, ale je dostupn piostednictvim
identikatoiu this.
public bool JePozdejiNez(DenniCas porovnavanyCas) {
return this.hodina * 60 + this.minuta
> porovnavanyCas.hodina * 60 + porovnavanyCas.minuta;
}
Metoda poiovnava dva celoiseln daje. Viaz this.hodina * 60 + this.minuta
uiuje poet minut od plnoci pio asov daj iepiesentovan adiesatem meto-
dy (tj. objektem nad nim je metoda volana). Objekt-adiesat je i zde odkazovan
18
identikatoiem this a k jednotlivm podobjektm lze pistupovat piostednic-
tvim identikatoi pislunch datovch len (s pouitim bn tekov notace
objekt.datov len).
Tento daj je poiovnavan s islem ziskanm vyhodnocenim podviazu porovna-
vanyCas.hodina * 60 + porovnavanyCas.minuta. l toto islo iepiesentuje poet minut
od plnoci, tentokiat ale u denniho asu iepiesentovanho paiametiem meto-
dy. Objekt paiametiu je dostupn pomoci piomnn (foimalniho paiametiu) se
jmnem p (viz hlavika funkce). Paiameti lze pojmenovat libovoln, ml by vak
vyjadovat vznam objektu pio metodu (jedinou vjimkou jsou ovem kliova
slova vetn identikatoiu this).
Metoda tudi viaci true (jen tehdy), kdy je as od plnoci vyjaden objektem-
adiesatem (= this) (oste) vti ne as od plnoci vyjaden paiametiem metody
(porovnavanyCas). Jinak eeno metoda viaci piavdivou hodnotu jen tehdy, kdy
je as iepiesentovan adiesatem metody pozdji ne as iepiesentovan jejim
paiametiem (v iamci jednoho dne).
Poznmka:
Zpesnni uveden v zavoice za bezpiostedn pedchazejici vtou je
kliov. asov daje se v nai implementaci denniho asu poiovna-
vaji jen v iamci jedinho dne. Tj. asov daj zcc je (vdy) pozdji
ne asov daj eI, nebo se pedpoklada, e se vztahuji ke stejn-
mu dni. To nicmn neni v souladu s inteipietaci asu buzeni, u nho
se pedpoklada, e jakkoliv asov daj, ktei pio buzeni nastavime
je v budoucnosti (nastavovat as buzeni v minulosti neni pili io-
zumn). Tj. as eI (buzeni) je pozdji ne as zcI (as nastaveni
budiku).
Podobn me vzniknout pioblm i u iepiesentace jizdnich ad. Po-
kud vlak vyjidi ve zIIc a pijidi v cz, je dle naeho pistupu de
facto tachyonem, nebo pijidi dive ne odjidi. Natsti jsou vlaky
jedouci pes plnoc v esk iepublice spie vjimkou a pedevimlze
tuto situaci snadno oetit.
Diuha metoda bude k danmu iselnmu daji piitat asov posun v minutach.
Uplatni se pedevim v pipad, e potebujete spoitat, kdy piavdpodobn pi-
jede zpodn vlak. U malch zpodni nema vtina lidi pioblmy. Kdy vak
pijede vlak, s piavidelnm pijezdem ve zzI minut pokud ma zpodni z mi-
nut`
Uivatelsk tidy 1,
Aplikace metody PitiMinuty na objekt denniho asu je snadna
DenniCas prijezd = new DenniCas(22,37);
prijezd.PrictiMinuty(525); / / pipoteme zpodni
/ / a vypieme as opodnho pijezdu
Console.WriteLine( "Vlakprijedeve" + prijezd);
Algoiitmus pipoteni neni sloit, vyaduje vak dv tiansfoimace. Nejdive je
nutno as pevst na poet minut od plnoci. Pot je tepive mono piist minu-
tov posun. Na konci je vak nutno vsledn poet minut od plnoci opt pevst
do inteini iepiesentace tj. na hodiny a minuty. Navic je bohuel nezbytn zajistit,
e pokud vsledn as petee z1cc, bude vsledek upiaven na odpovidajici as
v inteivalu ccc a zIv. Tj. napiklad as zs musi bt peveden na 11.
To vak neni jet ve. Zvidav uivatel Vai metody, me zkusit piist i zapoi-
n poet minut. To mu meme dovolit (piitani zapoinho isla je oditanim),
musime vak zajistit, e nedojde k podteeni (tj. vsledn daj nesmi obsahovat
zapoin islice).
Poznmka:
Piogiamatoi se skuten destiuktivnimi sklony me dokonce jako
paiameti pedat islo tak velk, e po piteni k islu iepiesentujici-
mu poet minut od plnoci dojde ke peteeni celho isla (tj. isla
vsledkem je islo, ktei neni pomoci objekt tidy int vbec iepie-
sentovateln. Pokud napiklad pite islo int.Max pak k peteeni
dojde u kadho iselnho daje kiom plnoci. Vsledkem je zdan-
liv nahodn velk zapoin islo (velk v absolutni hodnot), ktei
se stane po piav a tiansfoimaci, jet zdanliv nahodnjim aso-
vm dajem. Tomuto pioblmu lze pedejit bu omezenim absolutni
hodnoty pipoitavanch minut nebo vyuitim konstiukce eed
jazyka C=.
public void PrictiMinuty(int posun) {
int minutyOdPulnoci = this.hodina * 60 + this.minuta;
minutyOdPulnoci += posun; / / piteni posunu
minutyOdPulnoci %= (24*60); / / omezeni na hodnotu v iozmezi c a 11Iv
if(minutyOdPulnoci < 0) {
minutyOdPulnoci += 24*60;
}
/ / nasleduje nastaveni podobjekt podle posunutho asu
this.hodina = minutyOdPulnoci / 60;
1eo
this.minuta = minutyOdPulnoci % 60;
}
Nejdive jsou vypoteny minuty od plnoci stejn jako v pedchozi metod (pio
adiesata tj. objekt this). Vsledn objekt tid int je uloen do lokalni piomnn
minutyOdPulnoci (bude se nam v iamci metody jet mnohokiat hodit).
Na diuhm adku piteme k tomuto objektu poadovan minutov posun a v-
sledn daj uloime opt do piomnn minutyOdPulnoci (stiunji eeno zvi-
me hodnotu piomnn minutyOdPulnoci o hodnotu posun). Jsme si stale vdomi,
e pipotena hodnota me bt i zapoina (tj. zapoin me bt i uloen vsle-
dek).
Teti adek omezuje hodnotu uloenou v piomnn minutyOdPulnoci na hodnoty
c a 11Iv. Dje se tak vydlenim uloen hodnoty islem 111c a uloenim zbytku
zpt do piomnn minutyOdPulnoci. Zapis je pio zaateniky ponkud nepehled-
n, ale jedna se pouze o zkiacen tvai zapisu
minutyOdPulnoci = minutyOdPulnoci % (24 * 60)
Vimnte si tak, e poet minut v iamci dne neni zadano pimo, ale viazem
z1*ec. Vynasobeni tchto isel bude piovedeno ji pekladaemtj. nebude nikteiak
zpomalovat piogiam. Zapis v neioznasobenm tvaiu je mnohem pehlednji (je
hned zejm jak vznam tato konstanta ma). Navic nemusite vytahovat kalku-
latoi. Peklada stii vtinu kapesnich kalkulaek do kapsy a ony si tak budou
moci uivat zaslouen odpoinek v kemikovm nebi.
Pokud je vak pvodni hodnota minut od plnoci zapoina, je vsledkem zbytku
po dleni hodnota v iozmezi 11Iv a c. To bohuel neni platn poet minut od
plnoci (neni umistn v iamci danho dne). Natsti spiavn daj lze ziskat pi-
tenim isla 111c. Napiklad daj z symbolizuje as z minuty ped plnoci tj.
11Is minut od (de facto pedchozi) plnoci (11Is = z +111c). Toto koiekni pi-
teni zajiuje adek umistn ve vtvi piogiamu, jen je vykonan jen pio zapoin
poet upiavench minut.
Nyni ji nasleduje jen zptna konveize minut od plnoci na hodiny od plnoci (ce-
loiseln(!) dleni hodnotou ec) a minuty od poatku tto hodiny (zbytek po tomto
dleni). Ob ziskan hodnoty jsou uloeny do datovch len adiesata. Adiesat
se tim zmni (tj. jedna se de facto o jin objekt uloen na stejnm pamovm
mist).
Metoda sice mni svho adiesata, nic vak neviaci. Nelze ji tudi volat jako souast
sloitjiho viazu na mist opeiandu nebo paiametiu iesp. adiesata jin metody.
Uivatelsk tidy 1e1
Lze ji vak pouit jako pikaz. Tak je metoda vyuita i v ukazce uveden o nco
ve.
=
K tto ukazce se jet viame. Na samm jejim konci je pozmnn objekt vy-
pisovan pomoci metody Console.WriteLine (je to staticka metoda tidy Console).
Tato metoda je v zasad schopna vypsat textovou iepiesentaci libovolnho ob-
jektu (vetn objekt pidanch tj. uivatelskch tid). Tuto ponkud magickou
schopnost ziskava tim, e vola nad kadm svm paiametiem metodu ToString,
kteia objekt pevede do jeho textov iepiesentace (tj. na objekt tidy string). Tuto
metodu nepodpoiuji jen vestavn jednoduch typy (jako jsou isla, logick hod-
noty a znaky jak jsme ji dive nkolikiat vidli), ale v zasad vechny objekty v
piogiamu.
Zna je i objekt nami vytvoen tidy ToString, navzdoiy tomu, e jsme adnou
takovou metodu nedenovali (denovali jsme jen metody JeVetsiNez a PrictiMi-
nuty). Dvodem je skutenost, e jsme tuto metodu zddili ze tidy object, kteia je
zakladem vech tid v systmu. Podiobnji se s pioblematikou ddni budeme za-
bvat pozdji, zde stai jen vdt, e tuto metodu ziskava kada tida automaticky
(a ji chce i nechce).
To, e jsme tuto metodu zadaimo zddili, jet neznamena, e bude k nemu
dobia. Pokud toti vypieme na objekt, tak zjistime, e namisto samopopisn a
jednoznan textov iepiesentace je vypsana jen nazev tidy. Tj. nejsme schop-
ni nejen ziskat daj o iepiesentovanm ase, ale nejsme dokonce schopni odliit
objekty iepiesentujici izn asy (ve vpise bude vdy jen text DenniCas).
eeni natsti existuje. Zddnou (a zcela nepouitelnou) implementaci meme
nahiadit za vlastni specializovanou veizi, jinak eeno meme metodu pede-
novat.
Pedefinovn metody ToString
Nov pedenovana metoda ToString me zohlednit datovou iepiesentaci (kom-
pozici) objekt nov tidy a pedevim optimalni foimat textov iepiesentace. To
ve zna jen tvice nov tidy a jen on je odpovdn za implementaci nov a lepi
funknosti metody.
Pedenovanim nevznikne nova metoda, ale pvodni metoda ziska jen nov (spe-
citji) kod. Nemni se nejen nazev metody, ale ani poet a pislun poadova-
1e:
n tidy paiameti. Zmnit nelze ani tidu naviatov hodnoty. l nae veize meto-
dy ToString tak nesmi mit adn paiameti a musi viacet etzec. To ve zkontioluje
peklada. Hlavika pedenovan metody tak musi mit nasledujici signatuiu
public override string ToString()
Kliov slovo public ji zname. Nov vytvoena veize metody musi bt veejna
stejn jako pvodni (zddna veize). Me ji tudi volat kdokoliv a kdekoliv.
Kliov slovo override je pio vas novinkou. Je zde povinn a ika, e se jedna o
novou implementaci ji existujici zddn metody (override je anglick ekvivalent
eskho slova pedenuje).
lmplementani ast pedenovan metody se nelii od jinch metod. l zde hiaje
kliovou ioli specikatoi this odkazujici na objekt adiesata a monost pistupu k
jeho datovm lenm (komponentam).
Pio foimatovani textu v metod ToString se asto pouiva metoda String.Format,
kteia umouje pesn foimatovat hodnoty jednoduchch typ a spojovat je do
sloitjich textovch konstiukci spolu s xnimi znaky. Metoda string.Format na-
bizi jaksi minijazyk pio popis vstupnich textovch foimat.
V naem pipad nam viazn usnadni foimatovani asovho daje do tvaiu h:mm
nebo hh:mm (kde h je islice [c-v] nebo dvojisli [1c-zI] oznaujici hodiny a mm
dvojisli [cc-v] oznaujici minuty). Pikladem spiavn foimatovanch daj je
zc nebo zIc (naopak nespiavn jsou iepiesentace c1z nebo 1z).
Tento poadavek lze pomoci minijazyka metody string.Format snadno splnit (uva-
dim pio pehlednost celou metodu DenniCas.ToString)
public override string ToString() {
return string.Format("{0:0}:{1:00}", this.hodina, this.minuta);
}
Kliovm pivkem foimatovaci metody je tzv. foimatovaci etzec (zde je zastou-
pen etzcovmliteialem"{0:#0}:{1:00}"). loimatovaci etzec obsahuje dva typy
daj bn znaky a popisovae. Bn znaky jsou vypisovany beze zmny a tvo-
i tak xni ast vstupniho foimatu. V naem pipad je to pouze znak dvojteky
upiosted etzce.
Popisovae jsou uzaveny ve sloench zavoikach a uiuji na jakm mist a v
jakm foimatu bude vypsana textova iepiesentace objekt, ktei jsou pedany
jako dali paiametiy metody string.Format. Jedinou povinnou asti je poadi vy-
pisovanho paiametiu (od nuly, foimatovaci etzec se nepoita). Tj. popisova
Uivatelsk tidy 1e
"{0}" zajisti vpis pivniho dodatenho paiametiu (u nas je to objekt odkazova-
n datovm lenem this.hodina), popisova "{1}" diuh dodaten paiameti (u
nas this.minuta). isla jsou nezbytna, nebo popisovae mohou bt uvedeny ve
foimatovacim etzci v poadi, ktei neodpovida poadi dodatench paiameti.
Kad popisova me navic u jednoduchch (pedevim) iselnch hodnot pes-
nji specikovat jak budou foimatovana. Dili foimat se uvadi v popisovai za
dvojtekou a me bt znan komplexni. My budeme zatim pouivat jen ielativ-
n jednoduch foimaty. Ty do znan miiy odpovidaji foimatovam znamm z
MS lxcelu, ktei piavdpodobn znate.
Nkolik typickch iselnch foimat ukazuje tabulka
tda formt objekt repres. vznam
int c 1 1 jedna povinna islice
1z 1z ostatni jen jsou li platn
int cc 1 c1 dv povinn islice
1z 1z ostatni jen jsou li platn
int = ==c 1 1 jedna povinna islice, (ostatni jen,
jsou-li platn)
1ze 1 ze oddlovani mezeiou po tisicich
double c.ccc I.111v I,11z piav ti povinna desetinna mista
c. c,cc povinna jednotkova islice
double =.c= c. , nepovinna jednotkova islice
1 1,c povinn pivni desetinn misto
c. c. diuh se zobiazuje, jen je-li platna
Dobi je znat tak zakladni foimaty pio objekty tidy DateTime (testovaci objekt
tidy DateTime iepiesentuje as vcc dne v.11 zc1z. Vimnte si, e kliovou ioli
hiaje poet foimatovacich znak a tak iozdil mezi minuskami a veizalkami!
1e
formtova vstupn text vznam
d.M.y v.11.1z nejstiunji datum
d. M. yyyy v. 11. zc1z kiatk datum podle esk
noimy
yyyy-MM-dd zc1z-11-cv lSO foimat
d. MMMM yyyy v. listopad zc1z dlouh datum (tm) podle
esk noimy
d.\uzczlMMMM lyyyy v. listopad zc1z s zkou mezeiou po tece
d. M. yyyy HHmm v. 11. zc1z cvcc datum s asem (dvojcifein
hodiny)
Hmm vcc jen as (jednocifein daj
hodin)
Datumov foimaty nelze bohuel pimo vyuit pio nai objekty nai tidy (bez
doplnni pomocnho kodu funguji jen pio objekty tidy DateTime). Pioto jsou v
nai metod ToString pouity popisovae pio vpis jednotlivch datovch len,
tj. popisovae iseln s pislunmi iselnmi foimaty.
=
Nyni ji mame pivni implementaci tidy hotovu a meme ji vyzkouet. Vpis
uvadi pio jistotu i celou denici tidy (tentokiat hezky pospolu).
using System; / / dennicas.cs
class DenniCas {
private int minuta;
private int hodina;
public DenniCas (int hodina, int minuta) {
this.hodina = hodina;
this.minuta = minuta;
}
public bool JePozdejiNez(DenniCas porovnavanyCas) {
return this.hodina * 60 + this.minuta
> porovnavanyCas.hodina * 60 + porovnavanyCas.minuta;
}
Uivatelsk tidy 1e
public void PrictiMinuty(int posun) {
int minutyOdPulnoci = this.hodina * 60 + this.minuta;
minutyOdPulnoci += posun;
minutyOdPulnoci %= (24 * 60);
if (minutyOdPulnoci < 0) {
minutyOdPulnoci += 24 * 60;
}
this.hodina = minutyOdPulnoci / 60;
this.minuta = minutyOdPulnoci % 60;
}
public override string ToString() {
return string.Format("{0:0}:{1:00}", this.hodina, this.minuta);
}
}
class MainClass {
public static void Main() { / / testovaci kod
DenniCas d = new DenniCas(22, 37);
Console.WriteLine(d);
d.PrictiMinuty(525);
Console.WriteLine(d);
Console.WriteLine(d.JePozdejiNez(new DenniCas(22, 37)));
DenniCas pd = d;
pd.PrictiMinuty(-24 * 60 - 10);
Console.WriteLine(pd);
Console.WriteLine(d);
}
}
Co tento piogiam vypie` Mli byste to bt ji sami schopni odhadnout, ale pio
jistotu uveme (skuten) vpis piogiamu
22:37
7:22
False
7:12
7:12
Pivni vpis je zejm. Nov vytvoen objekt odpovida iselnmpaiametim, je
byly pedany konstiuktoim(iepiesentuje tedy skuten as zzI). Po piteni se
1ee
z minut se objekt zmni tak, e iepiesentuje as zz (oveni vyaduje tiochu
pemleni, ale je to skuten spiavn).
Nasledn si tento as poiovname s pvodnim. Jak ji bylo eeno denni as zo-
hleduje jen vztahy uvnit jedinho dne, tj. posunut as zz nen pozdji ne
as pvodni (zzI), a pioto se vypie hodnota false.
Vimnte si, e pvodni as musime vytvaet znovu, nebo pvodni objekt po
posunu de facto zanikl a byl nahiazen novm(pestoe na nj odkazuje stale stejna
piomnna!) Je to pivni piznak zasadniho pioblmu.
Vyzkouime jet piteni zapoinho posunu. Pedtim vak objekt zkopiiujeme
do nov piomnn se jmnem pd (nebo se o to alespo pokusime). Tepive pes
tuto piomnou se pokusime o posun v ase zpt. Piteni hodnoty z1 ec
1c tj. 11c zmni objekt na as 1z, co je spiavn a oekavan (odeteni i
piteni libovolnho nasobku z1*ec minut nema adn vliv). To nampotvidi vpis
piomnn pd na pedposlednim adku.
Pak vak vypieme i piomnnou p a mona s pekvapenim zjiujete, e se tak
zmnila (pestoe jsme ji po zkopiiovani ji nepouily tj. ani neposunuly). Pekva-
peni by vak nemlo bt tak velk. Stai si uvdomit, e vechny objekty vech
uivatelskch tid jsou iefeiennimi objekty. Jinak eeno piomnna neobsahuje
pimo objekt, ale jen odkaz na nj.
lnicializace nov piomnn pd, tak nevede ke kopiiovani, ale pouze k novmu
odkazu na ji existujici objekt. Jak piomnna d tak pd odkazuji jeden a tent
objekt tidy DenniCas. Je tedy zcela jedno piostednictvim jak piomnn objekt
modikujeme. Vdy dojde ke zmn u obou piomnnch.
lfekt je tedy zcela snadno vysvtliteln. To vak jet neznamena, e je i chtn
i ve vech pipadech snadno piedikovateln. Sdileni objekt toti nemusi mit tak
jednoduchou podobu.
Zkusme napiklad vytvoit seznam dennich as od plnoci (vetn) do poledne
(vetn) po plhodin. Nejjednoduim se jevi vyuiti cyklu while
List<DenniCas> pulhodiny = new List<DenniCas>();
DenniCas idc = new DenniCas(0, 0); / / inicializuj aktualni as (na plnoc)
DenniCas horniMez = new DenniCas(12, 0); / / inicializuje hoini mez
while (!idc.JePozdejiNez(horniMez)) { / / dokud neni as pozdji ne hoini mez
pulhodiny.Add(idc); / / pidej aktualni as do seznamu
idc.PrictiMinuty(30); / / piti k aktualnimu asu plhodinu
}
Uivatelsk tidy 1e,
/ / vypieme vsledn pole (pio stiunost do jedinho adku)
foreach (DenniCas dc in pulhodiny) {
Console.Write(dc + ""); / / poloky budou oddleny mezeiou
}
Ve se jevi v poadku, ale piotoe do seznamu nepidavame asov daj, ale pou-
ze odkaz na nj, ziskavame seznam tyiadvacet shodnch daj 1zIc (). Pole
toti odkazuje na stale stejn objekt, ktei se postupn modikuje (na konci ka-
d iteiace). Posledni dosaen stav iepiesentuje as 1zIc (ten sice ji nespluje
podminku cyklu, ale nastava!). Situaci jet lpe osvtluje obiazek .z na nasledu-
jici stian (je dobe vidt, e bhem iteiaci nevznikaji nov objekty novch as,
jen se zmnouji odkazy na jedin, i kdy stale se mnici, objekt).
Nezbva ne piznat, e nco neni v poadku. Objekt se nechova tak jak by se ml,
a nelze to snadno zmnit. Neexistuje napiklad snadn zpsob jak spiavn napsat
ve uvedenou inicializaci seznamu.
Jedinm eenim je napsat novou a lepi implementaci nai tidy. Tuto pileitost
meme vyuit i pio odstianni dalich dilich nedostatk (kteich si mona Ti
zkuenji ji vimli) a k miinmu vylepeni iozhiani.
Pravidlo 22: Pokud implementace tdy nevyhovuje naim zkladnm poadavkm
nebo vykazuje neoekvan i netn ovn, je vdy lep tdu implementovat
znovu. Vyhneme se tak stle rostoucm problmm a berlikm, kter se sna ne-
dostatky eliminovat.
Toto piavidlo ma samozejm i vjimky. Je-li je implementace tidy pili sloita a
asu neni nazbyt (piogiam musi fungovat pokud mono hned), nezbva mnohdy
nic jinho ne se s pvodni implementaci smiit. Nakonec vak dive i pozdji
piavdpodobn k ieimplementaci stejn dojde.
5.2. Nov implementace (znovu a lpe)
Hlavni zmnou nov a lepi implementace je eliminace nepijemnho efektu sou-
visejiciho se zmnou objektu, na ktei me odkazovat vice iefeienci.
Piotoe nememe idit i uiovat poet iefeienci na objekty uivatelskch tid,
je jedinm eenm pln zabrnit modikaci objektu po jeho vytvoeni (a ini-
cializaci). adna metoda nesmi mnit objekt (tj. adn z jeho komponent) a objekt
tak zstava nemnn a do svho zaniku.
1e8
idc
idc
horniMez
horniMez
0:30
0:30
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
DenniCas
idc
idc
horniMez
horniMez
1:00
1:00
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
1
idc
idc
horniMez
horniMez
12:30
12:30
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
1 23 24 2 22 . . .
Po prvn iteraci
Po druh iteraci
DenniCas
DenniCas
Po posledn (25.) iteraci
Obiazek .z. Piomnn a objekty pi vytvaeni seznamu mnitelnch objekt
Uivatelsk tidy 1e,
Poznmka:
Jazyk C= nabizi i dali a dokonce elegantnji eeni. Hlavni pioblm
toti spoiva v iozpoiu mezi iefeienni implementaci objektu denni-
ho asu (jen je pio objekty bnch uivatelskch tid jedinou mo-
nosti) a piiozenou hodnotovou smantikou asovch hodnot. lden-
tita asovho daje toti neni dana umistnim objektu v pamti, ale
jeho obsahem (tj. uloenm asem). Dva objekty se stejnm asem
jsou de facto identick, i kdy lei na iznch mistech pamti (v zasa-
d me existovat libovoln vzajemn identickch objekt) a naopak,
pokud se objekt zmni, pak mni i svou identitu (pestoe lei stale
na stejnm mist v pamti).
Pio objekty s hodnotovou smantikou je piiozen pouivat hodnoto-
v tidy, ktei automaticky zajiuji kopiiovani objektu pi piazeni
(nova kopie je uloena v jin piomnn, ale je to stale tent objekt!).
Pi zmn objektu se mni jeho identita, ale to nevadi piotoe neni
sdilen viceio piomnnmi. Zmnu tedy lze chapat jako zmnu pio-
mnn (piomnna po zmn obsahuje nov objekt). Tato smantika a
implementace je typicka napiklad pio isla a obecn fyzikalni daje
(mezi n denni as tak pati). U knihovnich standaidnich typ je
pouit napiklad u tidy DateTime
DateTime date1 = DateTime.Now; / / piomnna date1 obsahuje datum
DateTime date2 = date1; / / piomnna datez obsahuje identickou kopii
date1.AddHours(10); / / piomnna date1 obsahuje nov objekt!
/ / datez si vak zachovava pvodni obsah
Jak si vak vynutit hodnotovou implementaci u uivatelskch tid.
Stai pouze na zaatku denice pozmnit kliov slovo class za struct
(stiuktuia hodnotova tida). Ano jen tak malo stai a objekty denni-
ho asu piojevuji svou piiozenou hodnotovou smantiku a piogiam
pio inicializaci hodnot bude beze zmny fungovat (do seznamu se
toti vkladaji kopie hodnot).
Pio tedy toto eeni nepouijeme` Dvodem jsou obecna omezeni
tohoto eeni. Za piv jej nelze vyuit pio objekty, jejich obsah m-
ni svou velikost v pamti (nap. pio seznamy), za diuh u vtich
objekt vede k pomalmu kopiiovani pamti (objekty se pi piaze-
ni nebo pi pedavani do metod musi byte po bytu kopiiovat) a za
teti hodnotov uivatelsk tidy nejsou dostupn ve vech jazycich
1,o
(napiklad nejsou a nikdy nebudou v Jav, Pythonu a PHP). Pistup s
nemnnmi objekty tato omezeni nema. Navic ma i nktei dali v-
hody, jako je snadnji pouivani v paialelnich nap. vicevlaknovch
piogiamech.
Je-li vak objekt denniho asu nemnn, jak budeme implementovat minutov
posun` Natsti namisto modikace stai viatit nov (posunut) objekt (adiesat
se nemni). Bude to sice vyadovat o tiochu pamti navic, ale vice to odpovida
smantice posunu (objektas po posunu neni identick s objektemasem ped
posunem). Ostatni metody (JePozdejiNez a ToString) nemusime modikovat, nebo
adiesata v pvodni implementaci nemni.
Pi ievoluni ieimplementaci se vak nezastavime jen u zmny modikovatelnosti
objektu. Zmnu si zasloui i inteini iepiesentace asovho daje. Pvodni iepie-
sentace pomoci dvou celoiselnch podobjekt ma toti dv zakladni nevhody
1. vyaduje zbyten mnoho pamti. Pio iepiesentaci 111c jednotlivch stav
objektu vyaduje s byt pamti ( z velikost objektu tidy int). Osm byt
dokae iepiesentovat z
ss
stav (adov 1c
1s
). Naopak pio iepiesentaci 111c
stav stai jen
,
log
z
111c
= 11 bit.
z. pio inteini vpoty se lpe hodi lineaini iepiesentace potu minut od pl-
noci. Je to dobe vidt v pvodni metod PrictiMinuty, kde se musi piovst
pepoet do tto iepiesentace a nasledn zpt. Je vhodnji i pio poiovna-
vani asovch daj (viz metoda JePozdejiNez).
Jako viazn vhodnji se pioto jevi iepiesentace pomoci jedinho celoiselnho
objektu tidy int, je bude iepiesentovat poet minut od plnoci. Velikost aloko-
van pamti sice stale neni optimalni (Iz bit), ale je o polovinu meni.
Poznmka:
l kdy by bylo mono pouit i meni celoiseln typ jako nap. short
( 1e bit se znamnkem, dlouh jmno System.Int16), nevede toto sni-
eni k iealn spoe. Z dvod iychlho pistupu k pamti jsou toti
objekty zaiovnany na velikost pamovho slova piocesoiu, ktei je
u dnenich piocesoi minimaln Iz-bitov. Navic se vechny aiitme-
tick vpoty v aiitmeticko-logick jednotce piocesoiu (ALU) piova-
dji v tto ice tj. hodnota se musi stejn ped vpotem pevst na
iepiesentaci shodnou s tidou int.
Namisto sloenho objektu tak dostavame typick adapti. Pvodni objekt (ti-
dy int) ztiaci sv pvodni iozhiani (nema napiklad smysl asov daje nasobit),
Uivatelsk tidy 1,1
misto toho sloui jako zaklad objektu se zcela jinm iozhianim a smantikou.
Dale se pokusime vylepit pvodni implementaci v dalich smiech
1. asto pouivan liteialy nahiadime pojmenovanmi konstantami, ktei l-
pe vyjaduji vznam hodnoty. Tka se to pedevim hodnoty ec (poet mi-
nut v hodin) a 111c (ec * z1), co je poet minut ve dni.
z. umonime pim ale bezpen pistup k dajmo hodin a minut (v iamci
hodiny) piostednictvi nov pidanch vlastnosti
I. zajistime, e objekt denniho asu neni mono adnm zpsobem chybn
inicializovat. To spolu s nemonosti objekt nasledn mnit, zcela zabiani
existenci neplatnch objekt. Pvodni implementace umoovala vytvoit
objekt iepiesentujici nap. as ze1c11.
Nejdive si vypime celou implementaci (vetn testovaciho kodu)
using System; / / dennicas2.cs
using System.Collections.Generic;
class DenniCas {
private int minutyOdPulnoci;
const int MinutVHodine = 60; / /
. V kad iteiaci
je piomnna obsahujici aktualni as pesmiovana na nov objekt, iepiesentujici
as posunut o ticet minut. Pvodni objekt vak nezanika, nebo na nj odkazuje
nov pidana poloka seznamu.
while (!idc.JePozdejiNez(horniMez)) {
pulhodiny.Add(idc); / / pida pvodni objekt do seznamu
idc = idc.PrictiMinuty(30); / / vytvoi nov objekt (ten je pidan v dali iteiaci)
}
V kad iteiaci tak vznikne nov objekt, jen se v nasledujici iteiaci pida do se-
znamu. Seznam tak po ukoneni cyklu odkazuje na z nezavislch objekt, ktei
postupn iepiesentuji asy od ccc do 1zcc. Navic vznikne i ze. objekt, ktei se ji
18
idc
idc
horniMez
horniMez
0:00
0:00
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
idc
idc
horniMez
horniMez
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
1
idc
idc
horniMez
horniMez
12:00
12:00
pulhodiny
pulhodiny
0
List<DenniCas>
DenniCas
1 23 24 2 22 . . .
Po prvn iteraci
Po druh iteraci
Po posledn (25.) iteraci
0:30
0:30
0:00
0:00
0:30
0:30
1:00
1:00
0:00
0:00
0:00
0:00
1:00
1:00
11:00
11:00
11:30
11:30
...
12:00
12:00
12:30
12:30
Obiazek .1. Piomnn a objekty pi vytvaeni seznamu nemnitelnch objekt
Uivatelsk tidy 18
do seznamu nepida (a bude uvolnn po zaniku piomnni idc). Giack znazoi-
nni viz obiazek .1 na pedchozi stian (poiovnejte s obiazkem znazoiujicim
chybn algoiitmus s piomnnm objektem na stian 1es)
+1
= (
) = (
) =
+1
a tak dale. Vznika tak tzv. cyklus.
Unejjednoduich geneiatoi (lineain kongiuennich) ma funkce tvai +,
kde . jsou vhodn zvolen konstanty, piem vpoet se piovadi s -bitovmi
isly (s peteenim). Dlka cyklu je pioto vdy meni nebo iovna z
(zavisi na
hodnotach a ).
Podobnho typu je i standaidni geneiatoi nabizen knihovnou .NlT. Pio nae
ely bohat stai, pokud vak potebujete kvalitnji (pseudo)nahodnost je nut-
n se poohldnout po kvalitnjim geneiatoiu (zaloenm nap. na tzv. Mersenne
Twisteru, jen poskytuje extimn dlouh cykly). Pio ely kiyptogiae je pak
nutn pouivat specialni tidu geneiatoi, ktei musi bt nejen kvalitni, ale i ne-
piedikovateln (tj. musi alespo asten vyuivat haidwaiov geneiatoi, mini-
maln pio svou inicializaci).
=
Hieiaichickou stiuktuiu objektu tidy Cae lze vidt na obiazku . na nasle-
dujici stian. Obiazek ukazuje stav, kdy je vnitni seznam ji asten naplnn
polokami (tj. objekty tidy CaeItem). Konkitn znazoinn stav (vyiovnavaci
pam s temi polokami, z nich jedna je jet nevyuita tj. je iovna null), vznikne
nejdive po diuhm pidani (s piavdpodobnosti z/I), ale me setivavat i po
pozdji. Piavdpodobnost neplnho vyplnni s iostoucim potem pidani iychle
1,8
klesa (po pidanich je iovna
\
z
I
}
1
) . Vimnte si tak, e hodnoty tidy int jsou
uloeny pimo ve svm nadobjektu, nebo int je hodnotov typ,
Cache
CacheItem
data
genertor
CacheItem
int:key int:key
List<CacheItem> Random
[0] [1] [2]
string
value
string
value
null
Obiazek .. Ukazka kompozice objektu tidy Cae
Konstiuktoi nov vyiovnavaci pamti neni zcela tiivialni. Nejdive vytvoi piazd-
n seznam, jeho kapacita je nastavena tak, aby odpovidala vsledn velikosti.
Nasledn seznam vyplni postupnm pidavanim hodnot null na konec seznamu
(iychleji zpsob bohuel neexistuje, u malch vyiovnavacich pamti to vak neni
pili velk pioblm).
public Cache (int initialSize) {
data = new List<CacheItem>(initialSize);
for (int i=0; i<initialSize; i++) {
data.Add(null);
}
}
Nyni se podivejme na implementaci kliovch metod Insert, Contains a Find.
public void Insert(int key, string value) { / /
return i;
}
return -1;
}
public bool Contains(int key) { / /
nebo
1
z
`
=
Pouiti pomocn metody viazn zjednodui implementaci vyhledavacich me-
tod. Ve vech tech dotazovacich metodach stai piovst tiansfoimaci smantiky
pomocn metody (index poloky nebo 1) na smantiku pislun metody. Nej-
jednodui je to v pipad metody Constains
, kteia namisto platnho (tj. ne-
zapoinho) indexu viaci objekt true a na misto indexu 1 objekt false ( objekt
s danm kliem se ve vyiovnavaci pamti nenachazi). Na tiansfoimaci tak stai
pouh poiovnani indexu s nulou.
U obou metod Find je index vyuit k ziskani pislun hodnoty. Pokud je ioven -1
tak se smantika ve shod s naim pvodnim navihem lii. U metody
s jednim
paiametiem tj. bez implicitni hodnoty je vyvolana vjimka (signalizujici nepi-
pustn pouiti metody), u metody
s dodatenm paiametiem (implicitni hod-
notou) je viacena tato implicitni hodnota. Pio zkiaceni zapisu je vak v tomto
pipad namisto konstiukce if pouit tzv. podmnkov opertor.
Uivatelsk tidy :o
Podmnkov opertor
Podminkov opeiatoi je jedinm teinainim opeiatoiem jazyka C=, tj. opeiatoiem
se temi opeiandy. Pvodem je z jazyka C a pioto se vyskytuje v tm identic-
k podob v mnoha souasnch piogiamovacich jazycich (Java, PHP, JavaSciipt,
atd.)
Obecn tvai podminkovho opeiatoiu je
v1 ? v2 : v3
kde viaz v1 je podminka (tj. viaz, jen se musi vyhodnotit na objekt tidy bool)
a viazy v2, v3 mohou bt libovolnho avak spolenho typu (tj. po vyhodnoceni
viaceji objekt stejn tidy).
Nejdive je vyhodnocen pivni opeiand (tj. v1). Je-li vsledkem vyhodnoceni ob-
jekt true, pak je vyhodnocen diuh opeiand (vz) a vsledek jeho vyhodnoceni
se stava hodnotou celho opeiatoiu. Teti opeiand se v tomto pipad vbec ne-
vyhodnocuje (tj. nepiovedou se ani jeho pipadn vedleji efekty). Pokud je vak
vsledkem pivniho viazu objekt false, pak se naopak vyhodnoti teti opeiand
(za znakem ) a diuh zstane nevyhodnocen.
Podivejme se na jednoduch piklad, ale ilustiativni piklad
x > 0 ? x++ : x--
Tento viaz viaci (iseln) objekt, jen byl pvodn uloen v piomnn x (bez
ohledu na platnost podminky!). Pokud je vak podminka splnna (tj. > c) pak se
hodnota piomnn zvi o jedniku (je piovedena postinkiementace), v opanm
pipad se o jedniku snii (je vyhodnocen teti opeiand s postdekiementaci).
l kdy je jeho smantika obdobna konstiukci if, jedna se opeiatoi a nikoliv pikaz.
To viazn ovlivuje syntaktick kontext pouiti
I. ternrn opertor lze vyut uvnit jinho vrazu resp. na mst kde je vraz
oekvn
Teinaini opeiatoi je asto vyuivan v aigumentu pikazu return.
Namisto zapisu
if (podmnka)
return v1;
else
return v2;
:o
tak lze pouit mnohem kompaktnji vaiiantu
return podmnka ? v1 : v2;
Teinaini opeiatoi lze vyuiti ve skutenm paiametiu metod
list.Add(x>=0 ? x : -x)
Toto pidani absolutni hodnoty isla do seznamu je mnohem pehlednji ne
klasick zapis za pomoci if.
if(x>=0)
list.Add(x)
else
list.Add(-x)
Podobn lze teinaini opeiatoi vyuit uvnit indexace
seznam[i >= 0 && i < seznam.Count ? i : 0]
Tento zapis viaci poloku s danm indexem i pokud je tento pipustn, jinak po-
loku pivni ( s indexem c).
Mn asto se teinaini opeiatoi pouiva jako opeiand jinch binainich opeiatoi
x = y / (twoside ? h : h/2.0)
Piomnna twoside obsahuje logick piznak tj. hodnotu typu bool. Vimnte si i
zavoiek kolem podminkovho opeiatoiu. Tento opeiatoi ma velmi nizkou piio-
iitu, take zavoiky se bn objevuji kolem cel podminn asti nikoliv kolem
jeho jednotlivch opeiand.
II. parametry ternrnho opertoru nesm bt pkazy
Nejastji chybou je uvadni pikaz skoku v iamci teinainiho opeiatoiu
x > 0 ? return true : break;
nepipustn je i vyhozeni vjimky
x >= 0 ? 0 : throw Exception("Zapornahodnota");
Uivatelsk tidy :o
5.3.4. Testovac kd
Nyni je ji implementace vyiovnavaci pamti kompletni. Je vak nutno napsat
jet testovaci kod.
class MainClass {
public static void Main(string[] args) {
Random keyGen = new Random();
Cache c = new Cache(5);
int hits = 0;
for (int i=0; i<100; i++) {
int key = (int)keyGen.Next(i - 2, i + 3);
if (c.Contains(key)) {
Console.WriteLine(string.Format("Hit:{0}:{1}",
key, c.Find(key)));
hits++;
} else {
string value = key.ToString();
c.Insert(key, value);
}
}
Console.WriteLine("Totalhits:" + hits);
}
}
Testovaci kod vytvai malou vyiovnavaci pam a pot simuluje sto pistup k ni.
Do vyiovnavaci pamti se ukladaji etzcov iepiesentace malch isel. Kliem
je pislun islo. Tj. napiklad hodnota stiingzc je dostupna pes kli intzc.
To je samozejm jen velmi jednoduch a nepili piaktick piklad (pevod isla
na etzec je iychla opeiace, kteia nemusi bt uiychlovana vyuitim vyiovnavaci
pamti). Pioto tak nezjiujeme as piovedeni, ale jen poet cae hits tj. poet
spnch pistup k vyiovnavaci pamti.
Pistup k vyiovnavaci pamti je simulovan pomoci nahodnch isel. Pokud by byl
pimo pouit geneiatoi, ktei by viacel nahodna isla s iovnominmiozloenim
od c do vv, bylo by spnch pistup do cache jen pomalu (v adu malch jed-
notek). Natsti v iealnch aplikacich neni pistup zcela nahodn, nebo mnoh
pistupy se opakuji a to v nevelk asov vzdalenosti.
:oe
Pioto je simulovano vyuiti, v nm nahodn klie lei v malm iozmezi od z
do + z (vetn), kde vak postupn ioste od c do vv. To zvyuje piavdpodob-
nost, e dojde k opakovanmu pistupu jet ped zapomenutimpvodni hodnoty.
Vstup pak me mit nasledujici tvai (kad sputni viaci samozejm zcela jin
hodnoty, mly by vak mit stejn iozloeni)
Hit: 1:1
Hit: 10:10
Hit: 9:9
Hit: 9:9
Hit: 15:15
Hit: 19:19
Hit: 20:20
Hit: 23:23
Hit: 27:27
Hit: 29:29
Hit: 31:31
Hit: 37:37
Hit: 38:38
Hit: 42:42
Hit: 46:46
Hit: 53:53
Hit: 60:60
Hit: 63:63
Hit: 74:74
Hit: 85:85
Hit: 87:87
Hit: 90:90
Hit: 93:93
Total hits: 23
Vicenasobn sputni (1ccc) ukazalo, e poet spnch zasah kolisa v dosti i-
iokm iozhiani od 1e do 1z (tj. vpis iepiesentuje spie hoii piklad). S malou,
ale nenulovou piavdpodobnosti mohou nastat i situace s meni i vtim potem
zasah (poet zasah ma noimalni iozloeni se stedni hodnotou zs,1e a smio-
datnou odchylkou I,e).
Nae vyiovnavaci pam, zda se, funguje. Jeji datova iepiesentace vak neni stale
optimalni, nebo vyhledavani ma asovou sloitost (), kde je velikost cache.
Pomoci seznamu vak nikdy nedosahneme stavu, kdy ma jak vkladani tak vyhle-
davani sloitost lepi ne () (nejlpe samozejm (1)). Natsti vak zname i
Uivatelsk tidy :o,
kolekce, ktei umoni implementace vyiovnavaci pamti viazn uiychlit. Jed-
nou z nich je kolekce oznaovana jako slovnk, ji bude vnovana cela nasledujici
kapitola.
6. Slovnk
Slovnik (anglicky dictionary) je kolekce iepiesentujici zobiazeni z mnoiny tzv.
kli do mnoiny hodnot (viz e.1). Hlavni opeiaci slovniku je iychl vyhledani
hodnoty podle klie. Zobiazeni se anglicky oznauje slovem map tj. mapovn.
Pioto se jako alteinativni oznaeni slovniku pouiva i teimin map (esky mapo-
vani nikoliv mapa).
instance tdy kl (TKey)
mnoina kl
(Keys)
instance tdy hodnot (TValue)
mnoina hodnot
(Values)
kl
(vzor)
hodnota
(obraz)
zobrazen
dvojice (kl, hodnota)
Obiazek e.1. Slovnik zobiazeni kli na hodnoty
lxistuje nkolik dalich (vzajemn ekvivalentnich) pohled na slovnik
1. slovnik je neuspoadana kolekce dvojic tvoench kliem a hodnotou, kteia
piefeiuje vyhledavani podle klie. Ve slovnik nemohou bt uloeny dvo-
jice se shodnmi klii (v opanm pipad by to ji nebylo jednoznan
zobiazeni).
z. slovnik je piostedek jak iychle tiansfoimovat hodnoty z jedn mnoiny
na mnoinu diuhou (ob mnoiny nemusi bt disjunktni). Tiansfoimace je
dana explicitni tiansfoimani tabulkou.
I. slovnik je dvousloupcova tabulka kteia asociuje (spojuje) klie (unikatni) a
zcv
:1o
hodnoty (obdoba jednoduch databazov tabulky). Pioto je dalim alteina-
tivnim oznaenim slovnik teimin asociativn tabulka i asociativn pole.
Hlavni implementaci slovniku ve standaidni knihovn .NlT je geneiicka tida
System.Collections.Generic. Dictionary.
Mezi zakladni vlastnosti slovniku System.Collections.Generic.Dictionary pati
potencialn neomezen poet poloek (omezenim je pouze velikost adieso-
vho piostoiu a do jist miiy i velikost opeiani pamti)
klie musi bt homogenni tj. objekty kli by mly patit do stejn tidy.
Tato tida je uvadna pi denici seznamu a spiavna typova spiavnost je
kontiolovana ji pi pekladu (pi vkladani i hledani). Tida je foimaln (v
dokumentaci, apod) oznaovana jako TKey.
hodnoty musi bt homogenni tj. objekty hodnot by mly patit do stejn
tidy. Tato tida je uvadna pi denici seznamu a spiavna typova spiavnost
je kontiolovana ji pi pekladu (pi vkladani i ziskavani). Tida je foimaln
(v dokumentaci, apod) oznaovana jako TValue.
Mnoina vech instanci tidy kli (TKey) tvoi nadmnoinu mnoiny aktualnich
kli a mnoina vech instanci tidy hodnot (TValue) je nadmnoina aktualnich
hodnot (viz obiazek e.1 na pedchozi stian). Ve specialnich pipadech me slov-
nik mapovat vechny instance tidy kli (nap. jsou-li klii logick hodnoty nebo
vtov typ s nkolika malo instancemi). Podobn me splvat i mnoina hodnot
s mnoinou vech instanci tidy hodnot.
Tyto vlastnosti seznamu jsou zejm a vychazeji ji z jeho denice, v ni se uvadji
tidy kli a hodnot a naopak se neuvadi (maximalni) velikost. Slovnik vak ma
jet jedno kliov, ale ielativn skiyt omezeni (neni kontiolovano pekladaem)
objekty kli musi bt hodnotov nebo nemnn. V zasad lze dopoiuit
jen objekty tid, je nemnnost zaiuuji, tj. nemaji adnou metodu mnici
adiesata a adnou vlastnost s mutatoiem (seerem). Hodnotov tidy (jako
jsou vechny iseln tidy) lze pouit vdy (slovnik toti uchovava jejich
nemnn kopie).
Piotoe slovnik poaduje, aby byly klie jedinen, hiaje dleitou ioli i poje-
ti ielace shodnosti (ekvivalence). Nad mnoinou kli lze toti denovat velk
mnostvi iznch ielaci ekvivalence, z nich kada me mit sv opodstatnni v
uiitm kontextu. Dokonce i nktei vestavn tidy poskytuji hned nkolik typ
ekvivalence. Zatimco v jedn z ekvivalenci mohou bt objekty shodn (jako nap.
Slovnik :11
etzce s a SUSS), v jin naopak iozdiln. Pio jednoduchost budeme pio-
zatim pedpokladat, e ekvivalence je dana opeiatoiem shodnosti (tj. opeiatoiem
a jeho negaci !).
6.1. Zkladn operace
6.1.1. Definice a naplnn
Denice piomnn tidy Dictionary se svou stiuktuiou nelii od denice poui-
van u jinch geneiickch kolekci
using System.Collections.Generic;
Dictionary<string, int> pocetObyvatel;
Tato piomnna bude odkazovat na slovnik mapujici (zobiazujici) objekty tidy
string (iepiesentujici nap. jmno obce) na objekty tidy int (iepiesentujici poet
obyvatel dan obce). Piozatim vak stejn jako u vech iefeiennich tid, adn
nov objekt nevznikl a piomnna obsahuje hodnotu null.
Pioto je ve vtin pipad pohodlnji a bezpenji piomnnou inicializovat v
iamci denice (inicializanim viazem je volani konstiuktoiu).
Dictionary<string, int> pocetObyvatel = new Dictionary<string, int>();
Piomnna nyni odkazuje piazdn slovnik (tj. slovnik, v nm neni uloena adna
dvojice kli-hodnota).
Dalim kiokem je naplnni (population) nov vznikl instance slovniku. Zaklad-
nim piostedkem je zde stejn jako u seznamu metoda Add. Ta ma na iozdil od
seznamu dva paiametiy pivnim je objekt klie (vzoi v zobiazeni) diuhm ob-
jekt hodnoty (obiaz v zobiazeni). V naem pipad musi bt vzoi objektem tidy
string, a hodnota instanci tidy int.
pocetObyvatel.Add("Decin", 50620);
pocetObyvatel.Add("RoudnicenadLabem", 13114);
Alteinativn lze slovnik inicializovat pomoci indexace. lndexem je v tomto pipa-
d kli a indexovan viaz musi stat na lev stian piazeni.
:1:
pocetObyvatel["Litvinov"] = 18960; / / pida dvojici kli-hodnota
pocetObyvatel["Most"] = 67030;
Oba zpsoby pidani se lii v pipad, kdy je pidavana hodnota s kliem, kte-
i je ji ve slovniku obsaen. V pipad pouiti metody Add je vyvolana vjim-
ka System.ArgumentException (se zpiavou An element with the same key already
exists in the dictionary).
V pipad piazeni do indexovho viazu adna vjimka nevznikne a kli je sva-
zan s novou hodnotou (pvodni dvojice kli-hodnota zanikne).
pocetObyvatel.Add("Decin", 50620); / / vjimka (pestoe je nova hodnota stejna)
naopak
pocetObyvatel["Decin"] = 51621; / / OK, nov poet obyvatel
/ / funguje i
pocetObyvatel["Decin"]++;
O tom jak zpsob vkladani zvolit iozhoduje celkova stiategie pistupu ke slov-
niku.
V zasad existuji ti zakladni stiategie
1) pipustn je vkladani vice hodnot se stejnm kliem. Ve slovniku je zohledn-
no pouze posledni vloeni (aktualizace). V tomto pipad je lze piiozen vyuit
indexaci.
2) pipustn je vkladani vice hodnot se stejnm kliem. Ve slovniku je zohlednno
pouze pivni vkladani (inicializace).
V tomto pipad lze vyuit oba mechanismy vkladani, ty vak musi bt spojeny s
pedbnm testovanim vskytu klie ve slovniku
if (!pocetObyvatel.ContainsKey("Decin"))
pocetObyvatel.Add("Decin", 50620); / / jednou a dost
/ / nebo
if (!pocetObyvatel.ContainsKey("Decin"))
pocetObyvatel["Decin"] = 50620;
3) je zaiueno, e kli se bude vkladat jen jednou nap. ze zdioj u nich je uni-
katnost jista. Zde stai pouivat vkladaci metodu Add. Vjimky vznikne, jen je-li
tento pedpoklad naiuen.
Slovnik :1
6.1.2. Vyhledvn hodnoty podle kle
Nejdleitji opeiaci nad naplnnm slovnikem je vyhledavani poloky podle
klie.
Standaidni iozhiani slovniku nabizi dva mechanismy pio nalezeni hodnoty podle
klie, z nich vak je jen jeden pouiteln i pio zaateniky indexace kliem.
int pocet = pocet.Obyvatel["Decin"];
lndexace v tomto pipad (na lev stian piazeni) funguje jako geer, tj. viaci
hodnotu, na ni se kli zobiazuje (tj. s jakm kliem byla do slovniku vloena).
Nalezeni pislun hodnoty je velmi iychl a v zasad nezavisi na potu dvojic
kli a hodnot v seznamu tj. asova sloitost je (1)!
Co vak nastane v pipad, e ve slovniku neni hodnota s danm kliem` Je zej-
m, e neme bt viacena njaka specialni hodnota, nebo mnoina hodnot me
(alespo potencialn) pokivat vechny pipustn instance tidy hodnot (vet-
n hodnoty null u iefeiennich typ). lndexace bohuel neumouje ani zadani
ad-hoc implicitni hodnoty (viz diskuse v iamci navihu vyiovnavaci pamti, sek-
ce .I.1 na stian 1se).
Jedinm eenim je vyvolani vjimky (tidy KeyNotFoundException). K vyvolani
tto vjimky by vak v bnm piogiamu nemlo nikdy dojit (vjimka signalizuje
chybov stav nikoliv pouhou neexistence klie).
V piaxi se vyuivaji dv zakladni stiategii vyuiti slovnik.
Prvn strategie pedpoklada, e vyhledavany budou jen a pouze existujici klie.
Tuto jistotu lze ziskat piiozenm omezenim mnoiny kli nebo kontiolou ioz-
sahu kli ped jejich pouitim. Pokud budete napiklad zobiazovat GUl tlaitka
na pikazy, ktei vyvolavaji, pak je mnoina kli jasn denovana ( mnoina
vech tlaitek) a neme se stat, e bude pouit neexistujici kli ( stisknuto ne-
existujici tlaitko). Pokud by pesto tato situace nastala, pak je to piznak chyby
v piogiamu (nap. opomenuti vloeni nebo pouiti neplatnho objektu). Vyvola-
ni vjimky je v tomto pipad zcela adekvatni. Podobn lze inteipietovat pouiti
neplatnho klie v piogiamu, ktei mapuje jmna povinnch HTML atiibut na
jejich hodnoty. Neni-li povinn atiibut pitomen ve slovniku, pak je to piznak
chybnho foimatu, ktei ml bt odhalen ji ve fazi validace.
if(imgElement["src"]) { / / element img musi obsahovat atiibut sic
/ / zpiacovani URL obiazku
}
:1
Druh strategii naopak pedpoklada, e i neexistence klie (iesp. hodnoty s da-
nm kliem) nese njakou infoimaci. Pokud napiklad vyuivame slovnik pio po-
itani vskytu slov v textu (slovnik mapuje slovo-etzec na poet vskyt tj. na
cel islo), pak neexistence etzce signalizuje dosavadni nepitomnost slova v
textu. Je toti zejm, e na zaatku zpiacovani nelze vytvoit slovnik vech po-
tencialnich slov (jako kli), ktei jsou vechny mapovany na hodnotu nula (
nula vskyt).
Neexistence klie je v takovmpipad zcela bnou situaci. Na zaatku zpiacova-
ni dokonce viazn pevauje nad situaci, kdy je slovo u uloeno ve slovniku (tj.
alespo jednou se ji vyskytlo). Vznik vjimky (odvozeno od spojeni vjimena
situace) je v tomto pipad zcela neadekvatni ieakce. Vjimku lze sice zachytit a
ieagovat na ni (vloenim novho slova do slovniku), ale je to velmi, velmi pomal.
Pioto je nejdive nutn otestovat existenci klie pomoci metody ContainsKey a k
indexaci pomoci klie pistupovat a v pipad, kdy kli ji existuje (a vjimku tak
zcela eliminovat)
/ / vytvoime piazdn slovnik
Dictionary<string,int> pocetVyskytu = new Dictionary<string,int>();
List<string> text = new List<string>(); / / text iozdlen na slova
...
/ / nateni textu a iozdleni na slova
...
foreach(string slovo in text) {
if(pocetVyskytu.ContainsKey(slovo)) {
pocetVyskytu[slovo] ++; / / zvime poet vskyt o 1, indexace kliem je zde bezpena
}
else {
pocetVyskytu[slovo] = 0; / / vloime do slovniku dvojici slovo -~ c
}
}
lndexace je v tomto piogiamu pouita na dvou mistech a ani v jednom pipad
nezpsobi vjimku. Pi inkiementaci se nejdive ziska pvodni hodnota indexo-
vana kliem (kli musi existovat, ale to zaiuuje podminka konstiukce if ), ta se
zvi o jedniku a vsledek se uloi znovu do slovniku (pod stejnm kliem). Je to
mon, nebo pio vloeni nov hodnoty je pouita indexace a nikoliv metoda Add
(ta by skonila vjimkou, nebo kli u existuje a my chceme pouze aktualizovat
namapovanou hodnotu).
Slovnik :1
Diuha indexace kliem (v sekci else) vklada novou dvojici klie a hodnoty do slov-
niku. Zde by bylo pouiti zapisu pocetVyskytu.Add(slovo, 0) mon (a nkteimi
piogiamatoiy dokonce piefeiovan).
Pravidlo 25: Pi vyhledvn kle ve slovnku pomoc indexace, mus bt bu pe-
dem zejm, e je hodnota s danm klem ve slovnku ji obsaena, nebo mus bt
existence kle testovna pomoc metody ContainsKey.
Poznmka:
Testovani existence klie ve slovniku ped jeho pouitimpio indexaci
neni zcela efektivni, nebo vyaduje dv opeiace vyhledavani. l kdy
je opeiace vyhledavani ielativn iychla, neni zcela zanedbatelna. Po-
kud je napiklad pouivana v asto opakovanm kodu (tzv. tsnm
cyklu), me vst k tm dvojnasobnmu zpomaleni piogiamu (ten-
to scna vyuiti slovniku neni natsti pili bn).
Z tohoto dvodu nabizi iozhiani tidy Dictionary metodu TryGetVa-
lue. Tato metoda poskytuje v iamci jedinho volani jak testovani pi-
tomnosti klie, tak jeho (pipadn) ziskani.
Signatuia metody
public bool TryGetValue(TKey key, out TValue value)
Je zejm, e metoda viaci logickou hodnotu (signalizujici pitomnost
i nepitomnost klie), a pivnim paiametiem je hledan kli. Diuh
paiameti je vak netypick. Kliov slovo out uiuje, e se jedna o
tzv. vstupn parametr.
Zatimco bn (vstupni paiametiy) sloui k penosu objekt nebo od-
kaz na objekty dovnit metody ped jejim vykonanim, ma vstupni
paiameti piav opanou funkci sloui k penosu infoimaci zevnit
metody ven po jejimdokoneni. Tuto funkci ma bn naviatova hod-
nota, vstupni paiametiy vak nabizeji monost viaceni nkolika ob-
jekt zaiove.
Detailnji popis vstupnich paiameti najdete v piloze (sekce B.1
na stian zs1). V tuto chvili Vam postauje vdt, e pi volani meto-
dy je nutno na mist vstupniho paiametiu uvst neinicializovanou
piomnnou opatenou takt kliovm slovem out. Do tto piomn-
n se uloi vstupni objekt (iesp. odkaz na nj) a bude tak dostupn
i po ukoneni metody, v ni vznikl. V pipad metody TryGetValue
se do pedan piomnn uloi hodnota pisluna ke klii (je-li dan
:1e
kli pitomen), nebo hodnota null (je-li tida hodnot iefeienni) nebo
nulova hodnota (u hodnotovch)
Podivejme se jak vypada implementace itae slov za pomoci metody
TryGetValue a vstupni piomnn
/ / vytvoime piazdn slovnik
Dictionary<string,int> pocetVyskytu = new Dictionary<string,int>();
List<string> text = new List<string>(); / / text iozdlen na slova
...
/ / nateni textu a iozdleni na slova
...
foreach(string slovo in text) {
int frequency;
/ / neinicializovana piomnna, do ni se uloi vstupni paiameti
if(pocetVyskytu.TryGetValue(slovo, out frequency)) {
pocetVyskytu[slovo] = frequency + 1;
}
else {
pocetVyskytu[slovo] = 0;
}
}
6.2. Vyuit slovnku
Slovnik je velmi uitena kolekce, kteia se uplatni ve vech typech aplikaci. Je do-
konce tak uitena, e je asto uivana nadbyten na misto konstiukci, ktei jsou
mnohem efektivnji. Stava se to pedevim piogiamatoim, ktei jsou zvykli na
piogiamovaci jazyky jako je Perl nebo JavaScript, v nich hiaji slovniky kliovou
syntaktickou ioli (v C= je slovnik jen jednou z mnoha kolekci).
My se nyni detailnji podivame na tyi oblasti vyuiti slovniku
mal aktivni databaze uloen v opeiani pamti
idk seznamy (pole)
vyiovnavaci pamti
ita vskyt
Slovnik :1,
6.2.1. Databze v pamti
Slovnik umouje ielativn snadno iepiesentovat stiuktuiy podobn tabulkam
ielanich databazi. Relani databazov tabulky jsou tvoeny zaznamy (adky) o
pevn lineaini stiuktue. Kad jednotliv zaznam se sklada z nkolika elemen-
tainich daj (isel, etzc, apod.), piem alespo jeden daj hiaje ioli piimai-
niho klie, tj. hodnoty podle ni se zaznam identikuje, Piimaini kli musi bt v
iamci tabulky unikatni.
Stejn daj lze v OOP jazyce iepiesentovat jako objekt sloen z podobjekt ele-
mentainich tid. Tato iepiesentace vak neumouje iychl vyhledavani v kolekci
objekt-daj. Kliov daj je vak mono z objektu vyjmout a pouit ji jako kli
ve slovniku. Tento kli pak identikuje objekt iepiesentujici cel zaznam.
Vztah mezi databazovou tabulkou a odpovidajici slovnikovou iepiesentaci ukazu-
je obiazek e.z (viazn zjednoduena databaze piodej aut).
SPZ typ datum prodeje
5U6 1705 Trabant 2012-11-20
3U2 1458 Volo 2010-08-20
SPZ typ datum!prodeje
"tr#n$%&5U6 1705& "tr#n$%&Trabant& 'ateT#me% 2012-11-20
Sp( Typ 'atumProdeje
"tr#n$%&5U6 1705&
"tr#n$%&3U2 1458& "tr#n$%&Volo& 'ateT#me% 2010-08-20
Sp( Typ 'atumProdeje
"tr#n$%&3U2 1458&
)utoProdej
)utoProdej
"lon*+ , #n"tan-e t.*dy '#-t#onary/"tr#n$0 )utoprodej1
(2(nam 3.2de+4
pr#m2rn* +l*5 3atr#but4
rela5n*
tabul+a
+l*5 3"lon*+u4
obje+t 36odnota "lon*+u4
atr#but
dato7 5len
re"p8 la"tno"t
Obiazek e.z. Slovnik jako iepiesentace ielani tabulky
:18
Vimnte si, e v dan iepiesentaci je atiibut slouici jako kli (SPZ') uloen dva-
kiat. Jednou jako souast objektu iepiesentujicim zaznam ( instance tidy Au-
toProdej), podiuh pak jako kli slovniku identikujici dan zaznam. Je pitom
zejm, e oba objekty musi bt v iamci dan dvojice kli-hodnota shodn.
Tato duplikace se me zdat nadbytena (stail by jen objekt ve funkci klie). Zvy-
uje to poadavky na pam a pinai pioblmy v pipad, e piogiamova chyba
vede k nekonzistentnimu stavu, kdy kli identikuje zaznam s jinou hodnotou
kliov vlastnosti-atiibutu. Zven pamov naioky nejsou silnm piotiaigu-
mentem, nebo ve skutenosti jak kli tak hodnota bn odkazuji stejn objekt
v pamti, v naem pipad tedy stejn etzec (samozejm jen u iefeiennich
tid). Zveni je tak pouze v adu jednotek byt na zaznam. Potencialni pioblm
s nekonzistenci je mnohem zavanji.
Na diuhou stianu zahinuti klie do objektu iepiesentujiciho cel zaznam usnad-
uje jeho zpiacovani. Objekty-zaznamy jsou dale zpiacovavany (tj. jsou paiamet-
iy dalich metod) a pio zpiacovani je ve vtin pipad nutn cel objekt vetn
svho klie. Napiklad pi zobiazeni daje o piodeji auta by mla bt zobiazen
i statni poznavaci znaka. Pokud by nebyla obsaena v objektu-zaznamu, musela
by bt pedavana jako dali paiameti i ped zpiacovanimdo zaznamu pidavana.
To by zbyten komplikovalo piogiam a navic by to mohlo vst ke stejn nekon-
zistenci jako v pipad duplicitniho uloeni. Nekonzistence by byla sice omezena
jen na zpiacovavajici metody, ale efekt by byl obdobn.
Nejdleitjimpiotiaigumentemje vak velmi mala piavdpodobnost vzniku ne-
konzistence pi dodiovani nkolika elementainich zasad
objekty iepiesentujici zaznamy by mly bt nemnn (tj. po vzniku objektu
nelze kli, jen je v nm uloen, mnit)
pi vkladani je nutno vyuit kli ziskan pimo z objektu
Tj. pi ukladani zaznamu o piodeji auta je nutno vyuit vlastnost zpistupujici
kliov atiibut (SPZ).
class AutoProdej {
public string Spz {get; private set;} / / automaticka vlastnost
public string Typ {get; private set;}
public DateTime DatumProdeje {get; private set;}
public AutoProdej(string spz, string typ, DateTime datumProdeje) {
'ocialn je SPZ oznaovana jako registran znaka, ale identikatoiu RZ by tm nikdo neiozuml
Slovnik :1,
this.Spz = spz;
this.Typ = typ;
this.DatumProdeje = datumProdeje;
}
}
...
/ / pidani novho zaznamu do slovniku
AutoProdej auto =
new AutoProdej("5U61705", "Trabant", new DateTime(2012, 11, 20));
prodeje.Append( auto.Spz, auto ); / / kli auto.Spz (plati a vdy bude platit)
/ / nebo
prodeje[ auto.SPZ ] = auto;
Nyni ji vime jak tabulkova data iepiesentovat pomoci slovniku. Otazkou vak
zstava, pio to vbec dlat, kdy existuji ielani databazov systmy, ktei jsou
dnes bnou souasti vvojovch piostedi a pio zpiacovani tabulkovch dat jsou
optimalizovany.
Slovniky maji navic opioti ielanim databazim nkolik limit
1. velikost slovniku je ovlivnna velikosti dostupn pamti (velikost opeia-
ni pamti je hoini mezi, ve skutenosti ji vyuivaji i dali piocesy). To pi
souasn velikosti opeianich pamti (jednotky GiB) znamena, e poet po-
loek (dvojic kli-hodnota) je omezen na miliony.
z. piopojeni dat mezi tabulkami neni tak snadn jako v pipad ielanich da-
tabazi. Zatimco v ielanich databazich existuje vestavna podpoia ielaci, je
piopojeni slovnik ponkud sloitji (je to sice mon, ale nevyuiva se
pili iozhiani slovnik a bez pouiti LlNQ je to i syntakticky neohiaban)
I. slovniky nejsou peisistentni, tj. po ukoneni bhu aplikace zanikaji (vetn
nahlho peiueni typu vpadku napajeni)
Na diuh stian jsou slovniky extimn iychl (ve vtin pipad jsou dokon-
ce iychleji ne ielani databaze umistn v pamti) a maji mnohem jednodui
iozhiani.
Slovniky se pioto nejastji vyuivaji pio
iepiesentaci jednoduchch tiansfoimaci hodnot jednoho diuhu na diuh
(s ielativn malm potem monch tiansfoimaci). Typickm pikladem
jsou iselniky pevadjici identikatoiy na inteini iepiesentaci (typicky i-
selnou, odtud nazev). Pikladem budi pevod jmen bankovnich stav na
::o
identikani kod uivan v islech bankovniho t. Poet poloek v tako-
vto databazi je omezen. iselnik se bn plni z konguianiho souboiu
pi staitu aplikace a pak se ji nemni.
doasn iv databaze, ktei se iychle mni s ohledem na aktualni kontext.
Pikladem me bt slovnik mapujici jmna pihlaench uivatel na ko-
munikani kanaly (nap. TCP/lP sockety) v instant-messaging seiveiu. Tato
databaze se velmi iychle mni (uivatel se stale pihlauji a odhlauji) a po
pipadnm ukoneni bhu seiveiu ji nejsou (a nikdy nebudou) poteba.
Velikost slovniku me bt v tomto pipad ielativn velka (tisice i deseti-
tisice uivatel), pamov naioky vak zstavaji iozumn (jednotky MiB)
6.2.2. dk seznamy
Seznamy jsou lineainimi kolekcemi, u nich je piefeiovanou opeiaci iychla inde-
xace. VC= maji svou piiozenou iepiesentaci ve tid System.Colllections..Generic.-
List. Obdobnou iepiesentaci maji i tzv. pole (pole maji v C= na iozdil od seznam
pevnou velikost). Polokami seznam mohou bt seznamy, co umouje snadno
iepiesentovat dvojiozmina (a v zasad i viceiozmina data).
Seznamy (iesp. seznamy seznam) jsou optimalni iepiesentaci lineainich (iesp.
dvojiozminch maticovch dat), avak neplati to ve vech pipadech. Podivejte
se na typick list tabulkovho piocesoiu (obiazek e.I na nasledujici stian)
Pedstavte si, e bychom mli podobn tabulkov kalkulatoi napiogiamovat. Jak
budete iepiesentovat list (sheet) v pamti` Zvolite piiozenou iepiesentace dvoj-
iovovm seznamem`
V piv ad si musite uvdomit, e viditelna ast listu vak tvoi jen malou ast
viitualniho listu. LibreOce tabulkov kalkulatoi podpoiuje z
1c
sloupc a z
zc
ad-
k, tj. dokae adiesovat z
Ic
(1c
v
) bunk. Pokud by byl list iepiesentovan dvoj-
iovovm pole. pak by zaujimal minimaln 1 GiB pamti (i pouh odkaz null
zaujima ve Iz-bitovm systmu 1 byty pamti). Jinak eeno, iepiesentace listu
by se na vtin poita nevela do opeiani pamti a i v pipad poita s vice
ne 1 GiB by zaujimala jeji podstatnou ast (do zbytku se musi vejit ostatni listy
a samozejm i dali aktualni piocesy).
Ve skutenosti je ale valna vtina z vice ne miliaidy bunk piazdna. Optimalnim
eenimje iepiesentace jen tch bunk, ktei nejsou piazdn (tj. neobsahuji adn
text i vzoiec). Aby vak byla zachovana iychla odezva, musi bt k dispozici iychla
indexace (tj. nalezeni buky podle jeji adiesy adku a sloupce).
Slovnik ::1
Obiazek e.I. List tabulkovho piocesoiu idk pole
Uvaujme pioto, zda by vhodnm kandidatem pio iepiesentaci list nebyl slov-
nik. Kliem by byla dvojice dvou celch isel tj. zD adiesa buky, hodnotou pak
objekt iepiesentujici buku (jeji obsah a foimatovani). Pi zobiazeni nebo vpo-
tech lze snadno a iychle zjistit zda je buka piazdna i nikoliv (pomoci testovani
existence klie-adiesy ve slovniku metodou ContainsKey). Podobn je snadn zis-
kani infoimace o nepiazdn buce (pomoci indexace kliem). Pamov naioky
jsou dany potem uloench dvojic tj. odpovidaji potu vyplnnch bunk (bn
v adu maximaln tisic).
Meme vak dvojici objekt pouit jako kli slovniku` Pimo samozejm niko-
liv, meme je vak uzavit do kompozitniho objektu pepravky. Bohuel na to
nestai nestai jednoducha tida s automatickmi vlastnosti pio kad podobjekt
a konstiuktoiem pio jejich spojeni (jako byla nap. pepiavka CaeItem imple-
mentovana v sekci zainajici na stian 1vc). lnteini iepiesentace slovniku vya-
duje podpoiu nkolika dalich metod (viz nie).
Nejjednoduim eenim je vyuiti kolekce s nazvem n-tice (angl. tuple).
:::
N-tice (tuple)
N-tice je velmi jednoducha kolekce, umoujici iepiesentovat libovoln n-tice
objekt (v C= je od veize 1.c ). Poet objekt (tj. ) je pevn dan u pi denici
(navic je maximalni pouitelna velikost n-tice omezena, piem omezeni zavisi
na veizi knihovny, bezpen jsou podpoiovany alespo sedmice). Na diuh stia-
n me n-tice obsahovat i hodnoty iznch navzajem nesouvisejicich tid. Typ
kad poloky musi bt explicitn uien ji pi denici.
Objekty n-tice jsou vytvaeny konstiuktoiem, jemu jsou pedany vechny polo-
ky (piem zalei na poadi). Po vytvoeni objektu n-tice lze ziskavat jednotliv
uloen poloky pomoci vlastnosti Item1, Item2 a ItemN. Poadi je pimou sou-
asti identikatoiu, nikoliv bnm indexem (ten by byl v hianatch zavoikach).
Poet poloek je natsti velmi mal (v piaxi se pouivaji nejastji jen dvojice a
tiojice).
Uveme si mal (piozatim uml) piklad dvojice (tj. z-tice)
Tuple<string, int> tuple = new Tuple<string, int>("Frodo", 42); / / vytvoeni
Console.WriteLine(tuple.Item1); / / vypie liodo
Console.WriteLine(tuple.Item2); / / vypie 1z
Vytvoeni je tiochu iozvlan, nebo je nutno dvakiat specikovat typ kad po-
loky. Nae ukazkova dvojice bude sloena z etzce (pivni poloka) a celho is-
la (diuha poloka). Pouiti je u snadn. Vlastnost Item1 viaci etzec, vlastnost
Item2 islo.Tida naviatov hodnoty zavisi na typu poloky specikovan v de-
nici n-tice.
Vytvoena n-tice kiom zakladnich metod podpoiuje i poiovnani a obsahuje i
podpoiu pouiti na mist klie ve slovnicich (tj. iozumn pedenovava metodu
GetHash).
=
S vyuitim n-tice je implementace tabulkovho listu snadna. Slovnik pio ukladani
jednotlivch bunk je mono vyuivat pimo, ale pohodlnji a bezpenji je
vyuiti adapti tj. objekt nov vytvoeni tidy, ktei v sob ukivaji pislun
slovnik, nabizeji vak mnohemjednodui iozhiani. Nai adaptani tidu nazveme
Sheet.
class Sheet {
private Dictionary<Tuple<int,int>, string> sheet =
new Dictionary<Tuple<int, int>, string>();
Slovnik ::
public void SetCell(int row, int column, string context) {
Tuple<int, int> address = new Tuple<int, int>(row, column);
sheet[address] = context;
}
public string GetCell(int row, int column) {
Tuple<int,int> address = new Tuple<int, int>(row, column);
return sheet.ContainsKey(address) ? sheet[address] : "";
}
}
Objekt tidy Sheet obsahuje jen jedin podobjekt (je to tudi piav adapti)
slovnik mapujici dvojice celch isel na etzec iepiesentujici textov obsah bu-
ky (skutena implementace by samozejm vyadovala sloitji objekt).
Rozhiani nabizi jen kliov metody pio vloeni obsahu do buky a jeho optn
ziskani. Uobou metod je adiesa pedavana jako dvojice paiameti (tj. zvla adek
a zvla sloupec). Repiesentace kli pomoci n-tic je implementani detail a me
bt v dalim vvoji zmnn.
V obou metodach je nejdive vytvoena adiesa (tj. dvojice) z obou pedanch pa-
iameti. Pio uloeni je vyuita indexace, nebo pouita adiesa nemusi bt jedi-
nena. Pi pouiti stejn adiesy se zmni pisluna hodnota (tj. pepie se obsah
buky). Naopak pi teni je nutno eit i pistup k nedenovanmu klii (tj. k
piazdn buce, jich je valna vtina). Pioto je nejdive testovana existence kli-
e metodou ContainsKey. Pokud kli existuje, pak je viacena pisluna hodnota
(obsah buky), jinak je viacen piazdn etzec. Alteinativn lze viatit i hodno-
tu null. Viaceni piazdnho etzce je pohodlnji (pijemce nemusi testovat zda
byl viacen skuten objekt), vynucuje si vak model, v nm je piazdna buka
ekvivalentni buce obsahujici piazdn etzec (co je iozumn pedpoklad).
Kiom listu tabulkovch kalkulatoi existuji i dali idk matice, pole i sezna-
my. Obecn je to jakkoliv kolekce, kteia obsahuje jeden a tent objekt tolikiat,
e to tvoi vtinu (tzv. dominantni pivek). Nemusi to bt nutn nula nebo null.
Dleit je jen podil pislunho objektu. Hianice neni ostia a zavisi na typu ob-
jektu iesp. na inteini iepiesentace (nap. podil ped vc je ji iozhodn piznakem
idkosti, nebo je nutno explicitn ukladat jen zbvajicich mn ne 1c poloek).
Pikadem idkho seznamu je napiklad tabulka potu plnch zatmni Slunce
viditelnch na naemzemi podle jednotlivch let. Vposlednimtisicileti obsahuje
::
povtinou nulu ( adn zatmni) s vjimkou let 1ce a 111 (dali bude a ioku
z1I).
6.2.3. Vyrovnvac pam
Na pivni pohled se slovnik me jevit jako dokonala implementace vyiovnavaci
pamti. Ma podobn iozhiani, nebo uklada hodnoty spolu s kliem a ob nejd-
leitji opeiace tj. uloeni a vyhledani podle klie jsou velmi iychl (iychleji ne
podobn opeiace nad seznamem).
Ob kolekce se vak lii v jednom avak podstatnm iysu vyiovnavaci pam
ma omezenou velikost a musi tudi zapominat uloen hodnoty, slovnik je alespo
potencialn neohianien.
Bohuel piav zapominani se ve slovniku obtin implementuje. l kdy existuje
nkolik stiategii zapominani, adna z nich se neda efektivn implementovat nad
slovnikem.
Nhodn zapomnn (implementovan v pikladu uvedenm v sekci .I na stia-
n 1s) vyaduje nahodn pistup k pivkm dan kolekce. To je mon jen u ko-
lekci s lineaini indexaci. Slovnik vak lineaini indexaci nepodpoiuje, tj. nelze pi-
stupovat ke klim a hodnotam podle jejich poadi (nelze tedy nap. ici, kteia z
hodnot je uloena na diuh i teti pozici).
Podobn nelze vyuit stiategii uvolnn nejdle alokovan poloky (stiategie lllO).
Slovnik si toti nepamatuje v jakmpoadi byly poloky vkladany a pi piochazeni
je viaci ve zcela jinm poadi (ktei vak neni na diuh stian nahodn).
eeni samozejm existuje, je vak nutno slovnik doplnit o pomocnou kolekci,
kteia uklada jen klie (tj. klie jsou uloeny jak ve slovniku tak v tto pomocn
kolekci). Stiuktuia pomocn kolekce zavisi na poadovan stiategii zapominani.
U nahodnho to me bt (pozin indexovateln) seznam kli, u stiategie lllO
pak fionta (tida System.Collections.Generic.eue, viz http://msdn.microsoft.com/
en-us/library/7977ey2c.aspx) kli. Ukazkovou implementaci vyiovnavaci pamti
najdete v piloze (viz sekce C.1 na stian zs).
6.2.4. ta vskyt
Poslednim klasickm vyuitim slovniku je podpoia algoiitm poitajicich poet
vskyt uiit hodnoty v posloupnosti. Algoiitmy tohoto diuhu se pouivaji pe-
Slovnik ::
devim v piogiamech zamench na statistick zpiacovani dat, v menim mit-
ku se vak vyskytuji i v jinch typech aplikaci, ktei obas piovadji mala lokalni
statisticka zpiacovani (kdo se kolikiat pihlasil. kolikiat byl pehian audio souboi,
apod.).
Veejn iozhiani itae vskyt musi poskytovat minimaln dv kliov metody.
Pivni metoda (vkladaci) je volana pi vskytu pislun hodnoty (smantika z
pohledu tto hodnoty vyskytla jsem se, zapoitej mn), diuha (dotazovaci) viaci
pibn poet vskytu hodnoty (tj. poet aktivaci pivni metody s paiametiem
iovnmdotazovan hodnot, a to od vzniku itae do okamiku volani dotazovaci
metody).
ita lze tak inteipietovat jako pamov nenaionou iepiesentaci tzv. multi-
mnoiny. Multimnoina me obsahovat pivek vicekiat (piem nelze odliit jed-
notliv vskyty pivku v mnoin). Vkladaci opeiace je v tto iepiesentaci pida-
nim pivku do mnoiny, opeiace vyhledavaci pak zjitnim potu vskytu danho
pivku v multimnoin.
Poznmka:
Bnou mnoinu lze chapat jako specialni pikladem multimnoiny
(kad pivek je v mnoin piav jednou). Pioto lze i mnoiny iepie-
sentovat slovnikem. Mnoina je v tto implementaci iepiesentovana
klii, pisluna hodnota (obiaz zobiazeni) me bt sdilena vemi kli-
i (nema adnou infoimani hodnotu, dleita je pouze pitomnost
klie). Pio iepiesentaci mnoin vak od veize C= I.c existuje speci-
alizovana kolekce Set<TKey>, kteia vyuiva hashovaci tabulku neu-
kladajici hodnotu. To nejen sniuje pamovou naionost, ale tak
usnaduje pouiti (mnoina je napiklad pimo iteiovatelna, stejn
jako seznam).
lmplementace itae vskyt nad slovnikem je jednoducha a pitom dostaten
efektivni. Jadio implementace bylo uvedeno ji v sekci e.1.z na stian z1I, ale pio
jistotu si ji zopakujme. Vkladaci metody (v naem ukazkovm zdiojovm kodu je
oznaena identikatoiem Insert) testuje, zda byl objekt vloen dive (tj. existuje
dvojice s danm kliem). Pokud existuje, je pisluna hodnota ( poet vskyt)
zvena o jedniku. Jinak je vytvoena nova dvojice, piem hodnota je iovna
jedn ( piozatim jeden vskyt).
class Counter {
private Dictionary<string, int> c = new Dictionary<string, int>();
/ / podkladov slovnik
::e
public void Insert(string s) {
if (c.ContainsKey(s)) {
c[s]++;
} else
c[s] = 1;
}
public int Frequency(string s) {
return c.ContainsKey(s) ? c[s] : 0;
}
}
Vyhledavaci metodu (zde oznaena jako Frequency) lze pi pouiti podminkov-
ho opeiatoiu zapsat na jedinm adku. Je-li hledan objekt obsaen ve slovniku
jako kli, je viacena pisluna hodnota (tj. poet vskyt). V opanm pipad je
viacena nula ( adn vskyt). Vimnte si, e ani v tomto pipad nedochazi ke
vzniku (pomal a nechtn) vjimky pi pistupu ke slovniku.
l kdy je iepiesentace itae pomoci slovniku elegantni a efektivni, existuji i jin
alteinativy. Lze-li objekty snadno jednoznan zobiazit na cela isla v inteival c
a , pak je efektivnji iepiesentaci itae seznam isel. Seznam o pivcich musi
na zaatku obsahovat nuly. Pi vskytu stai zvit o jedniku poloku s danm
indexem. Alteinativni iepiesentace me bt vhodnji i v pipad, kdy je po
skoneni statistickho zpiacovani vyadovan vpis poloek s nejvyi fiekven-
ci vskyt. Slovnik neumouje pim vyhledani klie s nejvyi etnosti (iesp.
dokonce klie s -tou nejvyi etnosti).
6.3. Intern representace slovnku
lnteini iepiesentace objekt by mla zstavat skiyta (u jen pioto, e se me
mnit). V pipad kolekci je vak alespo astena znalost inteini iepiesentace
uitena, nebo umouje snadno odhadnout jejich (piminou) efektivitu a na-
znait situace, kdy je nutno poitat s viazn pomalejim bhem (tj. kdy me
bt vyuiti pinejmenim pioblematick). Tyto infoimace lze sice ziskat i detail-
nim studiem dokumentace (nikoliv vak MSDN, ta bohuel neni pili detailni).
Alespo iamcova znalost implementace Vam vak viazn usnadni zapamatova-
ni kliovch chaiakteiistik (vichni bohuel nemaji fotogiackou pam).
Slovnik ::,
Slovnik Dictionary<TKey, TValue> je implementovan jako otevena hashovaci ta-
bulka (angl. open hashtable). Zakladni datovou stiuktuiou hashovaci tabulky je
seznam o polokach. Tento seznam je na zaatku piazdn, tj situace je tak ale-
spo na poatku podobna bnmu seznamu.
Zcela jinak je ale implementovana opeiace vloeni. Pivnimkiokemje aplikace tzv.
hashovaci funkce na objekt klie. Tato funkce zobiazuje mnoinu vech instanci
tidy kli na isla c a 1. Vsledek hashovaci funkce pak pouijeme jako
index do hashovaci tabulky, ktei uiuje na jakou pozici vloime objekt-hodnotu.
Zakladni implementace vkladani je tedy tiivialni
[()] =
kde je hashovaci tabulka
je hashovaci funkce
je kli
je (ukladana hodnota)
Opeiace hledani je inveizni, index ziskan aplikaci hashovaci funkce na kli je
vyuit k ziskani uloen hodnoty (co je opeiace, je nezavisi na potu pivk tj.
ma sloitost (1)).
Nemusite bt matematiti gniov, abyste si poloili otazku, jak vlastn hashovaci
funkce zajisti, e se jednotliv (vzajemn odlin) klie mapuji na izn indexy v
hashovaci tabulce`
Odpov je jednoducha. Hashovac funkce nic takovho nezajiuje a obecn nem-
e jedinenost index vbec zajistit. Dokazat toto tvizeni neni sloit. Pedpokla-
dejme, e tidou kli je tida string. Zkusme odhadnout kolik iznch etzc (tj.
instanci tidy string) existuje. Pokud by byly etzce jen jednoznakov, existovalo
by tolik etzc, kolik je pipustnch znak v basic multilingual plane standai-
du Unicode. Pesn poet neni snadn zjistit (nktei znaky mohou bt pouity
jen v kombinaci s jinmi), ale nam postai hiub odhad z
1e
znak (to je po-
et znak kodovatelnch pomoci 1e bit, skuten poet je jen o pai piocent nii
viz http://en.wikipedia.org/wiki/Plane_%28Unicode%29). Poet potencialn iepiesen-
tovatelnch -znakovch etzc je z
1e
, tj. ji pio dvouznakov etzce je poet
potencialnich etzc adov shodn s potem byt opeiani pamti souasnch
osobnich poita (1 GiB z
Ic
byt). To znamena, e hashovaci tabulka na ni by
se jednoznan mapovaly vechny potencialn existujici dvojznakov etzce, by
::8
se nevela do opeiani pamti (kada poloka by musela zaujimat minimaln s
byt, nebo to je velikost odkazu ve e1 bitovch systmech). Velikosti opeianich
pamti sice pozvolna iostou, ale velikosti v adu z
e1
1e liB v blizk budouc-
nosti uiit nedosahnou. l takto obiovska pam by vak nezajistila jednoznan
indexy ani pio tyznakov etzce. Podobna situace je u vech tid s vicebytovou
iepiesentaci (nap. DateTime, double a v meni mie i int).
Jednoznanost mapovani kli na indexy tak nelze adnm zpsobem zajistit a
vdy musi dochazet k tzv. kolizim tj. dva izn klie jsou hashovaci funkci pe-
vedeny na stejn index v hashovaci tabulce. Hlavnim cilem inteini iepiesentace
je kolize co nejvice minimalizovat a pokud u vzniknou, pak je co nejefektivnji
vyeit.
Pio zajitni co nejmeniho potu kolizi pi zachovani iozumnch poadavk na
pam je nutno
1. zvolit optimalni hashovaci funkci
z. zvolit optimalni velikost hashovaci tabulky
Hashovaci funkce by mla pio nahodn vbi kli viacet indexy, ktei co nej-
iovnominji pokivaji iozsah [c. ) (kde je velikost hashovaci tabulky). Jinak
eeno pio nahodn zvolen klie, by se vypoitan indexy nemly kumulovat
kolem uiitch hodnot index, iesp. nechavat uiit asti tabulky zcela nevyui-
t. Navic by ml bt vpoet index velmi iychl (maximaln nkolik malo takt
piocesoiu)
Podivejme se napiklad na nkolik pipad potencialnich hashovacich funkci nad
klii tidy int.
1) () = ( je pedem zvolena celoiselna konstanta z inteivalu [c. ))
Nejhoii pipad hashovaci funkce. Kolize nastavaji pi kadm pistupu, zbytek
tabulky (s indexem ) je nevyuit.
z) () = sin(/1cc) ( 1)
Relativn iozumna hashovaci funkce, viacejici hodnoty v iozmezi [c. ). Hodnoty
blizk 1 jsou vak piavdpodobnji ne hodnoty kolem blizk nule (viz pi-
bh funkce sinus a hlavn jeji piv deiivace). Hlavnim pioblmem je vak vysoka
naionost vpot v pohybliv adov aice (pedevim funkce sinus).
I) () = mod
Nejastji hashovaci funkce pio iseln klie. Je velmi iychla (jedina instiukce
vykonavana ALU) a pio klie s iovnominm iozloenim iovnomin pokiva
Slovnik ::,
iozsah index. l tato funkce ma sva omezeni. Nehodi se pili pio mal mnoiny
kli a pokud jsou hodnoty pouitch kli nasobkem velikosti hashovaci tabulky
nebo jeho libovolnho netiivialniho dlitele, pak viaci jen indexy z velmi omezen
(v extimnim pipad jednopivkov). Pioto neme bt volba velikosti hashovaci
tabulky zcela libovolna. Nelze vyuit isla s velkm potem dlitel jako je nap.
1z, mocniny dvou nebo mocniny desitky, nebo na n se hodnoty bn zaokiouh-
luji). Nejastji se pioto voli pivoislo nebo islo, ktei nema mal dlitele.
Velikost hashovaci tabulky zavisi piimain na potu uloench pai klie-hodnota
(dale oznaovan jako ) (tj. nikoliv na potu vech potencialnich kli). Pokud je
velikost hashovaci tabulky meni ne poet uloench kli ( < ), pak uiit
dochazi ke kolizim (v tabulce je minimaln ) kolizi, ale v piaxi jich je samo-
zejm vice. U tabulek, jejich velikost je vti ne poet uloench kli me bt
dosaeno peifektniho hashovani ( bezkolizniho), ale v pipad univeizalnich ha-
shovacich funkci ke kolizim dochazi i v tomto pipad, natsti s ielativn malou
etnosti.
Pio ilustiaci se podivejme na etnost kolizi pi hashovani velkho potu etz-
c (obiazek e.1 na nasledujici stian). Pio testovani byl pouit seznam pijmeni,
je by ml obsahovat vechna pijmeni pouivana v esk iepublice (zdioj Mi-
nisteistvo vnitia R, http://www.mvcr.cz/soubor/2012-zctpr-zctpr-rijen-zip.aspx).
Celkem je to 1vI1e unikatnich jmen, pio ktei byla spoitan vsledek hashova-
ci funkce pio izn velikosti hashovaci tabulky (pouita funkce nemusi bt zcela
identicka s funkci pouivanou u objekt tidy Dictionaiy, ale je ji velmi blizka a
podobn efektivni). Pouit piogiam je uveden v piloze C.z na stian zsv.
Na ose je vynesena ielativni velikost hashovaci tabulky vzhledem k potu kli,
na ose je pimin iesp. maximalni poet slov, je hashovaci funkce mapuje
na stejn kli. Snadno lze zjistit, e i v pipad tabulky o velikosti
1
1
je maximal-
ni poet koliznich etzc ielativn mal (piblin 1), piem pimi je jet
meni (cca 1-). To je blizk optimalnimu pomiu (pimin 1 kolizni etzce) a
zjiuje velmi iychl vyhledavani (je nutno piohledat jen adov jednotky dvojic
kli a hodnot nikoliv statisice). U menich iozmi hashovacich tabulek poet
kolizi iychle (exponencialn) naista. U vtich naopak klesa ji mnohem miinji
a u velikosti nad 1. je zlepeni jen neviazn (vimnte si tak, e i kdy je
pimin poet kolizi blizk jedn, me v konkitnim pipad i miin vyi).
Volba optimalni iovnovahy mezi iychlosti a pamovmi naioky je obtina a za-
visi na mnoha aspektech systmu (pedevim, ale nikoliv vhiadn na velikosti
opeiani pamti). Velkost hashovaci tabulky je pioto v jazyce C= volena automa-
:o
1
2
3
4
5
6
0 0.5 1 1.5 2
mean size of collision group
1/x
2
4
6
8
10
12
14
16
18
20
0 0.5 1 1.5 2
max size of collision group
Obiazek e.1. Velikost kolizni skupiny pio hashovaci funkci nad etzci
Slovnik :1
ticky a uivatel slovniku ji neme pimo ovlivnit (a dokonce ani zjistit).
Pio dokoneni popisu iepiesentace hashovaci tabulky zbva doplnit infoimaci
jak jsou konkitn iepiesentovany kolize (k nim jak ji vime nezbytn dochazi).
eeni je ielativn jednoduch, namisto pouhch hodnot jsou do hashovaci ta-
bulky ukladany seznamy dvojic kli-hodnota. Nenastava-li kolize, je seznam pio
pislun index ( vsledek hashovaci funkce) jednopivkov, obecn vak me
mit libovoln poet pivk.
Pi opeiaci vyhledavani musi bt lineain piohledavany dvojice v seznamu a
zkoumany jejich klie (zda se neiovnaji hledanmu). Pi pouiti dobi hashovaci
funkce jsou vak jednotliv seznamy velmi kiatk (jednotky pivk). Na stiuktuiu
hashovaci tabulky se mete podivat na obiazku e. (miin zjednodueno). Od-
povidajici slovnik by byl instanci tidy Dictionary<string,string> a mapuje jmna
postav nejmenovan knihy na jejich stal bydlit.
0
1
2
3
4
5
6
7
8
9
string:Frodo
string:Hobitn
string:Aragorn
string:Minas Tirith
string:Galadril
string:!"rin
string:#lrond
string:$o%lin%a
string:Thorin
string:&ol
string:Th'odn
string:#doras
string:()*n%
string:H+r%a
string:Ar,n
string:$o%lin%a
h-.Thorin./ 0 1
Obiazek e.. Hashovaci tabulka
Poznmka:
Z dvod uiychleni opeiace vyjimani dvojic ze slovniku je pouit
tzv. spojov seznam. Piazdn poloky slovniku mohou bt piiozen
iepiesentovany hodnotou null. Navic nemusi bt pedem znama ve-
likost jednotlivch dilich seznam (spojov seznam me ist bez
nutnosti vynucenho kopiiovani pi naplnni sv pedem uien ka-
pacity).
::
lmplementaci hashovaci tabulky se navic komplikuje pedem nezna-
mm potem uloench pai kli-hodnota. l kdy lze pedpoklada-
nou velikost zadat ji v konstiuktoiu (stejn jako je tomu v pipa-
d seznam). Tato velikost vak nemusi bt dodiena. Zmna potu
uloench pivk vak viazn ovlivuje efektivitu hashovaci tabul-
ky. Pi postupnm zvyovani potu dvojic se vyhledavani zpomalu-
je, naopak pi jejich odebiiani zaujima hashovaci tabulka zbyten
mnoho mista. Z tohoto dvodu se musi obas tzv. pehashovat, tj. vy-
tvoit novou (povtinou vti) hashovaci tabulku a do ni nov uloit
vechny pvodni dvojice. Pi pehashovani se mni hashovaci funkce
tj. mni se i umistni jednotlivch pai v hashovaci tabulce (existuji
vjimky, ale ty nejsou v piaxi pili ast). Opeiace pehashovani je
pomala () a pioto je jeji planovani dosti sostikovan a je pln v
kompetenci inteini implementace (neme bt adnm zpsobem i-
zeno z vaeho piogiamu). V kadm pipad, si vak zapamatujte, e
i v pipad slovniku ma opeiace pidavani ( metoda Add), asovou
sloitost (1) jen tehdy, pokud zpimiujeme jednotliv asy pistu-
pu tj. konstantni sloitost je amoitizovana.
7. Souborov orientovan vstup a
vstup
l kdy v souasnosti existuje nespoetn mnostvi piogiam a aplikaci, maji tm
vechny jednu spolenou vlastnost musi podpoiovat pistup k exteinim loi-
tim dat (exteinim vzhledem k adiesovm piostoiu obsahujicim objekty).
V souasnosti lze exteini loit z hlediska piogiamovho pistupu iozdlit do
dvou zakladnich skupin
zaizeni s bytov oiientovanm pistupem (zakladni a univeizalni typ lo-
it)
ielani databaze (se zaznamov oiientovanm pistupem)
Relanimi databazemi se nebudeme dale zabvat, piotoe pistup k databazi vy-
aduje bu znalost dotazovaciho jazyka (SQL nebo LlNQ) iesp. vyuiti ielativn
komplikovanch model.
Bytov oiientovana zaizeni lze dale iozdlit na dv podskupiny
lokln soubory umouji teni a bn i zapis, piodleva pi pistupu je v a-
du maximaln milisekund (tj. hluboko pod iozliovaci schopnosti lidi). Data jsou
identikovana jmny bnmi v lokalnim opeianim systmu.
vzdlen soubory dostupn pes internetov protokoly umouji povtinou
pouze teni, piodleva me bt i v adu sekund. Data jsou identikovana pomoci
URL.
Rozdleni je dano mechanismempistupu, nikoliv (topogiackou) vzdalenosti. Pi
pouiti siov oiientovanch opeianich souboiovch systm (jako je NlS nebo
CllS) jsou i vzdalena data dostupna jako lokalni souboiy (mohou vak mit deli
piodlevy pi teni a zapisu). Naopak pomoci URL lze pistupovat i k lokalnim
souboim.
Pio pistup k bytov oiientovanm loitim lze bez ohledu na jejich chaiaktei
vyuit mechanismus tzv. datov proud (angl. stieam). Datov pioudy se obje-
zII
:
vily ji v jazyce Ca jako zakladni abstiakce jsou podpoiovany vtinou modeinich
opeianich systm. Modeini objektov systmy vak poskytuji i dali vistvy abs-
tiakce. Bohuel tak neini jednotn a jednotliv implementace se mnohdy viazn
lii (tj. nejedna se jen o iozdilnou teiminologii).
Podpoia pistup k bytov oiientovanmzaizenimve standaidni knihovn .NlT
je ielativn komplexni, je vak dobe naviena a podpoiuje i syntaktick zkiatky
pio nejastji pouivan manipulace (nap. nateni obsahu textovho souboiu lze
piovst pomoci dvou stiunch adk kodu).
Tidy objekt zajiujicich pistup k bytov oiientovanm loitim jsou souste-
dny ve jmennm piostoiu System.IO (zkiatka za Input/Output), nktei speciali-
zovan tidy se vak nachazeji i v jinch jmennch piostoiech. Vstupn-vstupni
tidy lze iozdlit do ti vistev
nzkorovov proudy pistupuji k pioudm poskytovanm opeianim sys-
tmem (jsou to pedevim souboiy a siov sockety)
filtran proudy modikuji pioud byt ziskan z jinho pioudu nebo do jinho
pioudu smiovan
zapisovatel a teni objekty, ktei pekladaji jednoduch objekty, jako jsou
etzce a iseln typy, do posloupnosti byt (zapisovatel) nebo je naopak
z posloupnosti byt vytvaeji (tenai). Zapisovatel pak tuto posloupnost
byt zapisuji do pioudu (a jejim piostednictvim na loit). tenai nao-
pak svoji vstupni posloupnost byt z datovch pioud ziskavaji.
Nad tmito zakladnimi vistvami existuji i dali vistvy poskytujici pistup ke kom-
plexnji stiuktuiovanm exteinim datm jako jsou XML souboiy nebo izn au-
diovizualni foimaty. Jinou nadstavbou jsou tzv. serializace tj. schopnost ukladat
do pioudu cel sloen objekty.
Nahled zakladni stiuktuiy l/O tid na platfoim .NlT poskytuje obiazek .1 na
nasledujici stian. Znazoinn je samozejm jen vbi tid, jsou vak uvedeny
vechny tidy popsan nie v tto kapitole.
Ve spodni asti obiazku jsou znazoinny nejbnji bytov oiientovana vstupni
zaizeni. Ta jsou vytvoena na iovni OS a poskytujici pistup k bytov oiientova-
nmdatovmloitim. Vimnte si, e loitmme bt i pole byt v opeiani
pamti, tj. jako souboi lze uivat i jednoduchou kolekci (hodi se to vak jen zidka).
Popime si napiklad teni textu ze zaifiovanho inteinetovho pioudu. Pio tento
el musi vzajemn spolupiacovat ti objekty objekt tidy NetworkStream, zaji-
ujici teni z TCP pioudovho socketu (ten poskytuje data poslana jinm pioce-
Souboiov oiientovan vstup a vstup :
FileStream
NetworkStream
MemoryStream
ZipStream
CryptoStream
BinaryWriter
TextWriter
soubor
TextReader
socket
pole
byt
filtry !iltro"ac# proudy$
byto"% oriento"an&
proudy
byto"% oriento"an&
zapisovae/tee
elem' ob(ekt
byto"% oriento"an#
BinaryReader
Obiazek .1. Stiuktuia l/O tid
sem pes siov spojeni), objekt tidy CryptoStream modikujici pioud bytovch
dat (pomoci kiyptogiack tiansfoimace, zde je to deifiovani) a na nejvyi iov-
ni objekt tidy TextWriter, jen tiansfoimuje (dekoduje) znaky z bytov posloup-
nosti. Pokud je objekt tenae poadan o peteni pivniho znaku, poada nejdive
bezpiostedn podizen pioud o dodani daliho bytu z loit. Timto pioudem
je kiyptogiack pioud, ktei data deifiuje pomoci blokov ifiy. Aby mohl pio-
vst deifiovani poada o blok dat pioud nejnii iovn (blok ma velikost jed-
notek byt). Timto pioudem je objekt tidy NetworkStream. Tento pioud pete
poadovan poet byt ze socketu. Pi tom me i chvili ekat, nebo data mu-
si bt nejdive do socketu zapsana diuhm komunikanim paitneiem (napiklad
WWW seiveiem) a musi bt penesena poitaovou siti.
Obdien blok je viacen kiyptogiackmu pioudu, ktei jej deifiuje. Pot viati
pivni byte z deifiovanho bloku instanci tidy TextReader. Ta se jej pokusi intie-
pietovat jako znak. Vyuiva k tomu tzv. znakov kodovani. lmplicitn se vyuiva
kodovani UTl-s. Toto kodovani iepiesentuje znaky pomoci jednoho a ty byt.
Pokud je pijat znak celmkodemznaku (tj. jeho nejvyi byte je c) je ve hotovo,
a objekt tenae viaci znak v inteini 1e-bitov iepiesentaci. V opanm pipad
:e
vak musi podizen pioud poadat o dali byte. Kiyptogiack pioud ma na-
tsti k dispozici dali byty z posledn deifiovanho bloku a tak me dali byte
viatit bez inteiakci s podizenm pioudem (objektem tidy NetworkStream). Po-
kud tena potebuje dali byty ve se jet (maximaln dvakiat opakuje). Pokud
nestai deifiovan blok me dojit i dalimu teni z fyzickho siovho spojeni
(piostednictvim nizkoiovovho pioudu NetworkStream).
Jak lze vidt z pikladu, me bt inteiakce objekt a bytov oiientovanch vstup-
n-vstupnich zaizeni ielativn sloita. Natsti si s tim bni piogiamatoi ne-
musi lamat hlavu. Stai jim vytvoit pislun objekty a zetzit je do jaksi v-
iobni linky od nizkoiovovho pioudu pes ltiovaci pioudy po cilov reader
nebo writer.
Vimnte si jist asymetiie v implementace vstupn vstupnich tid. Zatimco ob-
jekty pioudovch tid poskytuji zaiove metody pio teni i zapis, jsou tidy te-
na ( vstup) a zapisovatel oddlen (tj. metody tena poskytuji jen metody
pio teni a zapisovatel jen pio zapis). Toto odlieni je typick pio .NlT knihovnu
(napiklad standaidni knihovna jazyka Java oddluje vstupni a vstupni tidy na
vech iovnich). V piaxi se vak soubna monost teni i zapisu v iamci jedi-
n instance pioudu pouiva zidka. Vtina pioud podpoiuje pouze teni nebo
pouze jen zapis. Pokud pouijeme metodu pio opan smi, je vyvolana vjimka
(neplatna opeiace). To sice kontiolu pesouva a do faze bhu (piogiamse spiavn
peloi, ale zhavaiuje pi bhu), viazn to vak zjednoduuje model tid.
Pio zaatek se vak zamime jen na nejjednodui a nejastji pouivan kom-
binace teni a zapis do binainiho souboiu (postauje jen jeden objekt pioud),
zapis do textovho souboiu (se dvma objekty) a teni textovho souboiu (opt
dva objekty).
7.1. Bytov orientovan vstup a vstup (binrn
soubory)
7.1.1. Bytov orientovan vstup
Pi pouivani pioud (a do znan miiy i tena a zapisovatel textu) lze iozliit
ti zakladni faze
1) oteven proudu pi pouivani souboiovho pioudu se oteve pislun sou-
boi a stava se souasti kontextu piocesu (tj. stav souboiu se stava souasti stavu
Souboiov oiientovan vstup a vstup :,
piocesu). Pi oteviiani se ovuji i pistupova piava k souboiu (iesp. obecn k lo-
iti). Podai-li se souboi otevit, pak ji nehiozi pili velk nebezpei, e se data
nepodai zapsat nebo peist (jedinm nebezpeim je vyeipani kapacity svazku
nebi limit velikosti). U jinch pioud (nap. siovch) vak spn oteveni neza-
jiuje spn piovedeni opeiaci. Pi oteviiani se asto specikuje, zda je pioud
oteven pouze pio teni i pouze pio zapis (vjimen jak pio teni tak zapis).
2) pstup k otevenmu proudu teni i zapis dat
3) uzaven proudu kad pioud by ml bt po pouiti nepiodlen uzaven.
Pio to existuje hned nkolik dvod
1. pedevim v pipad zapisu me bt ukoneni penosu provedeno a po
uzaven proudu. Bohuel ani spn uzaveni vak bohuel nezajiuje
spn uloeni vech dat. Data mohou zstat ve vyiovnavacich pamtech
zpiavovanch OS.
z. oteven souboiy a komunikani kanaly jsou ielativn vzacnm piosted-
kem. Kad pioces jich me pouivat jen omezen poet, nebo jejich udi-
ovani vyaduje pam jadia.
I. stav zaizeni, je zajiuje oteven pioud, je souasti kontextu piocesu. Ne-
me tak bt vyuit jinm piocesem bez toho, e by bylo nutno eit syn-
chionizaci mezi piocesy. Synchionizace vyaduje dodaten piostedky a
je nachylna k chybam.
Pravidlo 26: Veker proudy je nutno bezprostedn po ukonen jeji vyuvn
explicitn zavt.
Tento zakladni model si ukaeme na jednoduchm piogiamu, ktei vytvoi sou-
boi tvoen 1cz1 nulovmi byty.
using System; / / writebytes.cs
using System.IO;
class MainClass {
public static void Main() {
/ / oteveni souboiu
FileStream fs =
new FileStream( "testFile", FileMode.CreateNew, FileAccess.Write);
/ / zapis byt
for (int i=0; i<1024; i++) {
fs.WriteByte((byte)0);
}
:8
/ / uzaveni souboiu
fs.Close();
}
}
Zakladnim piostedkem oteveni souboiovho je volani konstiuktoiu tidy Fi-
leStream. lxistuje nemn ne tinact iznch petiench veizi tohoto konstiuk-
toiu. Zde pouivame veizi, kteia kiom jmna souboru (pivni paiameti), umo-
uje specikovat tzv. reim oteven (tj. chovani aplikace v zavislosti na existenci
pislunho souboiu v okamiku jeho oteveni) a typ pstupu (jen teni/jen zapis).
loimat jmna souboiu zavisi pln na opeianim v systmu, v nm bude piogiam
piovozovan. Mete pouit jak ielativni jmno bez cesty (souboi bude vztaen k
tzv. aktualnimu adiesai), tak absolutni jmno s plnou cestou. Pi pouiti abso-
lutniho jmna mate vti volnost, piogiam se vak stava mn penositeln.
V unixovch (posixovch) systmech jsou jako oddlovae adiesa v cest vyu-
ivana klasicka lomitka a cesta neobsahuje identikatoi svazku (unixov systmy
vytvaeji jednotn viitualni stiom)
"/home/fiser/output"
Ve svt MS Windows se pouivaji lomitka obiacena a oznaeni svazku
"c:\\temp\\output"
Lomitka musi bt zdvojena, nebo jednoduch lomitko uvozuje nikov sekvence
(tj. nap. \t je znak tabulatoiu), Zdvojovani vak znepehleduje zapis a pio-
to je mono vyuit tzv. syrov (angl. raw) etzcov literly. V tchto liteialech
uvozench znakem zavinae nelze vyuivat nikov sekvence, a tudi neni nutn
zdvojovat zptna lomitka.
@"c:\temp\output"
Knihovna nabizi i monost vytvaeni penositelnch jmen, je to vak o nco na-
ionji. Pokud Vas tato pioblematika zajima, podivejte se na tidu System.IO.Path
a jeji metodu Combine.
Knihovna .NlT nabizi ielativn velk mnostvi ieim pi oteveni souboi, co
me bt pio zaatenika miin matouci. Natsti jsou tyto ieimy popsany po-
moci kombinaci malho potu iznch ieakci na existenci i neexistenci souboiu.
Navic jsou zce piovazany s ieimem pistup k otevenmu souboiu, tj.nktei
ieimy jsou mon a uiten jen u vstupnich pioudm jin naopak jen u pioud
vstupnich.
Souboiov oiientovan vstup a vstup :,
reim Create CreateNew Open
souboi existuje zkiaceni vjimka lP na zaatku
souboi neexistuje vytvoeni vytvoeni vjimka
typ. pistup W W R (RW)
reim OpenOrCreate Truncate Append
souboi existuje lP na zaatku zkiaceni lP na konci
souboi neexistuje vytvoeni vjimka vytvoeni
typ. pistup RW (R) W W
lP (FilePointer) aktualni pozice v souboiu, Od tto pozice je pioud ten iesp. od
tto pozice piobiha zapis.
Nejastji pouivanm ieimem oteveni je FileMode.Create pi zapisu (s pepsa-
nim pvodniho obsahu) a FileMode.Open pi teni. Reim FileMode.Append je po-
uivan pi pidavani dat na konec souboiu (nap. u logovacich souboi) a ma
specialni chovani.
Poslednim paiametiem konstiuktoiu pioudu je typ (ieim) pistupu. Nejastji
se pouivaji ieimy FileAcces.Read (jen teni) a FileAcess.Write (jen zapis). Pioudy
umoujici teni i zapis (FileAcess.ReadWrite) se pouivaji spie vjimen. Navic
je lze pouit jen u nkteich pioud. Podkladov zaizeni musi mimo jin podpo-
iovat nahodn posun aktualni pozice v souboiu.
Po spnm ukoneni volani konstiuktoiu ziskame nejen nov objekt v pamti,
ale vznikne i nov piostedek v iamci opeianiho systmu tzv. oteven soubor.
Oteven souboi umouje postupn teni byt z fyzickho souboiu (tj. poskytuje
vstupni pioud) iesp. zapis byt do souboiu (vstupni pioud). Pokud se pidleni
piostedku nepovede, je vyvolana vjimka.
Poznmka:
V iamci cel tto kapitoly pedpokladame, e v bhem cel doby exis-
tence otevenho pioudu, existuje piav jeden oteven souboi nad
fyzickm souboiem, tj. pistup k souboiu neni sdilen. To je ve vtin
pipad splnno, nebo fyzick souboiy jsou jen vjimen sdileny. V
opanm pipad bychom museli eit synchionizaci pistupu, co je
jednak pomin sloit, jednak zde existuje silna zavislost na opeia-
nim systmu, kteiou .NlT knihovna neme zcela odstinit. Neni pe-
kvapenim, e mechanismy podpoiovan touto knihovnou jsou blii
MS Windows ne nap. Linuxu.
:o
Po vytvoeni a oteveni pioudu lze do nj zapisovat pomoci metody FileStre-
am.WriteByte. Tato metoda oekava jedin paiameti, jim je hodnota zapisova-
nho bytu. Tato hodnota musi bt instanci tidy byte (pln jmno tidy je Sys-
tem.Byte).
tda byte
Tato tida se podoba tid int (tj. tak iepiesentuje cela isla), jeji instance vak
iepiesentuji pouze hodnoty od nuly do z (vetn). Maji tak jinou pamovou
iepiesentaci zaujimaji pouze jeden byte ( oktet osm bit) pamti.
Stejn jako ostatnich iselnch tid je nutno odliovat objekt tidy byte iepiesen-
tujici uiit islo od objektu tidy int iepiesentujici tot islo. Tj. nap. byte:0 se
lii od int:0.
Tato zakladni odlinost je v mnoha pipadech setena automatickou konveizi (im-
plicitnim petypovanim) isla tidy byte na islo tidy int.
int i = 5;
byte b = (byte)5; / / zde je nutn explicitn petypovat viz nie
Console.WriteLine ( i == b ); / / vypie true, byte se pevede na int
Console.WriteLine ( i - b );
/ / vypie c (tidy int, nebo byte se ped sitanim konveituje na int)
lmplicitni konveize je mona, nebo jakakoliv bytova hodnota je jednoznan ie-
piesentovatelna objektem tidy int. Pi konveizi tedy nedochazi k adn ztiat
infoimace.
Opana konveize (objektu tidy int na byte) neme bt automaticka, nebo ke
ztiat infoimaci me snadno dojit. Napiklad nelze bezeztiatov konveitovat is-
lo ze nebo 1. Pokud si konveizi vynutime opeiatoiem petypovani, je vsled-
kem u tchto (a dalich vice ne 1 miliaid isel) nedenovana hodnota (alespo de
iure). De facto ji dobi piogiamatoi dokae piedikovat, ale vsledek me zaviset
na konkitnim piocesoiu (typicky je to nejnii byte ze tybytov iepiesentace
isla int tj. nap. (byte)256 c a (byte)-1 z).
Zcela bezpena je tak konveize jen u isel, u nich mame jistotu, e lei v bezpe-
nminteivalu [c,z]. Neni pioto pekvapenim, e si peklada vynucuje explicitni
petypovani nap. u piomnnch i sloitjich viaz. Neme si bt jist, zda je
petypovani bezpen a nechava odpovdnost na uivateli (pouil jsi explicitni
petypovani, take vi co ini a bude za to po zasluze potiestan).
Souboiov oiientovan vstup a vstup :1
Tiochu pekvapiva je nutnost explicitniho petypovani u liteial, u nich by si
ml bt peklada jist, e petypovani je zcela bezpen. Pio je vbec nutn psat
napiklad
fs.WriteByte((byte)0)
i kdy je zejm, e nulu lze bezpen iepiesentovat i v jedinmbytu` Dvodemje
skutenost, e peklada nezohleduje jednotliv objekty, ale jen tidy. Je to toti
jedin pistup, ktei je zcela univeizalni a obecn aplikovateln. Peklada jej toti
podpoiuje i u sloitjich objekt, kde iozhodnuti podle konkitnich objekt neni
mon. Jazyk C= pouiva vechna piavidla dsledn a nikdy neini magicka (tj.
obecn nepiedikovatelna) iozhodnuti (nktei jazyky nejsou v tomto smiu zcela
iigidni, nap. Peil je asto magick).
Poznmka:
Jazyk C= nepodpoiuje pim liteialy tidy byte a obecn adn iseln
tidy, je je vlastni podmnoinou tidy int. Tato vlastnost je typicka
pio vechny (staticky typovan) jazyky odvozen od jazyka C (vet-
n samotnho jazyka C). To si u jazyk se stiiktni (silnou) typovou
kontiolou vynucuje explicitni petypovani iselnch liteial. Kiom
C= se to tka napiklad i Javy.
Objekty tidy byte se nejastji pouivaji v situacich, kdy jsou vy-
nuceny smantikou (nap. u bytov oiientovanch pioud) a u ko-
lekci (poli, seznam), kde mohou viazn sniit pamov naioky. V
ostatnich pipadech (bna iselna skalaini aiitmetika, itae, apod.)
je vhodnji pouivat tidu int. Nedochazi toti ani k spoe pamti
(z dvod optimalizace pistupu jsou i bytov objekty zaiovnavany
na hianici ty i osmi byt) ani ke ziychleni vpot (aiitmetick
opeiace se intein piovadji v cel ice iegisti tj. v iozsahu ty
nebo dokonce osmi byt)
=
Po zapsani hodnot do pioudu je nutn pioud uzavit. To se dje metodou FileStre-
am.Close. Metoda nema adn paiametiy a vdy koni spchem (lze dokonce
zavit ji uzaven pioud, v tomto pipad metoda nic nepiovadi).
Pi uzaveni dochazi k uvolnni pidlenho piostedku na iovni opeianiho
systmu (u souboiovho pioudu je to tedy oteven souboi). Vlastni objekt vak
zstava a pokud existuje i piomnna, kteia na nj odkazuje (pioudy jsou vdy
::
iefeienni objekty) me bt omylem pouit. Pokud se pokusime do uzavenho
pioudu znovu napsat je vyvolana vjimka. Stejn tak je vjimka vyvolana pi
pokusu o znovuoteveni.
l kdy pioud explicitn neuzaveme, bude pidlen piostedek nakonec uvolnn.
Dje se tak pi uvolnni objektu pioudu z pamti pi jejim klidu sbiaem smeti
(garbage collector). Bohuel vak nelze pedem piedikovat, kdy se ta stane. V nej-
lepim (ale nepiavdpodobnm) pipad u v okamiku, kdy zanikne posledni od-
kaz na objekt pioudu (tj. nap. zanikne lokalni piomnna, kteia jej inicializovala).
V nejhoiim (a mnohem piavdpodobnjim) pipad a pi ukoneni piogiamu,
Do t doby je piostedek zbyten alokovan.
Uzaveni souboiu explicitnim volanim metody Close ihned po piovedeni zapisu
i teni, pioblm s uvolnnim zdanliv dokonale ei. Bohuel to neni tak pln
piavda, nebo i kdy na uzaveni nezapomeneme, me dojit k situaci kdy neni
volani metody Close vbec piovedeno. Dvody jsou v zasad dva
1. uzaveni pioudu je obejito pikazemskoku. Nejedna se zde o nechvaln zna-
m pikaz goto (ten v jazyce C= existuje, ale neml by se nikdy pouivat),
ale pedevim o pikaz return. Pokud pedasn ukonujeme metodu pika-
zem return, musime zajistit e i v tomto pipad je pioud bezpen uzaven,
Nestai tedy jedin uzaveni na konci tla metody.
z. bhem zapisu a teni vznikne vjimka. Vjimka nemusi bt nutn zpsobe-
na zapisem(stai jen, e vznikne v libovolnmokamiku od oteveni po uza-
veni pioudu). Tato vjimka nemusi nutn vst k bezpiostednimu ukoneni
piogiamu (a tedy i nucenmu uzaveni). Vjimky lze zachycovat a po za-
chyceni me piogiamdale pokiaovat. Bohuel v tomto pipad pokiauje
s neuzavenm pioudem (po vyvolani vjimky se zbytek kodu metody ji
nikdy nepiovede).
konstrukce using
Natsti jazyk C= poskytuje konstiukci, kteia spiavn uvolovani piostedk v-
iazn usnaduje a zpehleduje konstiukci (pikaz) using.
Upozornn: Tato konstiukce nema nic spolenho s deklaiaci using uivanou pio
impoitovani jmennch piostoi. Autoi jazyka zde jen pouili stejn kliov slovo
pio dv zcela odlin konstiukce (pi navihu jazyka je vhodnji omezit poet
kliovch slov na minimum).
Souboiov oiientovan vstup a vstup :
Pi pouiti konstiukce using je existence exteinich piostedk vazana na piogia-
mov blok (ast piogiamu uzavena ve sloench zavoikach) stejn jako existence
piomnnch. Po oputni bloku (vetn vskoku i vjimky) je objekt automa-
ticky uvolnn.. Syntaxe je jednoducha v hlavice konstiukce using vytvoime
objekt s exteinim piostedkem (zde je to objekt souboiovho pioudu spojen s
otevenm souboiem) a odkaz na nj uloime do piomnn.
using (FileStream fs =
new FileStream( "testFile", FileMode.CreateNew, FileAccess.Write)) {
/ / zde meme objekt pioudu i otevenm souboiem pouivat
for (int i=0; i<1024; i++)
fs.WriteByte((byte)0);
} / / zde je oteven souboi uvolnn
Po hlavice nasleduje blok uzaven do sloench zavoiek. Uvnit tohoto bloku
meme objekt odkazovan piomnnou bez pioblm vyuivat. Po oputni blo-
ku (dosaenim konce, vskokem, vyhozenim vjimky) je pioud uzaven. Stejn
tak zanika i piomnna (nememe tedy objekt omylem vyuivat i pio uzaveni).
Jedin kdo oputni bloku peije je samotn objekt, ten je vak ji nedostupn a
pi nedostatku pamti bude uvolnn sbiaem smeti.
Konstiukci using tak lze inteipietovat tak takto objekt je pipiaven k pouit, ale
jen v iamci nasledujiciho bloku (pak u nebude poteba).
Poznmka:
Pi pouiti konstiukce using neni volana pimo metoda Close, ale
obecnji metoda Dispose ( uvolni [piostedek]). Tuto metodu lze
nalzt i dalich tid, jejich instance spiavuji exteini piostedek jako
je napiklad inteinetov socket, kiyptogiack modul nebo bitma-
pa uivana v GUl. lxistence metody Dispose v iozhiani objektu vak
jet nezaiuuje jeho pouitelnost v konstiukci using, nebo stejn
jmno me mit i jina nesouvisejici metoda. Postaujici podminkou
je implementace iozhiani System.IDisposable, Tim, nejen e vynutime
implementaci metody Dispose, ale foimaln stvidime, e metoda bude
mit poadovanou smantiku (peklada to neme sam zkontiolovat)
Konstiukce using je uitena, avak ne vdy pouitelna. Pokud je k pioudu pistu-
povano deli as a z mnoha navzajem nesouvisejicich mist kodu, je nutno vyuit
klasick eeni tj. explicitni volani metody Close. K tto situaci by vak nemlo
dochazet pili asto.
=
:
Pokud nemate specialni poadavky na ieim oteveni, lze objekt (otevenho)
pioudu ziskat i pomoci statick metody tidy File se jmnem Create, jen otviia
souboi v ieimu vhodnm pio zapis (souboi je oteven v ieimu Filemode.Create).
l v tomto pipad je vak nutno zajistit bezpen uzaveni souboiu.
using(FileStream fs = File.Create(path)) {
/ / zapis do pioudu
}
7.1.2. Bytov orientovan vstup
teni bytov oiientovanho souboiovho pioudu se pili nelii od zapisu. Opt
je nutno pioud otevit (tentokiat s uvedenim pislunho typu pistupu FileAc-
cess.Read a vhodnho ieimu oteveni) a po skoneni uzavit (optimaln pomoci
konstiukce using).
Pio vlastni teni je nejjednodui pouit metodu int ReadByte(). Tato metoda
kupodivu neviaci objekt tidy byte ale int. Dvodem je signalizace dosaeni konce
souboiu. Pokud je tato metoda pouita na konci souboiu (lepointer ukazuje za
posledni byte), neme metoda viatit bnou bytovou hodnotu, nebo v souboiu
mohou bt byty libovolnch hodnot (adn neni pedem vylouiteln). Mohla
by sice vyhodit vjimku, ale to neni zcela koei, nebo dosaeni konce souboiu
neni vjimena situace (kad souboi nakonec skoni). Pioto viati hodnotu -1,
kteia signalizuje dosaeni konce a je odlina od libovoln bytov hodnoty c a
z (nevejde se vak do bytu a musi bt tudi viacena jako instance tidy int).
Hodnota -1 se v tomto kontextu oznauje jako lOl (end of le)
Poznmka:
Viaceni hodnoty -1 pi dosaeni konce souboiu je u nkolik desetile-
ti zavedenm idiomem. Objevuje se v jazyku C a odvozench (vetn
Peilu a PHP) a nejen tam(pouiva se nap. i v Pythonu). Nktei jazy-
ky vak davaji pednost vyvolani vjimky, co si vynucuje pedbn
testovani pioudu ped teni (metoda se smantikou u jsem na kon-
ci souboiu`). To vak komplikuje zapis a neni to zcela bezpen. U
souboiu se sdilenim pistupu, me nastat situace, e test signalizu-
je, e konce nebylo dosaeno, ale nasledn pistup skoni s chybou,
nebo posledni byte mezitim nkdo odstianil zkiacenim souboiu.
Souboiov oiientovan vstup a vstup :
Pio ilustiaci zapisu si meme zvolit tiochu iozsahleji (a mnohem piaktitji)
piklad, odhalovn typu souboru podle prvn nkolika (v naem pipad ty)
byt. Mnoh typy souboiu toti maji na svm zaatku typick bytov vzoi, jen
je oznaovan jako magi slo (me bt toti inteipietovan jako islo s vice-
bytovou iepiesentaci). U nkteich souboiovch foimat vzniklo magick islo
nahodou u jinch bylo zavedeno zamin.
Detailnji infoimaci i s ukazkami nejznamjich magickch isel najdete v lanku
Wikipedie http://en.wikipedia.org/wiki/Magic_number_%28programming%29. Z tohoto
lanku jsou pevzata i ukazkova magicka isla uvedena v naem piogiamu (sku-
tena aplikace tohoto diuhu by mla obsahovat vti databazi).
using System; / / magicnumber.cs
using System.Collections.Generic;
using System.IO;
/ / / summaiy~
/ / / Simple detectoi of le types based in magic numbeis
/ / / /summaiy~
class MagicNumberTester {
/ / zakladni datova stiuktuia slovnik mapujici tveici byt na popis (tezec)
Dictionary< Tuple<byte,byte,byte,byte>, string > magn
= new Dictionary<Tuple<byte, byte, byte, byte>, string>();
/ / zbyten piazdn konstiuktoi
public MagicNumberTester () {
/ / empty constiuctoi
}
/ / / summaiy~
/ / / Method adds 1-byte magic numbei to inteinal database
/ / / /summaiy~
public void AddMagicNumber(string typeName, int b1, int b2, int b3, int b4) {
magn.Add(new Tuple<byte,byte,byte,byte>(
(byte)b1, (byte)b2, (byte)b3, (byte)b4), typeName);
}
/ / / summaiy~
/ / / Method guesses the type of the le (by using of database of magic numbeis)
/ / / /summaiy~
/ / / ietuins~Te desciiption of (guessed) foimat/ietuins~
:e
/ / / paiam namepath~path to le (including lename)/paiam~
public string GuessFileType(string path) {
using (FileStream fs = new FileStream(path, FileMode.Open,
FileAccess.Read)) {
List<byte> header = new List<byte>(4);
/ / iead
for (int i=0; i<4; i++) {
int b = fs.ReadByte();
if (b == -1)
return "unknownfiletype"; / / too shoit le
else
header.Add((byte)b);
}
Tuple<byte, byte, byte, byte> theader = / / list -~ tuple conveision
new Tuple<byte, byte, byte, byte>(header[0], header[1],
header[2], header[3]);
return this.magn.ContainsKey(theader) ? this.magn[theader]
: "unknownfiletype";
}
}
}
class MainClass {
public static void Main(string[] args) {
MagicNumberTester tester = new MagicNumberTester();
/ / vytvoeni minidatabaze
tester.AddMagicNumber("PNGimage", 0x89, 0x50, 0x4E, 0x47);
tester.AddMagicNumber("PDFdocument", 0x25, 0x50, 0x44, 0x46);
/ / test souboiu v piacovnim adiesai
Console.WriteLine(tester.GuessFileType("test.pdf"));
}
}
Objekty tidy MagicNumberTester adaptuji pio svj el slovnik mapujici n-tice
(tuple) ty byt na etzec. Pio pidani novho mapovani (zobiazeni) do slovniku
sloui metoda AddMagicNumber, jeji kod je tiivialni. Kad ze tveice byt je
do metody pedan jako zvlatni paiameti typu int (namisto oekavanho typu
byte). Dvodem volby iiiho typu je zjednodueni volani metody s celoiselnmi
Souboiov oiientovan vstup a vstup :,
liteialy (nemusi se explicitn petypovavat liteialy). Petypovani je piovedeno a
uvnit metody, kde se vytvai n-tice pouita na mist klie. Pio pidani novho
klie s hodnotou se pouiva metoda Add, nebo se nepedpoklada vicenasobn
pidani tho klie (zjednodueno obecn me mit vice typ souboi stejn tyi
byty magickho isla, pokud to nastava musi to bt zohlednno v etzci popisu).
Metoda testujici typ souboiu (GuessFileType) je o nco komplexnji. Nejdive je
v iamci hlaviky konstiukce using vytvoen nov objekt souboiovho pioudu.
Cesta k souboiu je pevzata z paiametiu metody, mod oteveni je FileMode.Open
(oteveni existujiciho souboiu s ukazatelem na poateni byte, vjimena situace
pokud souboi neexistuje) a typ pistupu je samozejm FileAccess.Read.
Vekeia dali manipulace se dje v tle konstiukce using. Algoiitmus je miin
zkomplikovan existenci souboi, jejich dlka je meni ne tyi byty (nejpiavd-
podobnji je existence piazdnch souboi). Tyto souboiy nelze podle magickch
isel iozeznat, ale nemly by vst k pedasnmu ukoneni piogiamu vjimkou. Z
tohoto dvodu jsou byty teny jeden po diuhm a vkladany doasn do seznamu.
Jestlie je bhem teni tchto ty byt dosaen konec konec souboiu, je testovani
ukoneno a je viacen etzec unknown le type.
Nejzajimavji asti metody je tiansfoimace tylennho seznamu byt na pi-
slunou n-tici. Piotoe n-tice me bt obecn heteiogenni ( s polokami iz-
nch typ) nelze ji inicializovat pomoci konstiuktoiu s inicializani kolekci (tato
kolekce by byla postupn piochazena a jednotliv pivky jeden po diuhm zko-
piiovany). Jedinm monm zpsobem inicializace je explicitni pedani jednotli-
vch pivk, tj. uvedeni konstiuktoiu se tymi paiametiy (z nich kad je ziskan
indexaci ze seznamu). Neni to pili stiun, ale bohuel nezbytn. Natsti se po-
uivaji jen n-tice malch iozmi.
Poznmka:
Nepijemn pevadni seznamu do n-tic by bylo mono eliminovat
vyuitim jednotn kolekce jak pio postupn naitani tak i na mist
klie v seznamu. Bohuel kolekce, kteia by byla pouitelna v obou
iolich, neme existovat. Postupn vkladani vyaduje podpoiu pi-
davani i alespo indexace (to neumouje n-tice a obecn adna ne-
mnna kolekce), pouiti na mist klie vyaduje naopak kolekci ne-
mnnou (co neni seznam a dokonce ani pole).
Po pevodu seznamu na n-tici je tato n-tice vyhledana ve slovniku. Pokud je dana
n-tice ve slovniku obsaena jako kli, je viacen odpovidajici popisn etzec (hod-
:8
nota pisluna klii). V opanm pipad je viacen etzec unknown le type.
Pio zestiunni je pouit podminkov opeiatoi.
Testovaci kod (v metod Main), pidava dv ukazkova magicka isla (vimnte si
pouiti liteial v estnactkov soustav pio jednotliv liteialy) a funkce je ovena
na testovacim souboiu (otestuje, zda je souboi skuten ve foimatu PDl).
Stejn jako v pipad zapisu i pi teni existuje alteinativni metoda pio vytvo-
eni a oteveni pioudu ve standaidnim ieimu FileMode.Open staticka metoda
File.OpenRead.
using(FileStream fs = File.OpenRead(path)) {
/ / teni z pioudu
}
Dokumentan poznmky
lmplementace piogiamu obsahuje kiom kodu i tzv. dokumentan poznmky. Ty-
to poznamky nejsou na iozdil do bnch poznamek uieny pio implementatoiy
tidy (tj. nejsou uieny piimain pio Vas a leny Vaeho tmu), ale pio uiva-
tele tidy (tj.piogiamatoiy, ktei vytvaeji instance tidy a aplikuji na n veejn
metody).
loimaln jsou dokumentani poznamky bnmi poznamkami tj. jsou zcela igno-
iovany pekladaem (z pohledu pekladae jsou jen specialnim pipadem mezeio-
vch znak). Jedinm syntaktickm iozdilem je pouiti daliho (tetiho) lomitka
na zaatku (adkov) poznamky.
Smantick iozdily jsou vak mnohem hlubi
dokumentani poznamky se umisuji jen na pesn denovana mista pio-
giamu. Piotoe dokumentuji veejn viditeln konstiukce jako jsou tidy a
veejn metody (vetn konstiuktoi a vlastnosti), musi bt uvedeny bez-
piostedn ped jejich hlavikami (tj. pimo ped denici metody nebo me-
tody/konstiuktoiu/vlastnosti).
uvnit dokumentanich poznamek je nutno vyuivat foimalizovanou stiuk-
tuiu vyuivajici znakovaci jazyk XML. Vechny infoimace musi bt expli-
citn oznaeny pomoci tzv. znaek (tag). l kdy existuje ielativn velk po-
et tchto znaek, je v piaxi vyuivano jen nkolik z nich. V naem pipad
Souboiov oiientovan vstup a vstup :,
jsou to znaky summary (stiun popis dan konstiukce), return (popis na-
viatov hodnoty u metod a vlastnosti) a params (popis funkce konkitniho
paiametiu, paiameti musi bt identikovan pomoci atiibutu name).
dokumentani poznamky nejsou uieny pio teni ve zdiojovmkodu, nebo
zdiojov kod tid nemusi bt pio jejich uivatele dokonce ani dostupn. Je
zpiacovavan exteinimi nastioji do podoby HTML dokumentace (nejpopu-
lainji je Sandcastle http://shfb.codeplex.com/, iesp. univeizalni geneiatoi
doxygen http://www.stack.nl/~dimitri/doxygen/). Navic je tato dokumentace
vyuivana i ve vvojovch piostedich pi zobiazovani iychl napovdy.
Dokumentani poznamky nejsou samozejm povinn, ale jsou neoceniteln v
pipad, e hodlate Vai tidu zveejovat i dlouhodob udiovat.
7.2. Textov orientovan vstup a vstup
Na svitu doby poita se textov oiientovan vstup neliil od vstupu bytov-
ho. Kad znak byl kodovan jednim bytem (viz napiklad kodovani ASCll, ktei je
dokonce jen sedmibitov) tj. zapis i teni znaku se iovnal zapisu i teni bytu. Ui-
it pioblmy byly pouze se znaky odadkovani (ty se v jednotlivch opeianich
systmech liily a dodnes se lii).
V souasnosti vak pevauje znakova sada Unicode, jeji iozsah (vice ne 11c ccc
znak) neumouje vzajemn jednoznan zobiazeni mezi byty a znaky. Pio-
to jsou v knihovn .NlT stiiktn oddleny tidy zajiujici bytov oiientovan
vstup/vstup od tid piacujicimi s textovm vstupem.
Textov oiientovan vstup a vstup navic umouje piacovat nejen s jednotliv-
mi znaky, ale i adky. adek je posloupnost znak zakonena i omezena speci-
alnimi symbolem (nebo symboly). Bohuel o tom jak symboly omezuji etzec
nepanuje shoda v Unixu se pouiva jedin znak (\n oznaovan jako new-line,
nebo line-feed), ve svt Windows pak dvojice \i a \n (carriage return, line fe-
ed). Pichod Unicodu pinesl i dali znaky oddlujici souboiy (ty se vak natsti
nepouivaji pili asto). adkov oiientovan vstup/vstup v .NlT tyto iozdily
ielativn spn skiva (tj. napiklad metoda TextReader.ReadLine pete adek
bez ohledu na oddlova).
:o
7.2.1. Textov orientovan vstup
Hlavni tidou zajiujici textov oiientovan vstup je TextWriter. Tato tida pe-
vadi znaky na byty, podle zvolen znakov sady a kodovani a tyto byty posila do
podizenho pioudu (tj. nepiovadi pimo vstup, ale vyuiva k tomu pioud).
Pokud chcete mit plnou kontiolu nad celm timto piocesem, musite celou opeiaci
zapisu iozdlit do pti fazi
1. oteveni pioudu (pio zapis s vhodnm ieimem oteveni)
z. oteveni objektu zapisovatele nad pioudem (s monosti volby kodovani)
I. vlastni zapis
1. uzaveni objektu zapisovatele
. uzaveni objektu podkladovho pioudu
Natsti lze tuto posloupnost opeiaci ve vtin pipad viazn ziedukovat.
Nejdive se vak podivejme na piklad s explicitnim vyjadenim vech kiok. V
piaxi se pili nepouiva, ale nejlpe ukazuje vechny dili faze piocesu zapisu
using System.Text;
using System.IO;
....
FileStream stream =
new FileStream("cp1250.txt", FileMode.Create, FileAccess.Write);
TextWriter writer =
new StreamWriter(stream, Encoding.GetEncoding(1250));
writer.WriteLine("luoukkplbelskdy");
writer.Close();
stream.Close();
Nejdive je vytvoen (a oteven) objekt pioudu. Kliovm pivkem je volba spiav-
nho typu pistupu (pioud musi podpoiovat zapis). To se piojevuje i v ieimu
oteveni (zde zvolen ieim FileMode.Create je jen jednou z monosti).
Po vytvoeni pioudu je vytvoen i objekt zapisovatele. Vimnte si nehody ti-
dy v denici piomnn wiitei. Piomnna ma typ TextWriter, avak po inicializaci
odkazuje na instanci tidy StreamWriter. To neni chyba. StreamWriter je speciali-
zovanou veizi tidy TextWriter uienou pio zapis do pioud a me bt pouit na
jejim mist (to zajiuje mechanismus tzv. ddinosti s nim se detailnji seznami-
me pozdji). Nazev tidy StreamWriter neni zcela vhodn, lepim pojmenovanim
by bylo StieamTextWiitei, nebo je to textov zapisovatel, zapisujici do pioudu.
Souboiov oiientovan vstup a vstup :1
Poznmka:
Kiom StreamWriteru existuji i jin specializovan tidy textovch
zapisovatel. V piaxi se vak astji setkate jen s tzv. StringWriterem,
ktei zapisuje do etzce. lunkce je podobna MemoryStreamu je vak
na vyi iovni abstiakce (do pamti nejsou vkladany byty, ale pimo
jednotliv znaky).
Zvolen konstiuktoi objektu zapisovatele ma dva paiametiy. Pivnimje podizen
pioud (pioto musel bt vytvoen jako pivni). Diuhm je objekt iepiesentujicim
znakovou sadu a jeji kodovani do byt. Tento objekt je ziskan volanim statick
metody GetEncoding tidy System.Text.Encoding. Tato metoda vyhleda kodova-
ni (a tudi znakovou sadu) podle iselnho identikatoiu. iseln identikatoiy
vech podpoiovanch znakovch sad lze zjistit nap. v dokumentaci tidy Sys-
tem.Text.Encoding (http://msdn.microsoft.com/en-us/library/system.text.encoding.
aspx)'. Kod 1zc ma znama s-bitova znakova sada windows-1zc pouivana pio
iepiesentaci eskch znak na platfoim Windows.
Pio zapis do zapisovae lze vyuit metod, ktei zname z iozhiani konzole tj, Write
a WriteLine. V tomto pipad to vak nejsou statick metody, ale instanni metody
konkitniho objektu zapisovatele.
Poznmka:
Metody Console.Write a Console.WriteLine jsou ve skutenosti jen al-
teinativnimi zapisy namisto volani pislunch metod nad objektem
tidy TextWriter zajiujicim pistup k pioudu standaidniho vstupu.
Tento objekt existuje v kadm konzolovm piogiamu a je dostup-
n pomoci statick vlastnosti Console.Out. Napiklad volani Conso-
le.WriteLine je identick s volanim Console.Out.WriteLine (volani me-
tody explicitn nad zapisovatelem).
Uzaveni zapisovatele pomoci metody Close je zce piopojeno s uzavenim pod-
kladovho pioudu. Uzaveni zapisovatele zajisti vypiazdnni inteinich buei
tohoto objektu a dosaeni konzistentniho koncovho stavu. Tepive po uzaveni
zapisovatele je mono zavit pioud.
Stejn jako v pipad pioud hiozi i zde, e objekt nebude uzaven a piostedky
uvolnny (navic zde me dojit i k nedenovan situaci, kdy zapisovatel neni
uzaven, ale podkladov pioud ano). l zde je pioto vhodnji pouiti konstiukce
'kody spiavuje Miciosof a mimo Windows jsou tm neznam. Navic v nich neexistuje adn
snadno zapamatovateln systm.
::
using. Optimalnim eenim je pak vyuiti dvou vnoench blok using, vnjiho
pio pioud a vnitniho pio zapisovatele (pidlovani a uvolovani piostedk se
dje ve spiavnm poadi).
using System.Text;
using System.IO;
....
using (FileStream stream =
new FileStream("cp1250.txt", FileMode.Create, FileAccess.Write)) {
using(TextWriter writer =
new StreamWriter(stream, Encoding.GetEncoding(1250))) {
writer.WriteLine("luoukkplbelskdy");
} / / zde je uvolnn zapisovatel
} / / zde je uvolnn pioud
Pokud nemate specialni poadavky na ieim oteveni a kodovani znakov sady
pak lze textov zapisovatel vytvoit volanim jedin statick metody tidy File.
using (TextWriter writer = File.CreateText("utf8.txt")) {
writer.WriteLine("luoukkplbelskdy");
}
Podkladov pioud je vytvoen v iamci tovaini metody File.CreateText a je uvolnn
pi uvolnni zapisovatele (pi volani jeho metody Dispose na konci bloku using).
Podkladov pioud lze ziskat piostednictvim metody StreamWriter.BaseStream,
ale toho je zapotebi zcela vjimen (do podkladovho pioudu nikdy nezapisuj-
te, ani jinak nemte!).
Metoda File.CreateText vytvai zapisovatel pio kodovani UTl-s znakov sady Uni-
code. To kodovani je nejpouivanjim exteinim kodovanim (tj. kodovanim pou-
ivanm pio data mimo adiesov piostoi aplikaci) a je asten kompatibilni se
staiim ASCll kodovanim (pokud zapisujete znaky s kodem menim ne 1z, je
vsledkem souboi, ktei je zaiove platnm ASCll i UTl-s souboiem). U tex-
t v eviopskch jazycich pouivajicich latinku je toto kodovani navic piostoiov
efektivni (jeden vjimen dva byty na znak). Hoii situace je u eck alfabety
a azbuky (vdy dva byty na znak) a bnch inskch znak (ti byty). Rozdilna
u staiich znakovch sad splva znakova sada s kodovanim. Pio znakovou sadu existovalo jen jedin
piiozen kodovani, v nm je pozice znaku ve znakov sad pimo ukladana jako bytova hodnota.
Uznakov sady Unicode je situace sloitji. Kad znak ma sice svou jedinenou pozici, ktei vak
me bt izn mapovan na posloupnost byt. Kiom kodovani UTl-s existuji i kodovani UTl-1e
nebo UTl-Iz.
Souboiov oiientovan vstup a vstup :
dlka kod jednotlivch znak tak ztuje indexaci ( nalezeni -tho znaku),
co diskvalikuje toto kodovani pio inteini iepiesentaci Unicode znak (pio n se
pouiva UTl-1e a UTl-Iz).
UTl-s je tak standaidnim kodovanim v modeinich Unixech (vetn Linuxu) a
to pedevim z dvod kompatibility s pvodni iepiesentaci znak v jazyce C
(UTl-s etzce mohou bt zakoneny jedinm nulovm bytem). Ve svt Win-
dows je situace sloitji. Bn se vyuivaji staii bytov oiientovana kodovani
(napiklad CP-1zc v esk veizi Windows) a intein UTl-1e. V kodovani webo-
vch stianek UTl-s jasn dominuje (zahinujic v sob i stianky s ASCll kodova-
nim), nebo jej vyuiva adov I/1 stianek (stav na konci ioku zc1z, podle http:
//w3techs.com/technologies/overview/character_encoding/all).
7.2.2. Textov orientovan vstup
Zakladni stiuktuia textov oiientovanho vstupu se nelii od vstupu. Kliovou
tidou je TextReader iesp. jeho specializace StreamReader. Objekty tchto tid po-
skytuji ti zakladni metody pio vstup (nktei ji zname z konzolovho vstupu)
string ReadLine()
te celou adku (po znak novho adku, ten ji neni ve viacenm etzci zahinut).
Na konci souboiu viaci hodnotu null.
int Read()
te nasledujici znak. Viaci jeho kod (1e-bitov) iozien na Iz bitov islo tidy
int. Na konci souboiu viaci hodnotu -1.
string ReadToEnd()
viaci cel text od aktualni pozice (vetn) v souboiu a do jeho konce. Je-li za-
volan bezpiostedn po oteveni souboiu (s aktualni pozici na pivnim znaku) je
najednou peten cel souboi. To je pohodln, ale u velkch souboi (v adu GiB)
se vsledn etzec nemusi vejit do opeiani pamti.
Obas se hodi i metoda int Peek(), kteia viaci pivni znak z pioudu, ale nevyjima
ho ( neposouva aktualni pozici v souboiu). Pi dalim teni jej pioto viati znovu.
Tato funkce se hodi v pipad, kdy se je poteba analyzovat stiuktuiu textu, v nm
nejsou jednotliv stiuktuiy oddleny oddlovai ( znaky, ktei nejsou souastmi
jednotlivch stiuktui, pouze je oddluji).
Podivejme se napiklad na nasledujici text
:
+14.05-25.37FRODO
Tento text lze snadno iozdlit na ti dili stiuktuiy (islo) 11.c, (islo) z.I a
slovo lRODO. Dili stiuktuiy nejsou oddleny adnm exteinim oddlovaem,
ale lze je vymezit na zaklad znak, ktei jsou jejich asti (nap. isla zainaji
znamnkem, etzec vskytem pivniho pismennho znaku). Tut stiuktuiu lze
zapsat i za pomoci explicitnich oddlova (nap. v CSV foimatu ve tvaiu 14.05,-
25.37,FRODO). Mnoh komunikani piotokoly a textov databaze vak pouivaji
foimu bez explicitnich oddlova (piavdpodobn z spoinch dvod, i kdy
tim pidavaji viasky piogiamatoim).
Pi zpiacovani tohoto typu textu se tou postupn jednotliv znaky pomoci metod
specializovanch na zpiacovani jednotlivch typ dilich stiuktui (zde by to byly
nap. metody ReadNumber a ReadWord) . Pioblmem jsou vak znaky na pomezi
jednotlivch stiuktui. Nap. znak l je nejdive peten v metod zpiacovavajici
isla, nebo z pohledu zapisu isla je to ukonovaci znak, ktei teni isla ukon-
uje. Zaiove to vak je pivni znak slova a musi tak bt petena a zpiacovan i
v metod pio teni slov. Jeden znak vak nelze ist dvakiat. Je vak mon vyuit
metodu Peek pio pedbnou kontiolu znaku (v metod pio zpiacovani zapisu is-
la), piozatimbez jeho teni. teni se piovede nasledn v metod, kteia zpiacovava
stiuktuiu, do ni tento hianini znak nalei.
lunkni (i kdy viazn zjednoduenou) implementace tidy pio textovou anal-
zu textovch souboi si ukaeme v nasledujicim zdiojovm textu (vetn jedno-
duchho testovaciho kodu).
using System; / / readnumbers.cs
using System.IO;
using System.Text;
using System.Globalization;
class SimpleParser {
private TextReader source;
public SimpleParser (TextReader source) { / /
this.source = source;
}
public SimpleParser (string path) { / /
int input;
StringBuilder result = new StringBuilder();
/ / pivni znak musi bt znamnko
input = source.Read();
if ((char)input != '+' && (char)input != '-') { / /
}
public bool TestAndSkipNewLine() { / /
int input;
int count = 0;
while ((input = source.Peek()) != -1) {
char c = (char)input;
if (c == '\n' || / /
get {
return source.Peek() == -1;
}
}
}
class MainClass {
public static void Main(string[] args) {
SimpleParser parser = new SimpleParser("testfile"); / /
SimpleParser stringParser
= new SimpleParser(new StringReader("+2-3\n-5.6+8.1\n"));
while (!parser.EndOfFile) {
double x = parser.ReadNumber();
double y = parser.ReadNumber();
Console.WriteLine("{0};{1}", x, y);
if (!parser.TestAndSkipNewLine())
throw new InvalidDataException("Newlineommited");
}
parser.Close();
}
}
Tida SimpleParser podpoiuje paisovani (textovou analzu) souboi, ktei obsa-
huji iseln daje oiganizovan do adk. Na kadm adku me bt vice isel,
ty vak nejsou oddleny explicitnim oddlovaem, ale (povinnm) znamnkem.
Pikladem me bt souboi se dvma iselnmi daji na na adku
+14.02+50.4
-2.57+10.02
+0.0-0.0
+100-100
Nov objekt tidy SimpleParser lze vytvoit bu nad pedanm textovm tena-
em, nebo si SimpleParser vytvoi tenae sam (a to nad souboiem, jeho jmno
pedame konstiuktoiu).
Pivni konstiuktoi
). Piotoe vak
me bt obtin souboi vytvoit a udiovat, lze vyuit i jednoduiho mechanis-
mu. Namisto tenae nad souboiovm pioudem lze vyuit instanci tidy Strin-
gReader, je je pouitelna na jakmkoliv mist, kde je oekavana instance obec-
nji tidy TextReader. Ukazkov text tak lze napsat pimo do piogiamu (neme
bt piiozen pili dlouh). Piklad vyuiti tenae nad etzcem je v testova-
cim piogiamu uveden, je vak zakomentovan. Pokud jej chcete vyzkouet, stai
jej odkomentovat (a zakomentovat oteveni paiseiu nad souboiemna pedchozim
adku).
7.2.3. dkov orientovan vstup a vstup
adkov oiientovan vstup a vstup je specialnim pipadem textov (iesp. zna-
kov) oiientovanho vstupu/vstupu. Zpiacovani celch adk textu vak pati
k nejastji implementovanm iutinam a je pioto pimo podpoiovano ve vech
piogiamovacich jazycich.
Kiom bnho teni, zpiacovani a vytvaeni textovch souboi se adkov oii-
entovan vstup/vstup pouiva i v dalich oblastech
1. piogiamovani textovch lti znamch pedevim z Unixu (typickm pi-
kladem jsou piogiamy cat, wc, giep a dali)
z. zpiacovani textov (pesnji adkov) oiientovanch inteinetovch pioto-
kol (HTTP, SMTP, POP)
I. geneiovani dynamickch WWW stianek (na nizk iovni)
Jako jednoduch (ale piaktick) piklad vytvoime piogiam(textov lti) pio cen-
zuiovani text. Na textov cenzoi nebude pili inteligentni, nebo bude cenzu-
iovat jen vskyty uiitch slov (pesnji jist xni posloupnosti znak) a to bez
ohledu na kontext. Nepipustna slova bude nahiazovat nahiadnimtextem(v aktu-
alni veizi piogiamu je to posloupnost znak x o dlce odpovidajici pvodnimu
textu).
Souboiov oiientovan vstup a vstup :e,
using System.Collections.Generic; / / censor.cs
using System.IO;
static class StringExtensions {
public static string FirstUpper (this string s) {
return char.ToUpper (s [0]).ToString () + s.Substring (1);
}
}
class Censor {
private List<string> suppressedWords = new List<string> ();
public Censor AddWord (string s) {
suppressedWords.Add (s);
suppressedWords.Add (s.ToUpper ());
suppressedWords.Add (s.FirstUpper ()); / / pouiti ioziujici metody
return this;
}
public void Censoring (TextReader input, TextWriter output) {
string line;
while ((line = input.ReadLine()) != null) {
foreach (string word in suppressedWords) {
string substitute = new string ('x', word.Length);
line = line.Replace (word, substitute);
}
output.WriteLine (line);
}
}
}
class MainClass {
public static void Main (string[] args) {
Censor c = new Censor ();
c.AddWord ("bomba").AddWord ("sex");
c.Censoring (Console.In, Console.Out);
}
}
Jadiem implementace cenzuiovaciho objektu ( instance tidy Censor) je seznam
nepipustnch slov. Tento seznam je na zaatku piazdn, lze jej vak ioziit po-
:e8
moci metody Add (tidy Censor). Metoda neni zcela tiivialni, nebo kiom vlast-
niho slova do seznamu pidava i jeho bn majuskulni vaiiace slovo tvoen
jen velkmi pismeny a slovo, jeho pivni pismeno je velk. To neni pili iobustni
eeni, nebo lze snadno stejn slovo vloit i vicekiat. To sice neovlivni vslednou
funkci, ale me to vst k viaznmu zpomaleni piogiamu. Nebezpei vicenasob-
nho vloeni lze sniit dslednm vkladanim slov jen v zakladnim minuskulnim
tvaiu ( slovo tvoen jen malmi pismeny).
Zohlednn majuskulni vaiianty tvoi jen malou podmnoinou vech majuskul-
nich vaiiaci. Vaiianty s velkmi pismeny na netypickch mistech nebudou cen-
zuiovany (pestoe jsou bez pioblm iteln). Pokiyti vech vaiiant by vak pio-
giam viazn zkomplikovalo (pedevim v substituni asti).
Vimnte si, e pio ziskani vaiianty s pivnim velkm pismenem je pouita jedno-
ducha ioziujici metoda (tida string tuto uitenou metodu bohuel nenabizi).
Pouita implementace neni pili efektivni, nebo bhem ni vznika a zanika iela-
tivn velk mnostvi objekt (dva vznikaji a dva zanikaji). Optimalizace pomoci
StringBuilderu je vak zbytena, nebo poet piovedeni tto metody je zavisl na
potu nepipustnch slov a jejich vaiiant (ielativn mal poet) a nikoliv na potu
slov v cenzuiovanm textu, jen je bn o nkolik ad vyi.
Dalim zajimavm iysem metody Consor.Add je jeji naviatova hodnota. Zatimco
obdobna metoda u seznam nic neviaci, je iozhiani a kontiakt nai metody zcela
jin. Jak lze snadno zjistit z kodu, nae metoda viaci odkaz na objekt adiesata (tj.
na instanci tidy Censor, na ni byla metoda aplikovana). Pio`
Odpov se skiva v testovacim piogiamu. Viaceni objektu adiesata umouje
tzv. zetzen voln metod. To miin zjednoduuje pidavani, nebo neni nutn
opakovat identikaci adiesata. Adiesat se postupn pedava od jednoho volani ke
diuhmu.
Zatimco bn (nezetzen) pidavani by mlo tvai
c.Add("sex");
c.Add("bomba");
lze pi pouiti dslednho viaceni adiesata pouit kiati (zetzen) tvai
c.Add("sex").Add("bomba");
Na uitenost zetzench volani existuji dosti piotikladn nazoiy nktei tvi-
di, e jsou zbyten a znepehleduje piogiam. Navic u metod s potencialnim
postiannim efektem neni zejm, zda se pedava stale stejn objekt (jen je tak
Souboiov oiientovan vstup a vstup :e,
mnohonasobn modikovan skuten zetzeni), nebo nov vytvaen kopie
(objekty jsou nemnn funkcionalni kolona). lxistuji vak i aktivni zastanci,
ktei tvidi, e piogiamatoi by ml mit alespo monost zetzeni pouit (a tudi
mit i vti svobodu). Podpoia zetzeni (tj. dsledn viaceni adiesata u modi-
kujicich metod, ktei by jinak nic neviaceli) si toti zetzena volani nevynucuje.
Metody lze samozejm volat i bez vyuiti jejich naviatovch hodnot. Me to si-
ce vst k malmu zpomaleni, ale s timsi vtinou poiadi i jednoducha automaticka
optimalizace v pekladai.
Knihovna .NlT zetzena volani pili nepodpoiuje (stai se podivat na modi-
kani metody kolekci), ale je dobi je znat alespo pasivn. lxistuji toti objektov
knihovny, ktei je vyuivaji masivn (nap. knihovna Jery v jazyce JavaScript).
Kliova metoda piovadjici cenzuiu (Censoring) je pimoaia. Paiametiem meto-
dy je objekt tidy TextReader ve funkci textovho vstupu a objekt tidy TextWri-
ter, do nho je zapisovan cenzuiovan text. Jadiem implementace je cyklus pes
vechny adky vstupu, za pouiti cyklu while, v jeho sloen podmince je adek
ten, ukladan do piomnn a vsledek poiovnavan s hodnotou null (iepiesentujici
konec souboiu). Obiat je dali inkainaci ckovskho cyklu pes vstupni hodnoty
(viz diskuse v pedchozi sekci).
Uvnit cyklu pes adky vstupu je vnoen cyklus pes vechna nepipustna slova
(uloena uvnit objektu v seznamu, jen je odkazovan datovm lenem suppres-
sedWords). V kad iteiaci vnoenho cyklu je volana metoda Replace, kteia viaci
nov etzec, v nm jsou vechny vskyty aktualniho nepipustnho slova na-
hiazeny nahiadnim textem. Potom je na tento nov text pesmiovan odkaz v
piomnn line (pvodni text adku je zapomenut). Nahiadni text je vytvoen po-
moci explicitniho konstiuktoiu tidy string, jen oekava vplov znak (u nas je
to x) a poet jeho opakovani (u nas je to dlka nahiazovanho slova).
Takto pojata implementace neni pili efektivni, nebo
1. nahiadni text vznika pio kad vstupni adek (bez ohledu na bude i nebude
pouit pio substituci)
z. nov (cenzuiovan) etzec me vznikat i v pipad, e se nepipustn
text na adku vbec nenachazi. Kontiakt metody Replace toti nespecikuje,
co se dje v pipad, e nahiazovan text v etzci vbec neni. Je viacen
pvodni etzec nebo jeho (nezmnna) kopie`
Lze-li pedpokladat, e se nepipustna slova vyskytuji jen zidka (jednou za n-
kolik desitek i stovek adk), pak je vhodnji nejdive otestovat pitomnost
:,o
nepitomnho slova v adku a a pak vytvoit nahiadni test a piovst substituci.
foreach (string word in suppressedWords) {
if (line.Contains(word)) {
string substitute = new string ('x', word.Length);
line = line.Replace (word, substitute);
}
}
Je-li naopak oekavana etnost nepipustnch slov vysoka (nkolik slov na adku),
pak je test nadbyten, na diuhou stianu je vak nutno eliminovat vytvaeni na-
hiady uvnit (vnoenho) cyklu. Optimalnim eeni je vytvoeni slovniku, ktei
mapuje texty na jejich nahiady. Kada poloka slovniku je inicializovana pouze
jednou v metod Censor.Add.
Na zavi se podivejme na vyuiti nov vytvoen tidy. Pokud chceme cenzuiovat
texty ze standaidniho vstupu a pio vstup vyuivat standaidni vstup, neni pote-
ba vytvaet novho itae a zapisovatele. Na mist pivniho paiametiu cenzuiova-
ci metody se pouije objekt, jen je viacen statickou vlastnosti System.Console.In.
Tento objekt tidy TextReader existuje v kadm konzolov oiientovanm piogia-
mu. Podobn existuje i vlastnost viacejici instanci tidy TextWriter iepiesentujici
standaidni vstup System.Console.Out.
Standaidni vstup iesp. vstup vyuiva konzoli (v unixov teiminologii teiminal),
lze je vak pesmiovat na iovni shellu. To se vyuiva pedevim v Unixu, kde
jsou pomoci mechanismu pesmiovani implementovany nap. kolony.
Na mist tenae a zapisovatele, vak lze pouit i objekty tidy StreamReader iesp.
StreamWriter
using (TextReader reader = File.OpenText("original.txt"),
TextWiter writer = File.CreateText("censored.text")) {
c.Censoring(reader, writer);
}
Oba vstupn-vstupni objekty musi bt po svmpouiti uzaveny, a pioto by mla
bt vyuita konstiukce using. Opioti dive uvedenm ukazkam je vyuita iozi-
ena syntaxe umoujici vytvoeni vice objekt v hlavice (jednotliv denice a
inicializace jsou oddleny aikou).
kiom standaidniho vstupu a vstupu podpoiuje Unix i tzv. standaidni chybov vstup. Tento
vstup je alespo foimaln dostupn i v konzolovch aplikacich MS Windows. V.NlT je dostupn
pomoci statick vlastnosti System.Console.Error
A. Pehled syntaxe (EBNF)
Pio popis syntaxe piogiamovacich jazyk existuje specializovan (meta)jazyk
oznaovan jako Bausova-Naurova normln forma (nebo jen Bausova nor-
mln forma). Tento metajazyk se popiv pouival pio zapis jazyka Algol (zaatek
ec. let). l kdy je tento metajazyk schopen popsat libovoln bezkontextov jazyk
(viz http://en.wikipedia.org/wiki/Context-free_grammar) a tudi dokae popsat pod-
statnou ast syntaxe vech piogiamovacich jazyk, je zapis v BNl dosti iozvlan.
Pioto vznikla jeho ioziena veize EBNF (Extended Baus-Naur form), kteia pe-
vzala nktei syntaktick pivky iegulainich viaz (pedevim tzv. kvantika-
toiy). Ma stejnou popisnou silu, viazn vak zkiacuje popis jazyka, nebo neni
nutno denovat nktei pomocn neteiminaly.
Zapis v lBNl obsahuje ti zakladni typy symbol
terminly text, jen se pimo objevi v textu popisovanho jazyka tj. v naem
pipad pimo ve zdiojovm textu piogiamu
neterminly pojmenovan odkazy na dive (i vjimen pozdji) denovan
syntaktick pivky. Neteiminaly jsou ve vslednm textu nahiazeny piav-
mi stianami denic (za znakem ). Pokud denice na piav stian obsa-
huje (alespo jeden) neteiminal, pokiauje nahiazovani iekuizivn (dokud
nezstanou je teiminaly)
opertory spojuji i modikuji zapisy lBNl. Zakladnim opeiatoiem je svislit-
ko, ktei oddluje jednotliv vaiianty. Pi iozvijeni se musi vdy zvolit jed-
na z vaiiant (ale piav jen jedna!). Dali opeiatoiy zavisi na diuhu pouit
lBNl. Zde jsou to napiklad tzv. kvantikatoiy (opakovae), ktei denuji,
e uiita ast piavidla je nepovinna, i se me vicekiat opakovat.
Syntaxe pouit lBNl notace
terminl
teiminalni symbol (text pouivan pimo ve zdiojovm kodu)
neterminl~
z1
:,:
neteiminal tj. odkaz na jin syntaktick piavidlo. Neteiminaly zainajici
a konici pomlkou nejsou explicitn denovany, nebo oznauji znaky z
jist znakov mnoiny, kteiou nelze zapsat vtem. Jejich vznam vyplva
z pouitho jmna neteiminalu.
opertor vznam
oddlova alteinativ
* c a neomezen opakovani
- 1 a neomezen opakovani
` c a 1 opakovani (nepovinna ast)
n piav opakovani
( lBNl ) seskupeni pi aplikaci opakovae na sloenou lBNl denici
Omezen
Syntakticka piavidla uvedena nie nepopisuje vechny platn zdiojov texty ja-
zyka C=! Od pln denice jazyka se lii v tchto (vzajemn se pekivajicich)
bodech
popsany jsou pouze konstiukce zaveden v tchto skiiptech. Jazyk C= vak
podpoiuje i dali konstiukce, ktei jsou nejen platn, ale i v piaxi asto
vyuivan.
nejsou zahinuty nktei zidka pouivan kombinace syntaktickch pivk.
To umonilo viazn zjednoduit a pedevim zpehlednit nkteia syntak-
ticka piavidla (nap. neteiminalu pio vraz). Pikladem eliminovan kom-
binace je monost pouiti piazeni na libovolnm mist viaz (napiklad
na mist skutenho paiametiu)
denice v nkteich pipadech zohleduji (nepovinn) zus. Vynucuji si
tak napiklad pouiti velkch pismen na zaatku jmen tid, nebo piivatni
datov leny.
piavidla nezohleduji nejen nepovinn, ale i povinn pouivani mezeio-
vch znak (vetn odadkovani). Mezeiov znaky mohou bt mezi jak-
mikoliv teiminalnimi symboly (a tudi i neteiminaly). Povinn jsou jen mezi
dvma teiminaly tvoenmi alfanumeiickmi znaky. Zahinuti bilch znak
by viazn zkomplikovalo zapis piavidel a pioto se nepouiva ani u piofe-
sionalnich lBNl denic.
Pehled syntaxe (lBNl) :,
Pedevim si je vak nutno uvdomit, e lBNl nedokae vyjadit kontextov za-
visla syntakticka piavidla (pestoe jsou mnohdy tiivialni). Pomoci lBNl tak nelze
napiklad zapsat poadavek, e pi pouiti nekvalikovanho jmna ( jmna bez
jmennho piostoiu) je nutno tento piostoi impoitovat pomoci denice using. Po-
dobn nelze zapsat piavidlo, e kada piomnna musi bt ped pouitim deno-
vana.
Zcela mimo monosti lBNl (a jakkoliv bezkontextov giamatiky) jsou i typov
kontioly. Nelze si tudi vynutit piavidlo, e podminka cyklu while musi bt viaz
viacejici instanci tidy bool (a adn jin). Kontiolovat nelze ani spiavn pouiti
opeiatoi a tim spie metod. l kdy nae syntakticka piavidla pipoutji napi-
klad zapis "Frodo"[0] * "Gandalf".Add(3), nezaiuuje to jet, e bude spn
peloen (znakem nelze nasobit a etzec nema metodu Add).
To, e piogiam lze popsat pomoci lBNl piavidel, je pouze nutna nikoliv dosta-
ujici podminka jeho syntaktick spiavnosti a peloitelnosti pekladaem.
Kontiola smantick spiavnosti, je pak zcela mimo monosti foimalnich notaci
(nezvlada to ani peklada).
A.1. Znaky a poznmky
majuskule~ A B Z
minuskule~ a b z
psmeno~ majuskule~ minuskule~
oktalov-slice~ 0 1 2 3 4 5 6 7
dekadi-slice~ oktalov-slice~ 8 9
alfanumeri-znak~ psmeno~ dekadi-slice~
hexadecimln-slice~
dekadi-slice~
a b c d e f
A B C D E F
poznmka-dkov-bn~
// -unicode-znak-vyjma-lomtka~
-unicode-znak-vyjma-oddkovn-~* -nov-dek-~
poznmka-dkov-dokumentan~
/// -unicode-znak-vyjma-oddkovn-~* -nov-dek-~
:,
poznmka-blokov~
/* -unicode-znak-~* */
poznmka~
poznmka-dkov-bn~
poznmka-dkov-dokumentan ~
poznmka-blokov~
mezerov-znak~ -tabultor-~ -nov-dek-~ poznmka~
A.2. Identifiktory
identiktor-promnn~ minuskule~ alfanumeri-znak~*
identiktor-metody~ majuskule~ alfanumeri-znak~*
identiktor-vlastnosti~ majuskule~ alfanumeri-znak~*
identiktor-poloky-vtu~ majuskule~ alfanumeri-znak~*
identiktor-primitivn-tdy~
int double char string bool byte
identiktor-jmennho-prostoru~
majuskule~ alfanumeri-znak~* ( . majuskule~ alfanumeri-znak~* )*
prost-jmno-tdy~ majuskule~ alfanumeri-znak~*
seznam-typov-parametr~ identiktor-tdy~ ( , identiktor-tdy~ )*
jmno-specializace-generi-tdy~
prost-jmno-tdy~ seznam-typovch-paiameti ~
kvalikovan-jmno-tdy~
identiktor-jmennho-prostoru~ . prost-jmno-tdy~
identiktor-jmennho-prostoru~ . jmno-specializace-generi-tdy~
identiktor-tdy~
prost-jmno-tdy~
jmno-specializace-generi-tdy~
kvalikovan-jmno-tdy~
identiktor-primitivn-tdy~
A.3. Literly
dekadi-int-literl~ dekadi-slice~-
Pehled syntaxe (lBNl) :,
hexadecimln-int-literl~ 0x hexadecimln-slice~-
celoseln-literl~ dekadi-int-literl~ hexadecimln-int-literl~
double-literl~
dekadi-slice~- . dekadi-slice~*
dekadi-slice~- . dekadi-slice~* e dekadi-slice~
dekadi-slice~- e dekadi-slice~
seln-literl~ celoseln-literl~ double-literl~
nikov-sekvence~
\" \' \\ \t \n \u hexadecimln-slice~1
ar-znak~
-unicode-znak-vyjma-apostrofu-~ nikov-sekvence~
znakov-literl~ ' ar-znak~ '
string-znak~
-unicode-znak-vyjma-uvozovky-~ nikov-sekvence~
etzcov-literl~ " string-znak~* "
boolovsk-literl~ true false
literl~
seln-literl~ znakov-literl~
etzcov-literl~ boolovsk-literl~
A.4. Vraz
aditivn-binrn-opertor~ + -
multiplikativn-binrn-opertor~ * / %
aritmeti-binrn-opertor~
aditivn-binrn-opertor~ multiplikativn-binrn-opertor~
opertor-inkrementace~ ++
opertor-dekrementace~ --
aritmeti-unrn-opertor~ - +
opertor-shodnosti~ == !=
opertor-uspodn~ < > >= <=
relan-opertor~ opertor-shodnosti~ opertor-uspodn ~
:,e
binrn-logi-opertor~ && ||
unrn-logi-opertor~ !
unrn-opertor~ aritmeti-unrn-opertor~ unrn-logi-opertor~
binrn-opertor~
aritmeti-binrn-opertor~
relan-opertor~
binrn-logi-opertor~
seznam-vraz~ vraz~ ( , vraz~)*
voln-stati-metody~ identiktor-tdy~` . identiktor-metody~
( seznam-vraz~` )
voln-instan-metody~ primitivn-vraz~ . identiktor-metody~
( seznam-vraz~` )
strukturovan-inicializtor~ { seznam-vraz~ }
voln-konstruktoru~
new identiktor-tdy~ seznam-parametr~ strukturovan-inicializtor~`
l-vraz~
identiktor~
identiktor~ . identiktor-promnn~
identiktor~ . identiktor-vlastnosti~
identiktor~ [ vraz~ ]
primitivn-vraz~
l-vraz~
literl~
voln-instan-metody~
voln-stati-metody~
voln-konstruktoru~
identiktor-tdy~ . identiktor-poloky-vtu~
( vraz~ )
vraz~
primitivn-vraz~
vraz~ binrn-opertor~ vraz~
unrn-opertor~ vraz~
( identiktor-tdy~ ) craz~
vraz~ ? vraz~ : vraz~
piazen~
l-vraz~ = vraz~
Pehled syntaxe (lBNl) :,,
l-vraz~ binrn-opertor~ = vraz~
l-vraz~ opertor-inkrementace~
l-vraz~ opertor-dekrementace~
opertor-inkrementace~ l-vraz~
opertor-dekrementace~ l-vraz~
piazen-s-porovnnm~ ( piazen ~ ) opertor-shodnosti~ vraz~
A.5. Pkazy
vrazov-pkaz~
piazen ~ ;
vraz~ opertor-inkrementace~ ;
vraz~ opertor-dekrementace~ ;
voln-instan-metody~ ;
voln-stati-metody~ ;
pkaz-ukonen-metody~ return vraz~ ;
pkaz-ukonen-cyklu~ break ;
pkaz-vyhozen-vjimky~ throw voln-konstruktoru~ ;
pkaz-skoku~
pkaz-ukonen-cyklu~
pkaz-ukonen-metody~
pkaz-ukonen-cyklu~
pkaz-vyhozen-vjimky~
przdn-pkaz~ ;
jednodu-pkaz~ pkaz-skoku~ vrazov-pkaz~ przdn-pkaz~
denin-pkaz~
denice-promnn~ ;
denice-promnn-s-inicializac ~ ;
blok~ { pikaz- }
podmnkov-konstrukce~
if ( vraz~ ) pkaz~
if ( vraz~ ) pkaz~ else pkaz~
seznam-denic-s-inicializac~
denice-promnn-s-inicializac ~ ( , denice-promnn-s-inicializac ~ )*
konstrukce-using~ using ( seznam-denic-s-inicializac ~ ) blok~
:,8
while-cyklus~
while ( vraz~ ) pkaz~
while ( piazen-s-porovnnm~ ) pkaz~
for-cyklus~
for ( denice-promnn-s-inicializac ~ ; vraz~ ; piazen ~ )
pkaz~
forea-cyklus~
foreach ( denice-promnn~ in primitivn-vraz~ )
pkaz~
cyklus~ while-cyklus~ for-cyklus~ forea-cyklus~
sloen-pkaz~ podmnkov-konstrukce~ cyklus~
pkaz~
jednodu-pkaz~
denin-pkaz~
blok~
sloen-pkaz~
A.6. Definice tdy
speciktor-pstupu~ public private
denice-datovho-lenu~
private denice-promnn~ ;
private denice-promnn-s-inicializac ~ ;
denice-parametru~
denice-promnn~
ref denice-promnn~
out denice-promnn~
seznam-formln-parametr~
denice-parametru~
( , denice-parametru~ )* ( , denice-promnn-s-inicializac ~ )*
denice-promnn-s-inicializac ~ ( , denice-promnn-s-inicializac ~ )*
denice-konstruktoru~
public prost-jmno-tdy~ ( seznam-formln-parametr~ ) blok~
nvratov-typ~ identiktor-tdy~ void
Pehled syntaxe (lBNl) :,,
denice-metody~
speciktor-pstupu~ nvratov-typ~ identiktor-metody~
( seznam-formln-parametr~ ) blok~
getter~ get blok~
setter~ speciktor-pstupu~` set blok~
denice-vlastnosti~
speciktor-pstupu~ nvratov-typ~ identiktor-metody~
{ geer~ seer~` }
speciktor-pstupu~ nvratov-typ~ identiktor-metody~
{ get; ( speciktor-pstupu~ set; )` }
denice-tdy~
class prost-jmno-tdy~ {
denice-datovho-lenu~-
denice-konstruktoru~*
denice-metody~-
}
seznam-formln-parametr-roziujc-metody~
this denice-promnn~ ( , seznam-formln-parametr~ )`
denice-roziujc-metody~ public static
nvratov-typ~ identiktor-metody~
( seznam-formln-parametr-roziujc-metody~ ) blok~
denice-tdy-pro-roziujc-metody~
static class prost-jmno-tdy~ {
denice-roziujc-metody~-
}
seznam-poloek-vtov-tdy~
identiktor-poloky-vtu~ ( = celoseln-literl~ )`
( , identiktor-poloky-vtu~ ( = celoseln-literl~ )` )*
denice-vtov-tdy~
enum prost-jmno-tdy~ {
seznam-poloek-vtov-tdy~
}
denice-nejvy-rovn~
denice-tdy~ denice-tdy-pro-roziujc-metody~ denice-vtov-tdy~
:8o
A.7. Program
import-jmennho-prostoru~ using identiktor-jmennho-prostoru~ ;
startovac-metoda~
public static void Main ( ) blok~
tda-startovac-metody~
static class prost-jmno-tdy~ {
startovac-metoda~
}
program~
import-jmennho-prostoru~*
denice-nejvy-rovn~*
tda-startovac-metody~
B. Pedvn parametr
Jazyk C= nabizi velmi iiok iepeitoai iznch mechanism pedavani paiamet-
i. Kiom bnch vstupnich paiameti jsou to dva typy paiameti pedavanch
iefeienci (vstupni a vstupn-vstupni) a pedavani vaiiabilniho potu paiameti
pomoci pole. Pi specikaci paiameti lze navic nktei paiametiy vynechavat
(ty pak nabvaji pedem uiench implicitnich hodnot) iesp. je lze identikovat
jmnem nikoliv pozici. adn z ve uvedench mechanism neni nezbytnm
iysem jazyka (v zasad si jakkoliv jazyk vystai s bnmi pozinimi vstupnimi
paiametiy), ale v mnoha pipadech znan zpehleduji a zkiacuji zapis. Jedna se
tedy o typick syntaktick pozlatko.
B.1. Vstupn parametry
Vstupni paiametiy sloui k pedavani objekt z volan funkce do funkce vola-
jici (tedy v opanm smiu opioti bnm paiametim). Dopluji tak zakladni
mechanismus naviatov hodnoty zajiovan pikazem return.
Vpiaxi by se vak mly pouivat jen v pipad skuten poteby. Ve vtin pipa-
d je mnohem pehlednji viacet objekty v pepiavce (doasnm objektu, jeho
jedinou funkci je spojit nkolik objekt do jedinho). Vstupni paiametiy nejsou
v mnoha jazycich vbec podpoiovany (pedevim z dvod jejich sloitosti).
Vstupni paiametiy funguji na piincipu odkaz na piomnn (tzv. pedvn pa-
rametr referenc ). Do metody se peda odkaz na piomnnou (nikoliv na objekt!).
Tato piomnna nesmi bt navic inicializovana (dvod je zejm vstupni pa-
iametiy nemohou slouit k penosu infoimace do funkce).
Uvnit metody (optimaln tsn ped jejim ukoneni) lze do odkazovan piomn-
n vloit objekt (je-li jeji tida iefeienni) nebo iefeienci na nj (je-li jeji tida
hodnotova). Stai pouze piadit objekt do vstupniho paiametiu. Po skoneni
volani tak nalezneme objekt (i iefeienci na nj) v piomnn, kteia byla pedana
na mist vstupniho paiametiu.
zs1
:8:
Tiochu matouci me bt skutenost, e pi pouiti iefeiennich typ na mist v-
stupnich paiameti, musime piacovat s pedstavou dvojit iefeience (tj. iefeience
na iefeienci). Z pohledu volan funkce, je vstupni paiameti bnou piomnnou,
do ni lze bn piazovat odkaz na objekt. Ve skutenosti to vak je odkaz na
jinou piomnnou (existujici vn volan funkce), kteia tepive obsahuje odkaz na
objekt. Jazyk ped nami ob iefeience skiva, dobi piogiamatoi vak musi mit
o tchto iefeiencich povdomi.
Podivejme se nasledujici ukazkov kod, v nm je metoda se dvma paiametiy.
Jeden je vstupni, diuh vstupni.
static bool TestOutParam(string inpar, out string outpar) {
inpar = "false_output"; / / nema adn skuten efekt
outpar = "output"; / / nastaveni pedan piomnn
/ / stav v tomto mist, viz obiazek B.1
return true;
}
/ / volani
string vstup = "input";
string box; / / neninicializovana
bool result = TestOutParam(vstup, out box);
Console.WriteLine(s); / / vypie input
Console.WriteLine(box); / / vypie output
Piazeni do paiametiu inpar je bn piazeni do lokalni piomnn. Tato pio-
mnna vznikla na zaatku metody a byl do ni zkopiiovan odkaz na objekt-etzec
input. Tento odkaz byl pivotn uloen v piomnn vstup (a stale se v ni nachazi).
Tato piomnna lei v jin metod a tak k ni zevnit metody TestOutParamnemame
adn pistup (na iozdil od objektu, ktei byl ped piazenim obma piomnn-
mi sdilen). Po piazeni odkazuje piomnna inpar nov etzec (false output). Je
to vak zcela zbyten, nebo dive ne staime etzec pouit, metoda skoni, lo-
kalni piomnn zanikaji a etzec se stava nedostupnm (a bude piavdpodobn
bizy odstiann z pamti). V piomnn vstup samozejm stale zstava odkaz na
pvodni objekt ( etzec input)
Piazeni do vstupniho paiametiu outpar vypada navenek zcela stejn, inteini
iealizace je vak zcela jina a viazn se lii i dsledky. Piomnna outpar toti neni
bnou piomnnou, ale doasnm odkazem na piomnnou, kteia byla pouita na
mist diuhho paiametiu (se specikaci out). Zde tedy odkazuje piomnnou box.
Odkaz na objekt-etzec output je tak uloen do piomnn box (tato piomnna
je uvnit metody viditelna jen pes odkaz). Po skoneni piomnna-odkaz zanika
Pedavani paiameti :8
(je tak lokalni), ale v pedan piomnn (box) zstava nova hodnota (tj. jedna se
skuten o vstupni paiameti).
Pio jistotu se jet podivejte na obiazek B.1, ktei ukazuje stav tsn ped ukon-
enim funkce (tj. ped pikazem return).
vstup
box
inpar
outpar
kontext volajc metody
kontext metody
TestOutParam
string:output
string:input string:false_output
hromada (heap)
loit! objekt"
Obiazek B.1. Pedani vstupniho paiametiu iefeienci
B.2. Obecn pedvn parametr referenc
Uiitm zobecnnim vstupnich paiameti jsou parametry pedvan referenc
(iesp. odkazem). Tyto paiametiy jsou vstupn-vstupni tj. lze je vyuivat jak pio
penos dat do metody, tak i pio penos opanm smiem.
Stejn jako u vstupnich paiameti je jejich zakladem iefeience na piomnnou v
nadizen metod. Tato piomnna vak musi bt ped ped pedanim inicializo-
vana tj. musi obsahovat objekt nebo objekt odkazovat. Tento objekt je nasledn
dostupn uvnit volan metody (nepimo pes odkaz na piomnnou) tj. funguje
jako vstup. Odkazovanou piomnnou vak lze stejn jako u vstupnich paiamet-
i zmnit tj. nahiadit objekt za jin (nov vytvoen). Tento objekt peije zanik
volan metody a me tak bt vyuit jako jeji vstup.
Paiametiy pedavan iefeienci se v C= pouivaji jen zidka (dokonce mn asto
ne paiametiy vstupni). Navic nejsou v mnoha jazycich vbec podpoiovany (Ja-
va, Python) a to vetn mnoha jazyk vyuivajicich platfoimu .NlT (Iron Python).
Pioto je pouivejte jen ve skuten vjimench situacich. Ve vtin pipad je
:8
lze nahiadit bnm (vstupnim) paiametiem a bnou naviatovou hodnotou (v
pipad poteby v iamci pepiavky spojujicich vice vslednch objekt).
Navic lze potebu pedavani iefeienci tm vdy eliminovat vyuitim pedavani
mnitelnch objekt iefeiennich typ. Uvnit metody lze pedan objekt bez
potii modikovat, piem se tyto zmny zachovaji i po ukoneni metody (tj.
metody mohou mit na pedanch objektech vedleji efekt). To sice neni tak siln
jako viaceni novho objektu, ale ve vtin pipad to postauje.
Syntakticky se pedavani paiameti iefeienci oznauje pomoci kliovho slova
ref, a to jak ped denici foimalniho paiametiu (v denici funkce) tak i ped
skutenm paiametiem (piomnnou) v iamci volani (obdobn jako u kliovho
slova out).
Klasickm pikladem metody vyadujici pedavani iefeienci (bez monosti jed-
noduchho opsani) je metoda pio zamnu obsahu dvou piomnnch (swap). Tato
metoda neni bnou instanni metodou, nebo objekt adiesata nelze pedat iefe-
ienci. Musi to bt funkce tj. staticka metoda bez vazby na na objekt i tidu sku-
tench objekt. loimaln vak musi bt denovana ve tid (k ni vak nemusi
mit adn vztah) jako staticka (tidni) metoda. Me bt denovana napiklad ve
tid s hlavni (Main) metodou.
using System;
class MainClass {
public static void Swap<T>(ref T a, ref T b) {
T p = a; / / ben algoiitmus vmny pes pomocnou piomnnou
a = b;
b = p;
}
public static void Main(string[] args) {
string x = "Ahoj";
string y = "svete";
Swap(ref x, ref y); / / volani s iefeienci na dv piomnn
Console.WriteLine("{0}{1}", x, y);
}
}
Pedavani paiameti :8
Metoda Swap je denovana jako geneiicka, tj. pio paiametiy mohou bt instan-
cemi libovoln (ale toton) tidy, oznaen foimaln jmnem T'. Tento identi-
katoi je pouit i pi denici pomocn piomnn. Piomnna tak bude mit stejn
typ jako paiametiy (tj. me obsahovat i odkazovat objekty stejnho typu jako
jsou paiametiy).
Pi pouiti (volani) peklada zjisti typ obou pedanch piomnnch. Pokud jsou
stejn (v naem piklad jsou oba typu string), je vytvoena a peloena metoda, v
ni je kad vskyt identikatoiu T nahiazen skutenm jmnem tidy (zde tedy
identikatoiem string). Tato specializovana metoda pak pijme iefeienci na ob
piomnn a piovede zamnu jejich obsahu.
l kdy je tento piklad zajimav a poun, v piaxi byste mli vmnu piovst
spie pimmkodem(bez vyuiti metody). Neni to o mnoho deli a lze jej snadnji
poitovat do jinch jazyk.
public static void Main(string[] args) {
string x = "Ahoj";
string y = "svete";
string p = x;
x = y;
y = p;
Console.WriteLine("{0}{1}", x, y);
}
'T je identikatoi, na jeho mist lze pouit libovoln jmno (podle zu by vak mlo zainat velkm
T)
C. Rozshlej programy
Tato piloha obsahuje komentovan vpis tch piogiam, jejich iozsah neumo-
nil zahinuti do hlavniho textu skiipt.
C.1. Vyrovnvac pam (generick verze nad
slovnkem)
Tato veize vyiovnavaci pamti vyuiva slovnik a fiontu pio vytvoeni efektivni
a pitom iychl vyiovnavaci pamti. Vyiovnavaci pam ma omezenou velikost
(maxSize) a po jejim pekioeni se maou nejdle alokovan poloky (tj. poloky
od jejich vloeni ubhlo nejvice asu).
Tida je implementovana jako geneiicka, tj. jedna se pouze o ablonu, z ni je kon-
kitni tida vytvoena dosazenim konkitnich jmen tid namisto obecnch iden-
tikatoi TKey (tida pio objekty kli) a TValue (tida pio objekty ukladanch
hodnot). Lze tak vytvaet individualni tidy vyiovnavacich pamti pizpsoben
pio ukladani hodnot libovoln (konkitni) tidy s kliem (obecn jin, avak tak
libovoln tidy).
class Cache<TKey, TValue> {
public int MaxSize { get; private set; } / / maximalni velikost
private Dictionary<TKey, TValue> data = new Dictionary<TKey, TValue>();
private Queue<TKey> keyQueue = new Queue<TKey>(); / / fionta alokaci
public Cache (int maxSize) {
MaxSize = maxSize;
}
public void Insert(TKey key, TValue value) {
if (data.Count >= MaxSize) {
data.Remove(keyQueue.Dequeue()); / / vyjmuti nejstaii hodnoty
zs
:88
}
data.Add(key, value); / / pidani hodnoty (pod danm kliem)
keyQueue.Enqueue(key);
}
public bool Contains(TKey key) {
return data.ContainsKey(key);
}
public TValue Find(TKey key) { / / vjimka, pi pistupu k piozatim neuloen hodnot
return data[key];
}
public TValue Find(TKey key, TValue defaultValue) {
TValue box;
return data.TryGetValue(key, out box) ? box : defaultValue;
}
}
Pouivani pedpoklada, e uivatel instance tidy nejdive zkontioluje pitomnost
hodnoty s danmkliem. Pidat je me jen v pipad, kdy si je jist, e vyiovnavaci
pam danou hodnotu neobsahuje. V opanm pipad je chovani nedenovan.
Ve vtin pipad vznikne vjimka (opakovan vloeni klie do podkladovho
slovniku), vjimen se to vak me zdanliv podait (je-li pislun kli vyjmut
pi uvolovani mista).
Piklad vyuiti (ukladana jsou data, kliem je jejich etzcova identikace)
Cache<string, DateTime> cache = new Cache<string, DateTime>();
....
DateTime finish;
if(cache.Contains("konecsveta"))
finish = cache["konecsveta"];
else {
finish = prophet.GetProphecy("konecSveta").Date; / / velmi pomala opeiace
cache.Insert("konecsveta", finish);
}
Rozsahleji piogiamy :8,
C.2. Program pro zjitn velikosti kolizn skupiny
v hashovac tabulce
Pomocn piogiam vyuit pio geneiovani giaf na obiazku e.1 na stian zIc. lm-
plementovany jsou dv tidy. Pomocna tida Counter vyuiva slovnik pio iealizaci
itae vsledk hashovaci funkce. Piotoe kliem mohou bt jen kladna isla (viz
dale), mapuje slovnik hodnoty tidy uint na poet (iepiesentovan jako int). Uint
(zkiatka za unsigned int) je specializovana iselna tida, jejimi instancemi jsou
kladna cela isla v iozsahu c a z
Iz
.
Hlavni tidou je HashTester, je vypoitava piminou velikost kolizni skupiny.
Kolizni skupina je mnoina kli se stejnou hodnotou hashovaciho indexu ( v-
sledku hashovaci funkce).
Hashovaci hodnota je ziskavana pio vechny hodnoty pedan kolekce (kolekce
musi bt schopna piochazeni tj. musi implementovat iozhiani IEnumerable). Pio
ziskani hashovaci hodnoty je vyuita metoda GetHash, kteiou poskytuji vechny
objekty. Tato metoda viaci islo typu int tj. islo v iozsahu z
I1
a z
I1
1. Toto is-
lo je petypovano na typ uint tj. tiansfoimovano do iozsahu c a z
Iz
(zapoina isla
se stavaji velkmi kladnmi). Potom je pevedeno do iozsahu c a HashTableSize
(velikost hashovaci tabulky) pomoci opeiace zbytek po dleni (hashovaci hodnota
je tedy vdy kladna). etnost iznch hashovacich hodnot je akumulovana po-
moci itae a nasledn je z tchto etnosti vypotena pimina velikost kolizni
skupiny (pomoci tiivialniho algoiitmu).
Hlavni piogiamvytvai textovou tabulku piminch velikosti pio tabulky o veli-
kosti a z1c potu hashovanch objekt (kiok je ). Hashovan objekty jsou
ziskany z textovho souboiu (ten vznikl expoitem a piavou excelovsk tabulky
z piimainiho zdioje http://www.mvcr.cz/soubor/2012-zctpr-zctpr-rijen-zip.aspx).
using System; / / hashtester.cs
using System.Collections.Generic;
using System.IO;
using System.Globalization;
class Counter { / / specializovan ita vskyt
private Dictionary<uint, int> c = new Dictionary<uint, int>();
public void Occur(uint o) {
if (c.ContainsKey(o)) {
:,o
c[o]++;
} else
c[o] = 1;
}
public int Frequency(uint o) {
return c.ContainsKey(o) ? c[o] : 0;
}
public IEnumerable<uint> Keys {
get { return c.Keys;}
}
}
class HashTester {
public uint HashTableSize { get; private set; }
public HashTester (uint hashTableSize) {
this.HashTableSize = hashTableSize;
}
public double MeanCollisionGroupSize(IEnumerable<object> keys) {
Counter counter = new Counter();
foreach (object key in keys)
counter.Occur((uint)(key.GetHashCode()) % HashTableSize);
int sum = 0;
int count = 0;
foreach (uint index in counter.Keys) {
int freq = counter.Frequency(index);
sum += freq;
count++;
}
return (double)sum / (double)count;
}
}
class MainClass {
public static void Main() {
List<string> names = new List<string>(500000);
TextReader tfile = File.OpenText("/home/fiser/doc/prijmeni");
string name;
Rozsahleji piogiamy :,1
while ((name = tfile.ReadLine()) != null)
names.Add(name);
double count = (double)names.Count;
for (double k=0.05; k<=2.1; k+=0.05) {
uint size = (uint)(k*count);
HashTester tester = new HashTester(size);
Console.WriteLine("{0},\t{1}", k.ToString(),
tester.MeanCollisionGroupSize(names).ToString());
}
}
}
Piklad vstupniho souboiu (zkiaceno, ve skutenosti ma tm pl milionu adek
a .s MiB)
A HASAN
AALTONENOV
ABAD GONZLEZ
ABANINOV
....
JAK
ERRIU
MANOLEA
HOUTENBRINK
Piklad vstupu (pouito neutialni jazykov nastaveni, v Linuxu pouijte nasta-
veni LANGC)
0.05, 20.0003619254434
0.1, 10.000985320732
0.15, 6.67519830351511
0.2, 5.0351708428246
0.25, 4.07519480838721
0.3, 3.4593137698145
...
1.85, 1.29914139210979
1.9, 1.2899794578107
1.95, 1.28119002661047
2, 1.2744075088595
2.05, 1.26713766694353
Seznam obrzk
1.1. Objektov oiientovan piogiamovaci jazyky . . . . . . . . . . . . . . . . . 1c
1.z. Objekty a tidy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
z.1. Skladani z elementainich objekt . . . . . . . . . . . . . . . . . . . . . . . 1v
z.z. Zetzen volani metody . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ic
z.I. lndexace v etzci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ie
z.1. Denice a inicializace piomnn pio objekty hodnotovch tid . . . . . . . 11
z.. Denice a inicializace piomnn pio objekty iefeienni tidy . . . . . . . . 1I
z.e. Sloitji denice a inicializace . . . . . . . . . . . . . . . . . . . . . . . . . 11
z.. Vmna obsahu dvou piomnnch . . . . . . . . . . . . . . . . . . . . . . . 1v
I.1. Jmenn piostoi System a jeho podpiostoiy . . . . . . . . . . . . . . . . . . s
I.z. Poitani slov (piklad) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ev
1.1. Asymptoticka sloitost. Piklady funkci . . . . . . . . . . . . . . . . . . . . vv
1.z. lnteini stiuktuia seznamu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1cz
1.I. Cyklus foi, iozboi piovadni . . . . . . . . . . . . . . . . . . . . . . . . . . 11s
1.1. Chybn algoiitmus selektivniho vmazu . . . . . . . . . . . . . . . . . . . 1z1
1.. Kopiiovani objekt s vice iovnmi odkaz (poateni stav) . . . . . . . . 1z
1.e. Kopiiovani objekt s vice iovnmi odkaz (stav po duplikaci) . . . . . . . 1z
1.. Kopiiovani objekt s vice iovnmi odkaz (stav po pidani adku) . . . . 1zs
1.s. Kopiiovani objekt s vice iovnmi odkaz (konen stav) . . . . . . . . . 1zv
1.v. Test setidni seznamu (typy pibh) . . . . . . . . . . . . . . . . . . . . 1Is
1.1c. Logika vtveni v tle cyklu (test setidnosti) . . . . . . . . . . . . . . . . . 11e
.1. Vznik objektu (s podobjekty hodnotovch tid) . . . . . . . . . . . . . . . . 1
.z. Piomnn a objekty pi vytvaeni seznamu mnitelnch objekt . . . . . . 1es
.I. Sniovani zavislosti mezi objekty . . . . . . . . . . . . . . . . . . . . . . . . 1sz
.1. Piomnn a objekty pi vytvaeni seznamu nemnitelnch objekt . . . . . 1s1
.. Ukazka kompozice objektu tidy Cae . . . . . . . . . . . . . . . . . . . . 1vs
e.1. Slovnik zobiazeni kli na hodnoty . . . . . . . . . . . . . . . . . . . . . zcv
e.z. Slovnik jako iepiesentace ielani tabulky . . . . . . . . . . . . . . . . . . . z1
zvI
:,
e.I. List tabulkovho piocesoiu idk pole . . . . . . . . . . . . . . . . . . . . zz1
e.1. Velikost kolizni skupiny pio hashovaci funkci nad etzci . . . . . . . . . . zIc
e.. Hashovaci tabulka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zI1
.1. Stiuktuia l/O tid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zI
B.1. Pedani vstupniho paiametiu iefeienci . . . . . . . . . . . . . . . . . . . . zsI