Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Algoritmické konstrukce

Podobné prezentace


Prezentace na téma: "Algoritmické konstrukce"— Transkript prezentace:

1 Algoritmické konstrukce
Rudolf Pecinovský Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

2 Obsah s odkazy Datové typy Literály Další informace o třídách
Operátory a operace Rozhodování v programu Hodnotové a odkazové objektové typy Cykly Spustitelné aplikace Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

3 Datové typy Lokální konstanty a proměnné
Jednorázová deklarace více konstant či proměnných Primitivní a objektové typy Správce paměti a jeho uklízeč Obalové třídy 29–31 35–40 147–156 197–204 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

4 Datové typy Veškerá data, s nimiž chceme v programu v Javě pracovat, musí mít předem určen svůj datový typ, který definuje, co jsou příslušná data zač Java dělí datové typy do tří skupin Typ-netyp void Primitivní datové typy – pouze 8 zástupců: boolean, byte, short, int, long, float, double, char, Objektové datové typy – vše ostatní (ve standardní knihovně Javy 6.0 je definováno přes datových typů, z toho je 3777 veřejných) Při práci s daty musíme používat data deklarovaného typu nebo typů s ním kompatibilních Při práci s hodnotami objektových typů dostane v Javě (a obecně ve všech moderních programovacích jazycích) žadatel vždy pouze odkaz na daný objekt Atové typy Opakování Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

5 Lokální data – konstanty a proměnné
Prozatím jsme deklarovali proměnné a konstanty pouze jako atributy; svoje data mohou mít i metody Data deklarovaná uvnitř metody označujeme jako lokální data metody; patří mezi ně Parametry = lokální data deklarovaná v hlavičce metody – jejich počáteční hodnoty nastavuje volající metoda Běžná lokální data = data deklarovaná v těle metody – jejich počáteční hodnoty je třeba nastavit v těle metody U lokálních dat nefunguje automatická inicializace, musíte je vždy inicializovat sami Parametry inicializuje volající metoda Lokální proměnné a konstanty si musí metoda inicializovat sama Použití neinicializovaného lokálního data je syntaktická chyba Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

6 Deklarace lokálních dat
Data metod jsou zásadně soukromá, zvenku nepřístupná (s výjimkou nastavování počátečního hodnot parametrů) Je možno je deklarovat jako konstanty i proměnné Nesmí u nich být žádné modifikátory přístupu, z probraných je povolen pouze modifikátor final Je možno je deklarovat na kterémkoliv místě programu, kam je možno zadat příkaz Ukládají se spolu s návratovou adresou na zásobník, a proto přestávají existovat v okamžiku opuštění metody Protože se většinou jedná o pomocné proměnné => jsou i nich tolerovány i jednoznakové identifikátory Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

7 Příklad použití lokálních dat
public Strom_3c( int x, int y, int šířka, int výška, int podílŠířkyKmene, int podílVýškyKmene ) { int výškaKmene = výška / podílVýškyKmene; int výškaKoruny = výška - výškaKmene; int šířkaKmene = šířka / podílŠířkyKmene; int posunKmene = ( šířka - šířkaKmene) / 2; koruna = new Elipsa( x, y, šířka, výškaKoruny, Barva.ZELENÁ ); kmen = new Obdélník( x+posunKmene, y+výškaKoruny, šířkaKmene, výškaKmene, Barva.HNĚDÁ ); } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

8 Jednorázová deklarace více dat
V jedné deklaraci je možno deklarovat několik konstant či proměnných současně Podmínkou je, aby všechna současně deklarovaná data měla stejné modifikátory a typ Jednotlivé deklarace v sadě pak oddělujeme čárkami public static final int MIN = 0, MAX = 10; private Barva SVIT=Barva.BÍLÁ, TMA=Barva.ČERNÁ; private static final Směr8 NAHORU = Směr8.SEVER, DOLU = Směr8.JIH, VLEVO = Směr8.ZÁPAD, VPRAVO = Směr8.VÝCHOD; Celá deklarace má společný dokumentační komentář => výhodné pouze u soukromých dat Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

9 Opakování Obalové třídy
Řada metod odmítá pracovat s hodnotami primitivních typů Aby mohly hodnoty primitivních datových typů vystupovat v programu jako instance objektových typů, je ke každému primitivnímu typu přiřazen jeho obalový objektový typ, který je objektovým obalem kolem příslušné hodnoty Primitivní Obalový boolean Boolean byte Byte char Character double Double float Float int Integer long Long short Short void Void Opakování Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

10 Obalové třídy a Java 5.0 Java 5.0 zavedla automatickou konverzi mezi hodnotami primitivních typů a instancemi jejich obalových typů Vyžaduje-li metoda či operátor hodnotu jednoho a my mu dodáme hodnotu druhého, překladač ji automaticky převede int i = 15; Integer ii = i / 2; i = Math.abs( ii = 10 ); Nebezpečí: Snížení efektivity programu Nepříjemné důsledky plynoucí ze specifických vlastností některých obalových typů – viz např. Pecinovský: Java 5.0 – Novinky jazyka a upgrade aplikací, CP Books 2005, ISBN Knihu je možno stáhnout ve formátu PDF na adrese Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

11 Literály Literály – jejich výhody a nevýhody
Literály primitivních datových typů Řetězcové literály 29–31 35–40 147–156 197–204 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

12 Literály Literál = konstanta pojmenovaná svojí hodnotou
3, "Ahoj", 'A', true, null, … Java umožňuje zadávat literály všech primitivních typů + textové řetězce (instance třídy String) + prázdný odkaz Používání „magických hodnot“ (= literálů) uvnitř programu je považováno za nevhodné Literály snižují srozumitelnost Literály snižují modifikovatelnost Za akceptovatelné jsou považovány pouze 0, 1, "", null, true, false Za magické hodnoty jsou považována všechna čísla s výjimkou nuly a jedničky (a někdy i ty) Před použitím literálů uvnitř programu se dává přednost používání běžných pojmenovaných konstant, kterým na počátku programu přiřadím pomocí literálu hodnotu Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

13 Logické literály a prázdný odkaz
true – ANO, pravda, false – NE, nepravda Prázdný odkaz (odkaz nikam) – null Lze jej přiřadit jako hodnotu kteréhokoliv odkazu Tento odkaz lze pouze porovnat s jiným odkazem, nic jiného s ním není možno dělat Posílání zprávy instanci prostřednictvím prázdného odkazu patří mezi nejčastější chyby; systém na ně odpovídá vyhozením výjimky NullPointerException Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

14 Celočíselné literály Celočíselné literály lze zadávat ve třech číselných soustavách; použitá soustava se pozná podle začátku čísla: 0x = šestnáctková (hexadedicmální) soustava: 0xA = 10; 0xFF = 255 0 (nula následovaná číslicemi) = osmičková (oktalová) soustava: 012 = 10; = 255 Nezačíná nulou = desítková soustava Počáteční + se psát může, ale nemusí Hodnoty typu long je třeba psát s příponou L či l 0L, 9_876_543_210L, -1L – syntaktická chyba, na celé číslo je moc velké Pro zadání hodnot typu byte a short je třeba použít operátoru přetypování (viz dále) byte b = (byte)0; Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

15 „Reálné“ literály U reálných literálů se pro určení typu používají přípony D nebo d pro čísla typu double: 1d; –3D F nebo f pro čísla typu float: 1f; –3F Při zadávání desetinné části se používá desetinná tečka Implicitním typem reálných čísel je double double d = 1.23; float f = 1.23f; //f = 1.23 je syntaktická chyba Čísla je možno zadávat buď v přímém, nebo v semilogaritmickém (vědeckém) tvaru Přímý tvar: 1.23 Semilogaritmický tvar: 1.23e2 (=1,23.102) 3e-3 (=3.10-3) Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

16 Znakové literály Znaky, které je možno přímo zadat, se píší mezi apostrofy 'ž', 'X', '©', '±', '$', '«', 'Ξ', 'گ', '♣' Znaky je možno zadat také přímo jejich kódem ve formátu \uHHHH, kde H představuje hexadecimální číslici, nebo \OOO, kde O představuje oktalovou číslici (nepoužívat) Některé řídící znaky mají vlastní způsob zápisu označovaný jako escape sekvence \b = \u0008 = backspace – odmazání předchozího znaku \t = \u0009 = HT = horizontální tabulátor \n = \u000A = LF (line feed) – přechod na další řádek \f = \u000C = FF (form feed) – přechod na další stránku \r = \u000D = CR (carriage return) – přechod na počátek řádku \" = \u0022 = uvozovky (double quote) \' = \u0027 = apostrof (single quote) – '\'' \\ = \u005C = zpětné lomítko (backslash) Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

17 Řetězcové literály Textové řetězce jsou instance objektového typu String String je (zatím) jediný objektový typ, který má vlastní literály Textový řetězec zadáváme jako posloupnost znaků uzavřenou mezi uvozovkami Uvnitř literálu nesmějí být řídící znaky (např. odřádkování), místo nich je třeba zadat příslušné escape sekvence "První řádek\nDruhý řádek\fDalší stránka" Znaky, které nechcete zadávat přímo (např. kvůli převodu mezi platformami) je možno zadávat kódem Místo "Přenositelná čeština" zapíšeme "P\u0159enositeln\u00E1 \u010DE\u0161tina" Místo Příliš žluťoučký kůň úpěl ďábelské ódy zapíšeme P\u0159\u00EDli\u0161 \u017Elu\u0165ou\u010Dk\u00FD k\u016F\u0148 \u00FAp\u011Bl \u010F\u00E1belsk\u00E9 \u00F3dy Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

18 Další informace o třídách
Třídní členy Inicializační blok a statický konstruktor Zavedení třídy a její inicializace Postup při vytváření instancí Spuštění celého programu Soubory JAR BlueJ a vytváření souborů JAR 61–66 183–185 473–477 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

19 Opakování Třídy a jejich členy Dělení členů
Třídní × instanční Datové (atributy) × funkční (metody) × typové (třídy a rozhraní) Instanční členy mají vždy vazbu na svoji instanci Atributy jsou umístěny v paměti přidělené jejich instanci Metody mají skrytý parametr this odkazující na jejich instanci Třídy mají skrytý atribut Vnější.this odkazující na jejich instanci Členy, které patří celé třídě označujeme modifikátorem static Specifika třídních členů Atributy jsou všemi instancemi sdíleny; o každé změně hned všechny vědí Metody je možno volat před vytvořením první instance Jako třídní členy lze použít i rozhraní (nesmějí mít atribut, takže jen třídní) Opakování Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

20 Vytvoření instance O vytvoření zcela nové instance je třeba požádat virtuální stroj (ostatní mechanizmy pouze kopírují dříve vytvořený objekt) Ostatní mechanizmy: klonování, serializace Postup vytváření nové instance Připraví (= vyhradí a vynuluje) na haldě místo pro budoucí instanci Vloží do něj odkaz na tabulku virtuálních metod (VMT) Připraví odkaz na vytvářenou instanci (this) jako nultý parametr Vyhodnotí předávané parametry a připraví je k předání Zavolá konstruktor rodiče Prochází program a v pořadí dle zdrojového kódu Inicializuje instanční konstanty a proměnné Spouští instanční inicializační bloky Vstoupí do těla konstruktoru a provede je Vrátí žadateli (volajícímu programu) odkaz na vytvořenou instanci Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

21 Statické a instanční členy – ukázka
public class Zaměstnanec { private static int počet; private String jméno; private String příjmení; public Zaměstnanec( String jméno, String příjmení){ this.jméno = jméno; this.příjemní = příjmení; počet ++; } public static int getPočetZaměstnanců(){ return početZaměstnanců; Zaměstnanec: početZaměstnanců: 1 Zaměstnanec: početZaměstnanců: 2 Zaměstnanec: početZaměstnanců: 0 1 2 Zaměstnanec_1: jméno: Pepa příjmení: Zdepa Zaměstnanec_1: jméno: příjmení: this this Zaměstnanec_2: jméno: Jana příjmení: Vdaná Zaměstnanec_2: jméno: příjmení: ++ ++ jana: pepa: počet: 2 počet: 0 počet: int počet = Zaměstnanec.getPočetZaměstnanců(); Zaměstnanec pepa = new Zaměstnanec ( "Pepa", "Zdepa" ); Zaměstnanec jana = new Zaměstnanec ( "Jana", „Vdaná" ); počet = Zaměstnanec.getPočetZaměstnanců(); ? Pepa Zdepa Jana Vdaná ? Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

22 Inicializační blok Na úrovni metod je možno definovat i nepojmenovaný blok příkazů Tento blok je součást konstruktoru a spouští se v rámci inicializací atributů těsně před vlastním tělem konstruktoru Nepojmenovaný inicializační blok je náhražkou konstruktoru v situacích, kde klasický konstruktor není možno použít Označíme-li nepojmenovaný blok modifikátorem static vytvoříme tak blok, který nahrazuje konstruktor třídy ® bývá označován jako statický konstruktor public class Třída { private final int[] pole = načti(); private final int součet; { for( int i=0,s=0; i < pole.length; s += pole[i++] ); součet = s; } public Třída() {} int getPrvek(int i) {return pole[i];} Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

23 Statický inicializační blok
V tomto bloku můžeme provádět akce, které je třeba vykonat před zavedením třídy do paměti Nepojmenovaný statický blok je jediné místo, kde je možno inicializovat statické konstanty (samozřejmě kromě jejich deklarace) Inicializačních bloků může být libovolné množství, definice více než jednoho bloku však není vhodná, protože znepřehledňuje program Inicializační bloky se spouštějí v okamžiku, kdy na ně při průchodu programem dojde řada => v statickém inicializačním bloku nesmíme používat data, která jsou deklarována až po něm Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

24 Inicializace třídy Třída se zavádí do paměti, až když ji někdo potřebuje Obrací-li se někdo na třídu poprvé, tj.: Žádá po třídě hodnotu jejího dostupného atributu Volá nějakou třídní metodu Volá konstruktor virtuální stroj zjistí, že třídu ještě nemá zavedenou, a požádá zavaděč tříd (ClassLoader), aby ji zavedl Povolaná instance třídy ClassLoader: Najde binární obraz třídy (class soubor, pole bajtů, …) Vytvoří její objekt Prochází „kód“ a inicializuje třídní atributy a spouští statické inicializační bloky Předá objekt třídy virtuálnímu stroji Třídu lze vytvořit i za chodu programu, a to do binárního pole Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

25 Správa dynamické paměti
Instance objektových typů vznikají zásadně na haldě (heap), kterou spravuje správce paměti (memory manager) Aby mohl správce spravovat paměť spolehlivě a efektivně, potřebuje, aby mu do toho nikdo „nekecal“ => proto k instancím nikoho nepustí a nutí nás se k nim obracet pouze prostřednictvím příslušných odkazů Instance je držena v paměti do chvíle, dokud ji někdo potřebuje, tj. dokud si na ni někdo drží odkaz Instance, na níž se již nikdo neodkazuje, je předána uklizeči, který ji příležitostně „uklidí“ a tím uvolní její místo v paměti Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

26 Uklízeč (garbage collector)
Uklizeč (garbage collector) je program (spíš modul), který je nedílnou součástí správce paměti a je zodpovědný za odstraňování nepotřebných instancí Jeho činnost je tak klíčová, že je často vydáván za správce paměti O tom, kdy bude paměť uvolněna rozhoduje pouze uklizeč, není šance mu jakékoliv rozhodnutí vnutit Metody, které uklízeče „spouští“ (např. System.gc()), jej pouze upozorňují, že se programátor domnívá, že nyní je vhodný čas na úklid; rozhodnutí o tom, co a kdy se bude uklízet je ale zcela v kompetenci uklízeče Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

27 Rozhodování v programu
Jednoduchý podmíněný příkaz Úplný podmíněný příkaz Násobná selekce Přepínač 11–15 159–176 227–234 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

28 Jednoduchý podmíněný příkaz
Používá se v situaci, kdy se program rozhoduje, zda něco udělá či neudělá Jednoduchý_podmíněný_příkaz: if ( logický_výraz ) příkaz Používá se pro něj označení příkaz if Příklad: int abs( int n ) { if( n < 0 ) n = -n; return n; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

29 Úplný podmíněný příkaz
Používá se v situaci, kdy si program může vybrat jednu ze dvou možností pokračování Úplný_podmíněný_příkaz: if ( logický_výraz ) příkaz else příkaz Používá se pro něj označení příkaz if-then-else Příklad: int abs( int n ) { if( n < 0 ) return -n; else return n; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

30 Rozhodování mezi více možnostmi
Používá se posloupnost úplných příkazů, tj. v části else se znovu použije úplný podmíněný příkaz Příklad: int sgn( int n ) { if( n < 0 ) return -1; else if( n > 0 ) return 1; else return 0; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

31 Přepínač Používá se v situaci, kdy se program rozhoduje mezi více možnostmi na základě hodnoty výrazu Přepínač: switch ( výraz_typu_int ) { ¶ [ návěští : [ příkaz ]… ] Návěští musí být celočíselná (int) konstanta vyhodnotitelná v době překladu Nemají-li se provádět příkazy následujících větví, je třeba vyskočit z větve příkazem break Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

32 Přepínač – příklad public void popojeď( int klávesa ) {
switch( klávesa ) case ŠIPKA_VLEVO: posunVlevo(); break; case ŠIPKA_VPRAVO: posunVpravo(); case ŠIPKA_VZHŮRU: posunVzhůru(); case ŠIPKA_DOLŮ: posunDolů(); default: CHYBA(); } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

33 Přehled operátorů podle arity Operace × příkazy Méně známé skutečnosti
Operátory a operace Přehled operátorů podle arity Operace × příkazy Méně známé skutečnosti 31–37 197–204 237–241 451 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

34 Přehled operátorů podle arity
Nulární Konstanty: null true false Unární Prefixové: ! Postfixové: Binární (infixové) Aritmetické: * / % Porovnávací: < <= == != >= > Logické: & | && || Bitové: ~ & | ^ << >> >>> Přiřazovací: = += -= *= /= %= |= &= ^= <<= >>= >>>= Ostatní: instanceof . (kvalifikace) () (přetypování; není infixový) Ternární Podmíněný výraz: ?: Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

35 Operace × příkazy Všechny operace provedou požadovanou činnost se svými operandy a vrátí nějakou hodnotu I přiřazení je operace; vrací přiřazovanou hodnotu Výraz je tvořen sledem operací; z výrazu uděláme příkaz tím, že za něj zapíšeme středník; do té doby je to vždy jen výraz, který může vystupovat jako operand v jiných výrazech První z následujících deklarací je syntakticky korektní (i když prasácká): int i, j = (i=3) * 3; Color c = new Elipsa().getBarva().getColor(); IGUI g = new GUI( new MojeCPU() ); Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

36 Operátor přetypování V závorce se zadává název typu, na nějž přetypováváme, za závorkou výraz, jehož hodnotu přetypováváme Příklad: System.out.println( "Znak=" + (char)34 ); Hodnoty číselných primitivních typů je možno libovolně vzájemně přetypovat u ostatních musíme vědět, že je přetypování korektní Instance třídy implementující rozhraní je v případě potřeby automaticky přetypována na instancí daného rozhraní Víme-li, že nějaká instance je instancí dané třídy, můžeme ji na tuto třídu přetypovat public boolean equals( Object o ) { if( !(o instanceof Pozice) ) return false; Pozice p = (Pozice)o; return (this.x == p.x) && (this.y == p.y); } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

37 Převody mezi primitivními typy
Převody z „menšího“ typu na „větší“ je ochoten dělat překladač byte ® short ® int ® long ® float ® double char ® int Pro převody z „většího“ typu na „menší“ je třeba použít operátor přetypování Při převodu z reálných typů na celočíselné se useknou desetinná místa Při převodu double ® float se pouze ztratí platné číslice Při převodu mezi celočíselnými typy se ztratí významnější bity byte b = (byte) 300; //b = 300 – 256 = 44 Při převodu velkých reálných čísel na celá se dosadí největší celé číslo int i = (int) 1e12; //i = Při převodu int/long ® float a long ® double se ztrácejí platné číslice: Platných číslic: int 9; long 18; float 6; double 15 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

38 Znaky a celá čísla Znaky jsou uloženy jako dvoubajtové kódy (případně jako posloupnost dvou dvoubajtových kódů) Rozdílná podstata znaků a čísel se projeví až ve chvíli, kdy se daná hodnota tiskne Do znakových dat (char) lze libovolně vkládat celá čísla (int) a do celočíselných dat lze libovolně vkládat znaky char c; //Následující přiřazení jsou c = 9; //navzájem ekvivalentní c = (char)9; c = '\t'; c = '\u0009' Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

39 Méně známé skutečnosti
Aritmetické operace Typ výsledku záleží na typu operandů; „větší“ operand přehlasuje „menší“ Operace nad hodnotami typů short a byte vrací výsledek typu int byte b1=1, b2=2, b3=(byte)(b1 + b2); U binárních se levý operand vyhodnocuje vždy první int i = 2, j = (i=3) * i; //j = 9 Operátory && a || aplikují zrychlené vyhodnocení, tj. znají-li po vyhodnocení levého operandu výsledek, pravý již nevyhodnocují; operátory & a | vyhodnotí vždy oba operandy Test (n & 1) vrací informaci o tom, je-li n liché Bitový posun <<, resp. >> je rychlejší verzí násobení, resp. dělení mocninou dvou Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

40 Vlastnosti některých operací
Operátory inkrementace a dekrementace ++ a -- Přičtou, resp. odečtou od svého argumentu jedničku To, jestli operátor vrátí hodnotu před nebo po provedení operace záleží na umístění operátoru vůči jeho operandu Ukázky použití: viz např. modrá učebnice str. 201 Ternární operátor (podmíněný výraz) V závislosti na výsledku vyhodnocení prvního operandu vrátí hodnotu druhého nebo třetího operandu Ukázky použití: viz např. modrá učebnice 451 int abs = (x > 0) ? x : -x; Dělní nulou U celých čísel vyhazuje chybu ArithmeticException: / by zero U reálných čísel vrací hodnotu Double.POSITIVE_INFINITY, resp. Double.NEGATIVE_INFINITY Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

41 Složené operátory přiřazení
Slučují operaci prováděnou s proměnnou, do níž se přiřazuje výsledek operace Šetří opakované psaní levého operandu x op= y ≡ x = x op (y) //Závorka v předchozím výrazu je důležitá int i=1, j=10, k=100; i *= j + k; // i = 1 * ( ) //NE i = 1 * Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

42 Sčítání textových řetězců
Třída String je (zatím) jediný objektový typ, který má vlastní přetížený operátor Je-li kterýmkoliv z operandů operátoru + textový řetězec (= instance třídy String), převede se i druhý operand na textový řetězec a výsledkem je řetězec vzniklý jejich sloučením "Ahoj" + "Franto" ® "AhojFranto" Výraz "" + x může sloužit jako převod či přetypování libovolné hodnoty x na textový řetězec Pozor na typy operandů v „součtu“ Vyhodnocuje se zleva doprava, vždy se dva sečtou a výsledek použije Výraz (10 + '\n' + " kusů") má hodnotu "20 kusů" Výraz ("Kusů: " '\n') má hodnotu "Kusů: 10\n" Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

43 Hodnotové a odkazové objektové typy
Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

44 Primitivní a objektové typy
Java pro zvýšení efektivnosti dělí datové typy na: Primitivní někdo je označuje jako hodnotové, protože se u nich pracuje přímo s hodnotou daného objektu (číslo, znak, logická hodnota) Objektové někdo je označuje za referenční, protože se u nich pracuje pouze s odkazem („referencí“) na objekt Dělení na hodnotové a odkazové není terminologicky vhodné protože objektové typy dále dělíme na hodnotové a odkazové Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

45 Trocha češtiny Někteří autoři označují odkazové typy jako referenční
Z jazykového hlediska je to stejná chyba, jako překládat control (řídit)  kontrolovat (check) Reference (česky) = zpráva, dobrozdání, doporučení, posudek Viz Akademický slovník cizích slov, ISBN , str. 652 Reference (anglicky) = zmínka, narážka, odkaz, vztah, … Viz Velký anglicko-český slovník, nakl. ČSAV , str. 1181 Obdobně referovat  odkazovat Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

46 Důsledek odkazové podstaty objektů
Ukazují-li dva odkazy na jeden objekt, pak změna stavu objektu vyvolaná zasláním zprávy prostřednictvím jednoho odkazu je současně změnou stavu objektu odkazovaného druhým odkazem public int coVrátímObj() { Obdélník o1, o2; o1 = new Obdélník(); o2 = o1; o1.setŠířka( 200 ); return o2.getŠírka(); } public int coVrátímPrim() { int i1, i2; i1 = 19; i2 = i1; i1 = 2 * i1; return i2; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

47 Šířka obdélníků graficky
x = 0 y = 0 šířka = 100 výška = 50 i1: 19 i1: ??? i1: 38 19 38 19 x = 0 y = 0 šířka = 200 výška = 50 o2: 200 i2: 19 i2: ??? 19 public int coVrátímO() { Obdélník o1, o2; o1 = new Obdélník(); o2 = o1; o1.setŠířka( 200 ); return o2.getŠírka(); } public int coVrátímP() { int i1, i2; i1 = 19; i2 = i1; i1 = 2 * i1; return i2; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

48 Dělení objektových datových typů
Odkazové datové typy (reference data types) Neuvažujeme o hodnotách, objekt představuje sám sebe, nemá smysl hovořit o ekvivalenci dvou různých objektů Příklady Geometrické tvary Vlákna Hodnotové datové typy (value data types) Objekt zastupuje nějakou hodnotu Objekty se stejnou hodnotou se mohou vzájemně zastoupit => má smysl hovořit o jejich ekvivalenci Obalové typy, zlomky, velká čísla a další matematické objekty Barvy, časy, data Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

49 Dělení hodnotových objektů
Proměnné (mutable) Hodnota jejich atributů se může v průběhu života měnit – viz příklad z počátku přednášky Nesmějí se používat v některých situacích Neměnné (immutable) Hodnotu, která jim byla přiřazena „při narození“ zastupují až do své „smrti“ Chovají se obdobně jako hodnoty primitivních typů a také je s nimi možno obdobně zacházet Metody, které mají měnit hodnotu objektu, musejí vracet jiný objekt s touto změněnou hodnotou Hodnotové typy bychom měli vždy definovat jako neměnné Proměnné hodnotové typy jsou pro program nebezpečné, a proto je používáme pouze výjimečně, máme-li pro jejich použití opravdu pádné důvody Objektový Odkazový Hodnotový Proměnný Neměnný Primitivní Typ Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

50 Porovnávání objektů Při porovnávání objektů zjišťuje operátor == pouze to, jedná-li se o shodné instance Požadujeme-li test shody hodnot, používáme volání metody equals(Object), která zjišťuje rovnost hodnot Všechny třídy dostanou tuto metodu nadělenou od systému, její implicitní verze vrací totéž, co operátor == U odkazových objektových typů to vyhovuje, u hodnotových typů musíme definovat jejich vlastní verzi Ruku v ruce s metodou equals(Object) by měla jít i definice metody hashCode(), která je s ní velmi úzce svázána Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

51 Metoda equals(Object)
public class Pozice { public final int x, y; //... Konstruktor a jiné metody vynechávám public boolean equals( Object o ) { if( !(o instanceof Pozice) ) return false; Pozice p = (Pozice) o; return (x == p.x) && (y == p.y); } Kontrakt Reflexivní: a.equals(a) == true Symetrická: a.equals(b) == b.equals(a) Tranzitivní: a.equals(b) & b.equals(c) <= a.equals(c) Konzistentní (co platí teď, musí platit pořád – proto musí být neměnné) Nenullové: a.equals(null) == false Zdánlivě obrácený směr šipky je důsledkem toho, že implikace je ekvivalentní s operaci "menší nebo rovno" Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

52 Doporučení pro tvorbu neměnných objektů
Používání proměnných hodnotových objektů výrazně snižuje robustnost a bezpečnost programů Neměnné musí zůstávat jen atributy, jejichž hodnoty používají metody equals(Object) a hashCode() Atributy neovlivňující výsledky těchto metod se mohou měnit, protože na nich hodnota instance nezávisí Příklad: Atributy počítající počet použití dané instance, počet volání některé metody atd. V definovaných třídách by měly všechny „změnové metody“ vytvářet nové instance Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

53 Sčítání textových řetězců podruhé
Třída String definuje hodnotový neměnný typ => sloučením řetězců vznikne vždy nový objekt public static void testShodyŘetězců() { String sa = "Ahoj", sb = sa; boolean rovno, equals; sa += "!"; // sa="Ahoj!" rovno = (sa == sb+"!"); // false equals = sa.equal(sb+"!"); // true Systém.out.println( "Shoda instancí: " + rovno "\nShoda hodnot: " + equals ); } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

54 Příklad: Zlomek public class Zlomek { private final int c; //čitatel
private final int j; //jmenovatel; public Zlomek plus(Zlomek z) { //this. return new Zlomek( this.c * z.j + z.c * j, this.j * z.j ); } public Zlomek krát(Zlomek z) { return new Zlomek( c * z.c, j * z.j ); public boolean equals( Object o ) { if((o == null) || (!o.instanceof Zlomek)) return false; Zlomek z = (Zlomek) o; return (c == z.c) && (j == z.j); Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

55 Cykly K čemu jsou cykly Cyklus s počáteční podmínkou
Cyklus s koncovou podmínkou Cyklus s parametrem Nekonečný cyklus Cyklus s podmínkou uprostřed Cyklus přes iterovatelné objekty 45–48 497–517 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

56 Cykly – obecný přehled Cykly jsou datové konstrukce specifikující jak budeme část kódu opakovat Části cyklu Hlavička – rozhoduje o vstupu do těla Tělo cyklu – obsahuje opakovanou část kódu Patička – rozhoduje o opakování po ukončení těla Cykly je možno do sebe vnořovat, příkazem v těle cyklu může být jiný cyklus Cykly je možno definovat tak, že je lze při splnění definované podmínky opustit i uprostřed těla cyklu Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

57 Cyklus s počáteční podmínkou (while)
Cyklus_while: while ( podmínka ) příkaz Příkaz v těle cyklu se nemusí provést ani jednou Příkaz v těle může být prázdný while( ! klávesaStisknuta() ) ; Většinou se jako tělo používá složený příkaz public int nsd( int a, int b ) { while( a != b ) { if( a < b ) { int p=a; a=b; b=p; } a -= b; } return a; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

58 Cyklus s koncovou podmínkou (do – while)
Cyklus_do_while: do příkaz while ( podmínka ) ; Tělo cyklu se vždy provede nejméně jednou Prázdné tělo se nepoužívá, jako tělo se většinou používá složený příkaz public int nsd( int a, int b ) { do { if( a < b ) { int p=a; a=b; b=p; } a %= b; } while( a != 0 ); return b; } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

59 Cyklus s parametrem (for)
Cyklus_for: for( Inicializace ; Podmínka ; ¶ Modifikace ) Příkaz Inicializace: [ Výraz ] [ Deklarace ] Podmínka: [ Logický_výraz ] Modifikace: [ Výraz [, Výraz ] ] Kteroukoliv část je možno vynechat, pro mne je for(;;) ikona nekonečného cyklu Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

60 Příklad: výpočet faktoriálu
//Klasický cyklus s parametrem public static int faktoriál_I(int n) { if( n <= 1 ) return 1; int fakt = 2; for(int i = 3; i <= n; i++) { fakt *= i; } return fakt; //Cyklus s parametrem bez těla public long faktoriál_L( int n ) { long fakt = 2; for(; n > 2; fakt *= n-- ); //Rekurzivní volání public long faktoriál_R( int n ) { return n * faktoriál_R( n - 1 ); Cyklus je někdy výhodné nahradit rekurzí Rekurze = operace, při níž metoda volá přímo nebo zprostředkovaně sama sebe U rekurze musíme myslet na ukončení, jinak přeteče zásobník návratových adres Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

61 Cyklus s podmínkou uprostřed
Nekonečný cyklus Řada programů běží jako nekonečný cyklus Optimální zápis: for(;;) { /*tělo*/ } Lze použít i while(true) { /*tělo*/ } Cyklus s podmínkou uprostřed volíme, je-li nutno pro test podmínky něco připravit a po testu něco udělat K výskoku z těla cyklu slouží příkaz break K ignoraci části těla od podmínky k patě a novému skoku na test v hlavičce slouží příkaz continue Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

62 Příklad značkyKeZdi /***************************************************** * Dojde se zadaným robotem až ke zdi a cestou pokládá * na všechna navštívená pole včetně výchozího značky * r Robot,který má značkovaně dojít ke zdi */ public void značkyKeZdi( Robot r ) { for(;;) r.polož(); if( r.zeďPřed() ) break; r.krok(); } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

63 Příkaz break s návěštím
Potřebujeme-li v kódu definovat složitější přesun než je pouhý výskok z nejvnitřnějšího cyklu, můžeme použít příkaz break s návěštím Návěští označuje blok, z nějž daný příkaz právě vyskakuje Jako návěští slouží identifikátor za nímž následuje dvojtečka Návěští se vkládá před blok, z nějž budeme příslušným příkazem break vyskakovat Příkazem break s návěštím nemusíme vyskakovat pouze z cyklu, ale můžeme jej použít k výskoku z libovolného bloku

64 Princip použití příkazu break s návěštím
POKUS: if (podmínka) { příkaz(); if (jiná_podmínka) jiný_příkaz(); if( všechno špatně ) //Výskok z bloku označeného POKUS break POKUS; } dokonči_vnitřní(); } dokonči_vnější(); tady_se_pokračuje_po_break(); Návěští Příkaz skoku Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

65 Příklad použití příkazu break s návěštím
public void run() { double konečné_y = SP.getBVýška() - balon.getVýška(); double rychlost = 0; int x = balon.getX(); //Nemění se, takže nepotřebujeme double double y = balon.getY(); VNĚJŠÍ: do{ while( y < konečné_y ) { rychlost += SNÍMKOVÉ_ZRYCHLENÍ; y += rychlost / FREKVENCE; balon.setPozice( x, (int)y ); IO.čekej( PERIODA ); if( Thread.interrupted() ) { break VNĚJŠÍ; //Výskok z několika bloků -----> } y = konečné_y - 1; //Aby opět vstoupil do cyklu while rychlost = -rychlost * ÚTLUM; }while( -rychlost > MINIMÁLNÍ_RYCHLOST ); Návěští Máme činnost přerušit Příkaz skoku Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

66 Cyklus for – procházení kolekce
Zavedla Java 5.0 Cyklus_for-each: for( Typ Proměnná : Kontejner ) Příkaz Kde Typ je typ parametru cyklu a současné typ získávaných prvků Proměnná je název parametru cyklu, do nějž se ukládají odkazy na prvky Kontejner je iterovatelný objekt (= objekt implementující rozhraní Iterable), jenž je zdrojem prvků, s nimiž se v těle cyklu pracuje Při iteraci je v hlavičce vždy předán do proměnné odkaz, s nímž tělo cyklu pracuje; po vyčerpání všech prvků v kontejneru cyklus končí Cyklus neumožňuje jakoukoliv modifikaci obsahu kontejneru Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

67 Příklad: vzájemné odrazy molekul
public void popojeď() { double xn = x + rx; //Plánovaná nová vodor. souřadnice double yn = y + ry; //Plánovaná nová svislá souřadnice boolean odraz = false; //Předpokládáme, že se neodrazí for( Molekula m : molekuly ) { if( (m != this) && //Sama od sebe se neodrazí (P.délka( xn, yn, m.x, m.y ) < PRŮMĚR) ) double p; //Molekuly si prohodí rychlosti p = rx; rx = m.rx; m.rx = p; p = ry; ry = m.ry; m.ry = p; odraz = true; } if( !odraz ) setPozice( (int)(x = xn), (int)(y = yn) ); Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

68 Spuštění celého programu Soubory JAR BlueJ a vytváření souborů JAR
Spustitelné aplikace Spuštění celého programu Soubory JAR BlueJ a vytváření souborů JAR 61–66 183–185 473–477 Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

69 Metoda main(String[])
Nespouštíme-li program pod vývojovým prostředím, musíme virtuálnímu stroji prozradit, kde má s vykonáváním programu začít Oznámíme mu startovní třídu programu; ta musí obsahovat metodu (na jméně parametru nezáleží, jen na jeho typu): public static void main( String[] args ) nebo public static void main( String... args ) Tuto metodu virtuální stroj spustí BlueJ nabízí vytvoření třídy s předdefinovanou metodou main Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

70 BlueJ a metoda main BlueJ umí spustit i aplikaci neobsahující hlavní třídu s metodou main(String[]) Hlavní třídu s touto metodou potřebujeme pouze chceme-li danou aplikaci spouštět přímo jako jiné aplikace v daném operačním systému Po žádosti o vytvoření hlavní třídy se vytvoří třída obsahující pouze metodu main(String[]) Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

71 Šablona hlavní třídy aplikace
/************************************************************** * Třída Hlavní slouží ke spouštění aplikace ... * jméno autora */ public class Hlavní { /********************************************************** * Metoda, prostřednictvím níž se spouští celá aplikace. args Parametry načtené z příkazového řádku public static void main( String [] args ) /*# Sem vložte kód, kterým se bude aplikace spouštět.*/ } Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

72 Aplikace v archivech JAR
Kompletní aplikace se v Javě balí do souborů s příponou JAR (JAR = Java ARchive) Soubor JAR je klasický ZIP soubor doplněný o složku META-INF s textovým souborem MANIFEST.MF s informacemi o aplikaci V programu Total Commander lze do souboru JAR vstoupit klávesovou zkratkou PgDown Povinné řádky v souboru MANIFEST.MF: Manifest-Version: 1.0 – verze manifestu je stále 1.0 Created-By: 1.6.0_24 (Sun Microsystems Inc.) – Informace o verzi a dodavateli použité verze Javy Main-Class: Xyz – kde Xyz je úplný název hlavní třídy aplikace (nejedná-li se o spustitelnou aplikaci, ale jenom o knihovnu, řádek s uvedením hlavní třídy být uveden nemusí) Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

73 BlueJ a vytváření aplikací
BlueJ umí na požádání zabalit aplikaci do souboru JAR Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

74 Spouštění aplikací v souborech JAR
Většina operačních systémů umožňuje tyto aplikace spouštět obdobně jako klasické aplikace Druhou možností je spouštění z příkazového řádku Konzolový řežim: java –jar soubor parametry Spustí se aplikace spolu s konzolovým oknem, do nějž se vypisují texty pro standardní a chybový výstup Okenní režim: javaw –jar soubor parametry Otevře se pouze okno aplikace bez konzoly, standardní i chybový výstup jdou standardně „do kanálu“ Předpokládá se, že program vše vypisuje do oken Ve Windows se při standardní instalaci Javy automaticky sdruží soubory JAR s okenním voláním Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce

75 Děkuji za pozornost Rudolf Pecinovský mail: ICQ: Copyright © 2009, Rudolf Pecinovský VŠE – 04. Algoritmické konstrukce


Stáhnout ppt "Algoritmické konstrukce"

Podobné prezentace


Reklamy Google