From 7532c1b601034aadaa84a15e3e901c267cad9975 Mon Sep 17 00:00:00 2001 From: BigTire Date: Mon, 19 Dec 2022 01:20:14 +0100 Subject: [PATCH] =?UTF-8?q?P=C5=99id=C3=BDny=20pozn=C3=A1mky=20za=20cel?= =?UTF-8?q?=C3=BD=20semestr.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KIV PPA1/Poznámky PPA1.md | 725 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 725 insertions(+) diff --git a/KIV PPA1/Poznámky PPA1.md b/KIV PPA1/Poznámky PPA1.md index 9e842ec..f67bb42 100644 --- a/KIV PPA1/Poznámky PPA1.md +++ b/KIV PPA1/Poznámky PPA1.md @@ -2392,3 +2392,728 @@ daném kódování - Vrací ```true```, pokud je ve vstupním souboru další řetězec - Např. metoda ```hasNextLine()``` - Vrací ```true```, pokud je ve vstupním souboru další řádka + +#### Použití třídy ```PrintStream``` pro zápis do souboru +- Třída ```PrintStream``` poskytuje známé metody ```println()```, ```print()``` a ```format()``` pro zápis formátovaných dat do souboru +- V referenční proměnné ```System.out``` se skrývá instance třídy ```PrintStream``` +- Jeden z konstruktorů umožňuje vytvořit novou instanci třídy ```PrintStream``` ze zadaného názvu souboru + - Místo souboru můžeme použít i standardní výstup + - Stačí použít ```System.out``` (viz první zakontovaná řádka v metodě ```main()```) a odstranit konstrukci ```try – catch``` + +### Využití prostředků balíku ```java.nio.file``` +- Prostředky pro jednoduché čtení a zápis z/do souborů poskytuje třída ```Files``` z balíku ```java.nio.file``` + - Nahrazuje funkcionalitu z balíku ```java.io```, který je v Javě od začátku + - Mnoho tříd z balíku ```java.io``` však stále využívá + - Obsahuje snadno použitelné statické metody (podobně jako třída ```Math```) + +#### Rychlé čtení s využitím třídy BufferedReader +- funguje dobře, ale pokud by byl vstupní soubor větší, trvalo by jeho načítání nezanedbatelnou dobu + - Je třeba si uvědomit, že práce (tj. čtení a zápis) s vnější pamětí (tj. typicky s pevným diskem, kde jsou soubory uloženy) je řádově pomalejší než práce s vnitřní pamětí => rychlost čtení a zápisu je vhodné řešit ve většině případů, nejen při práci s extrémně velkými soubory +- Využití třídy ```BufferedReader``` + - Tzv. bufferovaný vstup + - V podstatě to znamená, že se z disku načte najednou větší část obsahu souboru do paměti a odtud se následně čtou data => podstatně rychlejší než číst data z disku po jednotlivých číslech nebo řádcích + - Instanci třídy ```BufferedReader``` lze snadno získat ze třídy ```Files``` na základě zadání souboru jako instance ```Path``` + - Metoda ```Files.newBufferedReader(soubor)``` + - Třída ```BufferedReader``` nabízí metodu ```readLine()```, která umožňuje načíst jednu řádku ze souboru + - Metoda vrací ```null```, pokud dosáhne konce souboru – využívá se, pokud nevíme, kolik řádek v souboru je (častý případ) + - Nenabízí však metody pro načtení jiných datových typů jako třída ```Scanner``` + Načtenou řádku je tedy nutné zpracovat (rozdělit podle nějakého znaku, převést na číslo apod.) ručně + - Čtení pomocí třídy ```BufferedReader``` je výrazně rychlejší než čtení pomocí třídy ```Scanner``` + +#### Rychlý zápis s využitím třídy BufferedWriter +- Podobně jako lze čtení ze souboru urychlit použitím třídy ```BufferedReader```, je možné zápis do souboru urychlit použitím třídy ```BufferedWriter``` + - Tzv. bufferovaný výstup + - V podstatě to znamená, že se data zapisují nejprve do paměti a následně se větší blok dat zapíše najednou na disk + - Ze třídy ```Files``` lze snadno získat instanci ```BufferedWriter``` pro rychlý zápis do souboru pouze na základě zadání souboru jako instance ```Path``` + - Třída ```BufferedWriter``` ale neobsahuje metody pro pohodlný zápis výstupu (```println()```, ```print()```, ```format()```) + - Proto je vhodné zkombinovat ji se třídou ```PrintWriter```, která zmíněné metody obsahuje + - Třída ```Files``` bohužel neobsahuje metodu, která by vrátila rovnou instanci třídy ```PrintWriter``` +- POZOR! + - Při použití třídy ```BufferedWriter``` je obzvláště důležité soubor po zapsání všech dat uzavřít + - ```BufferedWriter``` zapisuje data nejprve do paměti a následně zapíše celý blok dat do souboru + - Pokud soubor neuzavřeme, velmi často se stává, že poslední blok se do souboru nezapíše a soubor tak není kompletní + - Pokud je dat, které zapisujeme do souboru, málo, může se stát, že soubor bude úplně prázdný + - Okamžité zapsání do souboru lze vynutit metodou ```flush()``` +- Příklad použití tříd ```BufferedWriter``` a ```PrintWriter``` +- Rozdíl mezi ```PrintWriter``` a ```PrintStream``` + - V Javě je několik tříd pro práci se vstupy a výstupy končící na …(```Input/Output```)```Stream``` a několik tříd pro práci se vstupy výstupy končící na …```Reader/Writer``` + - Třídy ```…Reader/Writer``` pracují se znaky + - Znak v Javě zabírá dva byty, ale většina textových souborů takto uložena není + - Znaky se do souborů typicky ukládají jako jeden či více bytů podle použitého kódování + - Při čtení nebo zápisu provádějí třídy ```…Reader/Writer``` konverzi + - Třídy …(```Input/Output```) ```Stream``` pracují s byty + - Jsou určeny pro práci s byty, které však také mohou představovat znaky + - Metody určené pro formátovaný výstup (např. metody ```println()```, ```print()``` a ```format()``` třídy ```PrintStream```) rovněž provádějí konverzi, ostatní metody ne + - Umožňují i zápis a čtení jednoho či více bytů přímo (bez konverze) +- Proč je standardní výstup instance třídy ```PrintStream``` (určená pro práci s byty), i když standardní výstup evidentně pracuje se znaky + - Historické důvody, v Javě 1.0 třídy ```…Reader/Writer``` neexistovaly + - Zachováno kvůli zpětné kompatibilitě + - Jsou i situace, kdy je vhodné, aby standardní vstup a/nebo výstup pracoval s byty a ne se znaky + +#### Načtení všech řádek souboru +- Určeno pro malé soubory + - Rychlost načítání je řádově srovnatelná s třídou ```BufferedReader``` +- Metoda ```Files.readAllLines(soubor)``` + - Metoda zajistí otevření i uzavření souboru samostatně, je potřeba pouze odchytit případnou ```IOException``` + - Metoda vrací seznam řádek (```List``` – ne pole) souboru zadaného jako instance ```Path``` + - Jednotlivé řádky v seznamu jsou přístupné pomocí metody instance seznamu ```get(index)``` + - Indexy jsou stejné jako u pole – 0 až délka seznamu - 1 + - Délku seznamu vrátí metoda instance seznamu ```size()``` + - Seznam se dá procházet, stejně jako pole, cyklem ```for – each``` + +### Práce s binárními soubory +- Práce s binárními soubory je v Javě velice podobná práci s textovými soubory +- Používáme třídy končící na …(```Input/Output```) ```Stream``` + - Naprostá většina metod těchto tříd neprovádí konverzi na znaky (s výjimkou metod ```println()```, ```print()``` a ```format()``` třídy ```PrintStream```) + - Byty se načtou/zapíšou tak, jak jsou (na rozdíl od tříd končících na ```…Reader/Writer```) + +#### Zápis do binárního souboru +- Je možné zapisovat přímo jednotlivé byty + - Základní třída ```OutputStream``` + - Její instanci lze získat metodou ```Files.newOutputStream(soubor)``` +- Je možné zapisovat hodnoty základních datových typů + - Třída ```DataOutputStream``` + - Obsahuje metody ```writeTyp(hodnota)``` pro zápis všech základních datových typů + - Např. ```writeDouble(5.0)``` + - Do jednoho souboru je tak možné zapsat hodnoty různých datových typů + - Pořadí a počty jednotlivých hodnot je třeba řádně zdokumentovat, aby bylo možné takový binární soubor číst +- Pro urychlení je možné použít třídu ```BufferedOutputStream``` stejným způsobem jako ```BufferedWriter``` + - Třída ```Files``` však neposkytuje metodu, která by vracela instanci ```BufferedOutputStream``` + - Je potřeba vytvořit ```BufferedOutputStream``` ručně + +#### Čtení z binárního souboru +- Je možné číst přímo jednotlivé byty + - Základní třída ```InputStream``` + - Její instanci lze získat metodou ```Files.newInputStream(soubor)``` +- Je možné číst hodnoty základních datových typů + - Třída ```DataInputStream``` + - Obsahuje metody ```readTyp()``` pro čtení všech základních datových typů + - Např. ```readDouble()``` + - Odpovídají metodám ```writeTyp()``` třídy ```DataOutputStream``` +- Pro urychlení je možné použít třídu ```BufferedInputStream``` + - Třída ```Files``` však neposkytuje metodu, která by vracela instanci ```BufferedInputStream``` + - Je potřeba vytvořit ```BufferedInputStream``` ručně + +## Zobrazení dat v počítači +- Všechna data uložená v počítači jsou uložena jako posloupnost binárních číslic (bitů) uspořádaná po bytech (8 bitů) +- Způsob uložení dat se nazývá **kódování** + - Je dán datovým typem dat + - Určuje, jaký mají význam jednotlivé bity a byty +- Rozsahy hodnot jednotlivých datových typů a počet bytů, které zabírají v paměti, byly zmíněny v Kap. 3.2 +- Jakým způsobem jsou jednotlivé datové typy uloženy (jaké kódování je použito), je popsáno v následujících podkapitolách + +### Převod čísel mezi soustavami +- Nativní číselná soustava počítače, odpovídající uspořádání fyzické paměti, je dvojková (binární) + - Ruční zápis binárních čísel je však dlouhý, proto se pro zápis binárních čísel často používá šestnáctková (hexadecimální) soustava, která pro stejné číslo potřebuje 4x méně číslic + - Na jeden byte stačí 2 hexadecimální číslice, ale 8 binárních číslic +- V běžném životě se většinou počítá v desítkové (dekadické) soustavě +- Čísla lze mezi jednotlivými soustavami převádět pomocí kalkulačky či jiných programů (přepočet je dostupný např. v PSPadu) +- Algoritmy pro ruční převod čísel mezi dvojkovou, desítkovou a šestnáctkovou soustavou jsou v následujících podkapitolách + +#### Převod z desítkové do dvojkové soustavy (univerzální postup) +- Celou a desetinnou část řešíme zvlášť +- Celá část + - Celou část dělíme 2, píšeme si zbytky po dělení + - Poslední číslice výsledku (0 nebo 1) a zbytky přečtené odzadu dají celou část binárního čísla +- Desetinná část + - Desetinnou část násobíme 2, píšeme si číslici vlevo od desetinné čárky (v celé části) + - Číslice přečtené popředu dají desetinnou část binárního čísla +- Příklad převodu čísla 69,6875 na jeho reprezentaci v binární soustavě je na + +#### Převod z desítkové do dvojkové soustavy („intuitivní“) +- „Intuitivní“ postup pro celá čísla +- Napsat si vyčíslené mocniny 2, nalézt největší menší nebo stejnou mocninu 2, zapsat pod ní 1 a odečíst ji od převáděného čísla +- Opakovat, dokud z čísla nezbude 0 +- Příklad převodu 69 na jeho reprezentaci v binární soustavě + - Odečtu 64, protože 64 < 69, pod 64 zapíšu 1, zbude 5 + - Odečtu 4, protože 4 < 5, pod 4 zapíšu 1, zbude 1 + - Odečtu 1, protože 1 = 1, pod 1 zapíšu 1, zbude 0 + - Zbytek pozic doplním 0 + +#### Převod z dvojkové do desítkové soustavy +- Převod z dvojkové soustavy do desítkové (pro celá i reálná čísla) + - Každou číslici označit zprava doleva jako zvyšující se mocninu 2 + - Mocniny u číslic 1 vyčíslit a sečíst + +#### Převod z dvojkové do šestnáctkové soustavy +- Převod z dvojkové soustavy do šestnáctkové (pro celá i reálná čísla) + - Rozdělit číslo na čtveřice od desetinné čárky (na obě strany) + - Každá čtveřice je jedna číslice šestnáctkové soustavy (0 až F) + - Vyčíslit hodnotu čtyř binárních číslic jako při převodu do desítkové soustavy + +#### Převod z šestnáctkové do dvojkové soustavy +- Převod z šestnáctkové do dvojkové soustavy (pro celá i reálná čísla) + - Každou šestnáctkovou číslici převést do desítkové soustavy + - Použít pro každou číslici intuitivní postup pro převod z desítkové do dvojkové soustavy + +### Kódy pro uložení celočíselných datových typů +- Pro uložení celočíselných datových typů existuje několik kódů + - Bezznaménkové + - Znaménkové + - Přímý kód + - Inverzní kód + - Doplňkový kód + - Kód s posunutou nulou + +#### Uložení celých čísel bez znaménka +- Zápis ve dvojkové soustavě zarovnaný na násobky bytů +- Pouze pro nezáporná čísla +- Např. 131 je ```1000 0011```, 3 je ```0000 0011``` + +#### Přímý kód +- Kladná čísla stejná jako u bezznaménkového kódování +- Znaménko určeno v MSB (Most Significant Bit – ten nejvíce vlevo) +- Např. -3 je 1000 0011 +- Nevýhody + - Dvojí nula ```– 1000 0000``` (záporná) a ```0000 0000``` (kladná) +- Používá se pro zobrazení mantisy u reálných čísel + +#### Inverzní kód +- Kladná čísla stejná jako u bezznaménkového kódování +- Pro záporná čísla se mění všechny ```0``` na ```1``` a ```1``` na ```0``` +- Např. -3 je ```1111 1100``` +- Nevýhody + - Dvojí nula ```1111 1111``` (záporná) a ```0000 0000``` (kladná) +- Používá se v bitových operacích, případně jako mezikrok v doplňkovém kódu + +#### Doplňkový kód (dvojkový doplněk) +- Matematická definice + - D(x) = x pro x ≥ 0 + - D(x) = x + K pro x < 0, kde K = $2^{n}$ (kapacita soustavy) +- Kladná čísla stejná jako u bezznaménkového kódování +- Záporná čísla jsou uložena jako „inverzní kód + 1“ +- Např. -3 je ```1111 1101``` +- Používá se výhradně pro uložení celých znaménkových čísel + - Např. typy ```byte, short, int, long``` v Javě +- Výhody + - Pouze jedna nula – ```0000 0000``` + - Odečítání je přičítání záporného čísla +- Pozor na nesymetrický rozsah -128 až 127 (pro 1 byte) + - Absolutní hodnota nejmenšího záporného čísla je mimo rozsah +- Přetečení + - Nastává, když nám aritmetickými operacemi vyjde hodnota, která se nevejde do daného rozsahu + - Např. 127 + 1 (pro 1 byte) = -128 + - MSB se přičtením 1 k maximálnímu číslu nastaví na 1, což indikuje záporné číslo, proto vyjde -128 + - Možné reakce na přetečení + - Přerušení výpočtu jako reakce na chybu + - Pokračování výpočtu s nesprávným výsledkem – používá Java + - Zda přetečení nastane, závisí na vstupních číslech – někdy může program fungovat správně a někdy ne => špatně se hledá + +#### Kód s posunutou nulou +- Lineární posun nuly po celočíselné ose + - ```0000 0000``` je nejmenší (záporné) číslo + - Nula je ve středu rozsahu, tedy $2^{n-1}$ – 1, např. ```0111 1111``` + - ```1111 1111``` je největší kladné číslo +- Podobně jako u doplňkového kódu je rozsah nesymetrický +- Nevýhoda + - Kladná čísla jsou odlišná od bezznaménkového kódování + - Např. 3 je ```1000 0010``` +- Používá se pro uložení exponentu u reálných čísel + +### Kódy pro uložení reálných datových typů +- Aproximace reálných čísel +- Též nazýváno „zobrazení v pohyblivé řádové čárce“ (floating point) +- Dle normy IEEE 754 na 4 nebo 8 bytech (v Javě ```float``` – 4 byty a ```double``` – 8 bytů) + - Kromě samotného kódování norma IEEE 754 definuje i standardní chování základních aritmetických operací (sčítání, odčítání, násobení, dělení, …) + +#### IEEE 754 na 4 bytech +- Formát v pohyblivé řádové čárce s jednoduchou přesností (single-precision floatingpoint format) +- Používá 4 byty (32 bitů) + - Rozsah v absolutní hodnotě cca 10-45 až 10+38 + - Přesnost na cca 6 až 7 (dekadických) desetinných míst + - Rozdělení na znaménko, exponent a mantisu +- Znaménkový bit patří mantise (nikoliv exponentu) + - 0 odpovídá + + - 1 odpovídá - +- Mantisa (23 bitů) + - Uložena v přímém kódu (znaménkový bit je oddělen exponentem) + - Je normovaná + - 1 ≤ mantisa < základ (tj. 2) + - Její první bit v normovaném tvaru musí tedy být vždy 1 (1 před desetinou čárkou) a proto se neukládá + - Určuje přesnost čísla +- Exponent (8 bitů) + - Uložen v kódu s posunutou nulou, kde 0 je ```0111 1111``` + - Určuje rozsah čísla +- Hodnota 0 je uložena jako samé nuly +- Hodnota čísla se dá vypočítat +- Určení, jak bude vypadat zápis v IEEE 754 na 4 bytech pro číslo -258,125 +- Přesnost uložených čísel je omezená +- Některá čísla jsou zaokrouhlená +- Pokud je hodnota čísla menší než minimum, číslo nelze zobrazit, zaokrouhluje se automaticky na 0 => podtečení +- Pokud je hodnota čísla v absolutní hodnotě větší než maximum, číslo nelze zobrazit, zaokrouhluje se automaticky na (kladné nebo záporné) nekonečno => přetečení +- NaN (Not a Number) + - Definovaná hodnota při chybné operaci s reálným číslem (např. dělení nuly nulou) +- Operace s reálnými čísly + - Sčítání + - Porovnáním exponentů se zjistí menší číslo, tomu se zvětší exponent na úroveň většího čísla => zmenšuje se přesnost (mantisa) + - Pro exponentem hodně odlišná čísla se může v důsledku místo menšího čísla přičítat nula + - Násobení + - Exponenty se sečtou + - Mantisy se vynásobí +- Obecně platí + - Nepoužívat reálná čísla tam, kde stačí celá + - Výpočty nemusí být přesné (zaokrouhlovací chyby) + - Výpočty s celými čísly mohou být rychlejší + - Nepoužívat pro reálná čísla porovnání na rovnost (operátor „```==```“) + +#### IEEE 754 na 8 bytech +- Formát v pohyblivé řádové čárce s dvojitou přesností (double-precision floating-point format) +- Používá 8 bytů (64 bitů) + - Přesnost na cca 15 (dekadických) desetinných míst +- Způsob uložení je úplně stejný jako u 4 bytů, jen se liší velikost exponentu a mantisy + - Znaménko 1 bit + - Mantisa 52 bitů + - Exponent 11 bitů + +### Kódy pro uložení znaků a řetězců +#### Uložení znaků +- Přiřazují každému znaku zvolené abecedy nezáporné celé číslo +- Existuje mnoho kódů + +#### Uložení řetězců +- Řetězec je složen z jednotlivých znaků (v daném kódování) +- Řetězec má délku udávanou v počtu znaků +- Způsob uložení v paměti závisí především na použitém programovacím jazyce + - Java + - String + - Řetězec je neměnná (immutable) instance třídy + - Znaky řetězce jsou v instanci uloženy jako pole znaků (char[]) + - Řetězec tak může mít libovolnou délku + - ```StringBuilder/StringBuffer``` + - Měnitelný řetězec + - Kromě délky má i kapacitu (kolik znaků lze do řetězce uložit), která je rovněž proměnná + - Znaky řetězce jsou v instanci rovněž uloženy jako pole znaků (char[]) + - Řetězec tak může mít libovolnou délku + - C + - Řetězec je pole bytů začínající indexem 0 + - Za posledním platným znakem řetězce je přidán znak s hodnotou 0 (tj. '\0' – nikoliv znak '0') + - Řetězec tak může mít libovolnou délku + - V řetězci se nesmí vyskytnout znak '\0' + - Pascal + - Řetězec je pole bytů, znaky jsou uloženy od indexu 1 + - Na indexu 0 je uložena délka řetězce, která je tak omezena na maximálně 255 znaků + - Platí pro původní specifikaci jazyka Pascal + - Jeho novější mutace (např. FreePascal) obsahují i další typy řetězců + +### Uložení logického datového typu (```boolean```) +- Též booleovský datový typ +- Ukládají se jen dvě hodnoty + - ```true``` (pravda, logická 1) + - ```false``` (nepravda, logická 0) +- Prakticky se realizují pomocí celočíselného bezznaménkového typu +- Některé jazyky specifický logický typ nemají a používají místo něj celočíselný typ + - Např. C + +### Problém ukládání dat do fyzické paměti +- Týká se všech datových typů, jejichž hodnoty jsou uloženy na více než jednom bytu tj. většina) + - Demonstrujeme na uložení neznaménkového čísla na 4 bytech (01A2B3C4)H počínaje adresou 1000 +- Pokud má datový typ větší délku než jeden byte, pak jsou dvě možnosti, jak tyto byty uložit do fyzické paměti + - Big Endian (BE) – „vyšší řády na nižší adrese“ – „přirozené“ uložení + - Číslo bude uloženo jako ```01 A2 B3 C4``` + - Adresa 1000: ```01``` + - Adresa 1001: ```A2``` + - Adresa 1002: ```B3``` + - Adresa 1003: ```C4``` + - Little Endian (LE) – „vyšší řády na vyšší adrese“ – „obrácené“ uložení + - Číslo bude uloženo jako ```C4 B3 A2 01``` + - Adresa 1000: ```C4``` + - Adresa 1001: ```B3``` + - Adresa 1002: ```A2``` + - Adresa 1003: ```01``` +- Obecně se nedá říct, s kterým způsobem se setkáme více + - Je běžné, že se oba způsoby vyskytují na jednom počítači +- Může způsobit potíže při zápisu a následném čtení binárních souborů + - Je potřeba vědět, zda je soubor zapsán jako LE nebo BE +- Způsob záleží na + - Procesoru + - Např. Intel LE, Motorola BE + - Operačním systému + - Windows LE + - Programovacím jazyce + - Java BE + - Zaručuje přenositelnost binárních souborů + - Pokud však byly zapsány i přečteny programem napsaným v Javě + - V mnoha programovacích jazycích není určen a přebírá se způsob od operačního systému + +## Kodování znaků +- Určuje, jakým „číslem“ jsou jednotlivé znaky (a řetězce složené ze znaků) reprezentovány + +### Základní pojmy +- Terminologie není jednotná, liší se u velkých firem a organizací + - Stejné pojmy se používají pro různé věci + - Pro stejné věci existují různé pojmy +- V dalším textu bude využita terminologie z Unicode – Character Encoding Model + - Viz https://www.unicode.org/reports/tr17/ + +#### Organizace kódování znaků +- Pro kódování znaků lze použít několikaúrovňovou organizaci + - Znaková sada (množina kódovaných znaků – Coded Character Set – CCS) + - Mapování mezi množinou (abstraktních) znaků a množinou nezáporných celých čísel (kódové body – code points) + - Např. ```A = 41``` (abstraktní znak ```A``` má kódový bod ```41``` (hexadecimálně)) + - Příklady znakových sad jsou US-ASCII, ISO-8859-1, Unicode + - Forma kódování znaků (Character Encoding Form – CEF) + - Mapování množiny nezáporných celých čísel (prvků CCS) na množinu kódových jednotek dané šířky (např. 32bitových hodnot ```int```) + - Např. ```A = 00 00 00 41``` (znak ```A``` namapovaný na 32bitový ```int```) + - Kódovací schéma (Character Encoding Scheme – CES) + - Alternativní název charset – budeme používat dále, odpovídá třídě v ```Javě java.nio.charset.Charset``` + - Způsob mapování kódových jednotek z CEF do posloupnosti bytů + - Např. ```A = 00 41``` (znak ```A``` pro znakovou sadu Unicode a kódovací schéma UTF-16BE) + - Pro jednu znakovou sadu může existovat více charsetů + - Např. pro znakovou sadu Unicode existují charsety UTF-8, UTF16 a UTF-32 + - Často ale pro jednu znakovou sadu existuje jen jeden charset + - Např. ISO-8859-2 + ěžně je jeden soubor napsán v jednom charsetu +- Teoreticky je ale možné, aby byl jeden soubor současně napsán + - Ve více znakových sadách (např. Unicode, ISO-8859-2) + - Za použití více charsetů (UTF-8, ISO-8859-2) + - Kombinací obou předchozích – nejhorší případ +- Různé soubory jsou běžně v různých charsetech + +#### Trocha historie +- Sedmibitový ASCII kód (US-ASCII) + - American Standard Code for Information Interchage + - Základem většiny kódování používaných v současnosti (alespoň v Evropě a Americe) + - Protože data se standardně ukládají po bytech, je osmý (nejdůležitější) bit (Most Significant Bit – MSB – ten nejvíc vlevo) vždy 0 + - Umožňuje uložit 128 znaků + - Stačí pouze pro čistě anglické texty + - Nestačí pro uložení dalších znaků jiných jazyků (např. diakritické znaky češtiny) používajících latinku a už vůbec ne pro uložení znaků jiných abeced +- 8bitové kódy založené na ASCII + - Použila se zbývající polovina rozsahu jednoho bytu (MSB roven 1), což dává dalších 128 znaků + - Protože jeden znak je jeden byte, není třeba používat speciální charset (kódovací schéma) + - Znaková sada má stejný název jako charset + - 128 znaků navíc ale nestačí pro požadavky všech jazyků (ani pro všechny jazyky používající latinku) najednou + - Vzniklo mnoho charsetů, každý reprezentující specifické požadavky jednoho či skupiny jazyků) + - I pro jeden jazyk vzniklo více (různých) charsetů + - Vznikají charsety dle normy ISO ISO-8859-1 až ISO-8859-15 (pro různé skupiny jazyků) + - Vznikají charsety v národních standardizačních organizacích + - Vznikají propietární charsety, které jsou platformově závislé (Cp1250 pro Windows, MacCentralEurope) +- 16bitový CEF + - Řeší problém s nedostatečným počtem znaků použitím 16 bitů (2 bytů) pro jeden znak => to dává až 65536 možných znaků + - Na vývoji pracují cca od roku 1990 paralelně dvě organizace + - Unicode Consortium + - Znaková sada Unicode + - ISO (International Organization for Standardization) + - Znaková sada ISO/EIC 10646, ve zkratce UCS (Universal Character Set) + - Pro běžné použití netřeba rozlišovat, jednotlivé znaky mají stejné kódové body +- 32bitový CEF + - Při zahrnutí ideografických písem (typicky asijská písma) však ani 65536 znaků není dostatečné množství + - Řeší se použitím 32 bitů (4 bytů) pro jeden znak => to dává teoreticky přes 4 × 10**9 možných znaků, kdy se však nevyužívá celý rozsah + +#### Problém pojmenování charsetů +- Je běžné, že jeden charset má několik jmen, které se od sebe částečně nebo zcela liší + - Způsobeno tím, že charsety nově pojmenovávají i různí výrobci (HW a/nebo SW), i když už jméno charsetu existuje + - Např. US-ASCII má 14 dalších evidovaných jmen + - ISO646-US, IBM367, ASCII, cp376, default, ascii7, ANSI_X3.4-1986, iso-ir-6, us, 646, iso_646.irv:1983, csASCII, ANSI_X3.4-1968, ISO_646.irv:1991 +- Pořádek zavádí IANA (Internet Assigned Numbers Authority) +- Rozlišuje se základní pojmenování (nejoficiálnější), tzv. kanonické jméno, a ostatní evidovaná jména, tzv. aliasy + - Např. US-ASCII je kanonické jméno a iso-ir-6 je jeho evidovaný alias +- Může se stát, že jméno charsetu není evidováno v IANA, ale charset je podporován některými aplikacemi + - Pak se používá stejný princip kanonického jména a aliasů, ale kanonické jméno musí začínat „x-“ nebo „X-“ + - Např. Java Core API podporuje charset x-MacCentralEurope s aliasem MacCentralEurope + +### Jednobytové kódy +- Ačkoliv se čím dál více užívá Unicode, stále se můžeme setkat s použitím jednobytových kódu + - Především historické soubory, které (dosud) nebyly převedeny do Unicode + +#### US-ASCII (ASCII) +- Většina (nejen) jednobytových kódů vychází ze US-ASCII +- Původně využito pouze 7 bitů + - ```00``` až ```1F``` (0 až 31) – řídící znaky (např. ``````, `````` atd.) + - ```20``` (32) – mezera + - ```21``` až ``2F`` (33 až 47) – interpunkce (např. „!“, „,“, „"“ atd.) + - ```30``` až ```39``` (48 až 57) – číslice „0“ až „9“ + - ```3A``` až ```40``` (58 až 64) – další znaky (např. „;“, „:“, „<“, „@“ atd.) + - ```41``` až ```5A``` (65 až 90) – velká písmena „A“ až „Z“ + - ```5B``` až ``60`` (91 až 96) – další znaky (např. „^“, „[“, atd.) + - ```61``` až ```7A``` (91 až 122) – malá písmena „a“ až „z“ + - ```7B``` až ```7F``` (123 až 127) – další znaky (např. „{“, „~“, „|“ atd.) +- I v anglicky mluvících zemích se začalo využívat dalších 128 znaků (MSB roven 1), ač nebyly potřeba pro běžné znaky anglické abecedy + - Využití mj. pro znaky s čárami umožňující vykreslení „grafických“ oken v textovém prostředí + +#### Různá jednobytová kódování češtiny +- Stejně jako pro mnoho jiných jazyků i pro češtinu vznikl jednobytový kód vycházející z ASCII + - Prvních 128 znaků stejných jako US-ASCII (MSB roven 0) + - Dalších 128 znaků použito pro diakritické a další znaky (MSB roven 1) +- Bohužel vzniklo hned několik kódů, které se vzájemně liší pozicí některých znaků s diakritikou + - Běžněji se vyskytujících je cca 11 + - Pokud předpokládáme, že soubor je uložen v jednom kódování a ve skutečnosti je uložen v jiném, některé znaky s diakritikou nebudou zobrazeny správně (tj. budou místo nich zobrazeny jiné znaky) + - Některá kódování se liší jen v několika málo znacích, proto je možné si nesrovnalostí na první pohled nevšimnout +- Jednobytová kódování pro češtinu (a slovenštinu a další středo a východoevropské jazyky), se kterými je možné se setkat + - ISO-8859-2 – Latin Alphabet No. 2 + - Aliasy – ibm912, l2, ibm-912, ISO_8859-2, latin2, csISOLatin2, iso8859_2, 912, 8859_2, ISO8859-2, iso-ir-101 + - Základní charset pro východoevropské země – mezinárodní standard dle ISO + - Dříve se používalo na Linuxu téměř výhradně (dnes na Linuxu většinou nahrazeno UTF-8) + - windows-1250 – Windows Eastern European + - Aliasy – cp1250, cp5346 + - Proprietární charset firmy Microsoft + - Podporován operačními systémy (Windows) a aplikacemi této firmy + - Od ISO-8859-2 se v češtině liší pouze ve znacích „š“, „Š“, „ž“, „Ž“, „ť“, „Ť“ + - IBM852 – MS-DOS Latin-2 (POZOR! – Liší se od ISO-8859-2 ale i od windows1250) + - Aliasy – 852, ibm-852, csPCp852, ibm852 + - Proprietární charset firmy IBM + - Používaný charset v českém MS-DOS + - Stále používaný implicitní charset v konzoli českých Windows + - Obzvláště bizardní situace, kdy konzole používá IBM852 a zbytek systému používá windows-1250 + - Důvod, proč mohou nastat problémy s diakritickými znaky při jejich vstupu/výstupu z/do konzole + - Java předpokládá na standardním vstupu/výstupu charset operačního systému (což je windows-1250), ale konzole používá IBM852 + - Od verze Java 1.8 zlepšení, ale stále nefunguje univerzálně + - x-MacCentralEurope – Macintosh Latin-2 + - Alias MacCentralEurope + - Proprietární charset firmy Apple + +### Unicode +- Řeší problému s nedostatkem znaků použitím více bitů (bytů) + - Původně (verze 1.0, 1991) 16 bitů (2 byty) až 65536 znaků + - Brzy se ukázalo (verze 2.0, 1996), že 16 bitů není dost a přešlo se na 32 bitů teoreticky přes 4 × 109 možných znaků, ale v současnosti se neplánuje využití více než 21 bitů + - Prvních 128 znaků mají stejné kódové body (code points) jako znaky v 7bitové US-ASCII +- Kódové body (code points) jednotlivých znaků se označují jako ```U+hexaČíslo``` + - ```hexaČíslo``` jsou typicky 4 hexadecimální číslice, může jich být až 6 (vzhledem k uvažovanému rozsahu maximálně 21 bitů – každé 2 číslice reprezentují 1 byte) + - Např. ```U+0041``` je znak „```A```“ – odpovídá zápisu ```\u0041``` v Javě + +#### Současné rozdělení rozsahu znaků Unicode +- Ze 32 bitů se využívá pouze 21 bitů + - Konkrétně hodnoty ```U+000000``` až ```U+10FFFF``` +- Tento rozsah je rozdělen na 17 skupin (sfér – planes), každá o velikosti 65536 znaků => celkem přes 10**6 znaků + - Původní sada znaků, která se vejde do 16 bitů (2 byty) se označuje jako BMP (Basic Multilingual Plane) + - Je první v pořadí, rozsah ```U+000000``` až ```U+00FFFF``` + - Zahrnuje všechny znaky používané v Evropě a Americe a základní ideografická písma čínštiny, japonštiny a korejštiny (HAN písmo) + - Samotné BMP je vnitřně děleno do bloků, které (na rozdíl od sfér) nemají konstantní velikost + - Např. ASCII (rozsah ```U+000000``` až ```U+00007F```) je tzv. Basic Latin Block + - Dalších 16 sfér v rozsahu ```U+010000``` až ```U+10FFFF``` jsou tzv. doplňkové sféry (supplementary planes), které se v oblasti střední Evropy téměř nikdy nepoužívají + - V současnosti (2022 – Unicode verze 15.0) má pět doplňkových sfér přiřazeny znaky a celkem šest sfér je pojmenováno + - V současnosti (2022 – Unicode verze 15.0) je namapováno (tj. kódovým bodům jsou přiřazeny znaky) 149697 znaků + - Unicode verze 1.0.1 měl 28327 znaků + +#### Kódovací schémata (charsety) Unicode +- Protože znak může být uložen na více bytech, je možné používat více charsetů (kódovacích) schémat +- Unicode má tři základní charsety UTF (Unicode Transformation Format), přičemž dva z nich mají další varianty celkem 7 charsetů + - UTF-8 + - UTF-16 + - Další varianty UTF-16BE a UTF-16LE přesně specifikující pořadí uložení bytů + - UTF-32 + - Další varianty UTF-32BE a UTF-32LE přesně specifikující pořadí uložení bytů + - Všechny charsety jsou schopny uložit celý rozsah Unicode (21 bitů) + - Jednotlivé charsety jsou popsány v Kap. 28.3.4 až 28.3.6 + +#### Problém pořadí bytů, značka bytového pořadí +- Pokud ukládáme do paměti či souboru vícebytové entity (v tomto případě znaky), je potřeba rozlišit pořadí bytů + - Např. pokud uvažujeme uložení znaku „```A```“ (```U+0041```) na dvou bytech, může být uložen jako + - Little Endian (LE – „obrácené uložení“) – ```41 00``` + - Big Endian (BE – „přirozené uložení“) – ```00 41``` + - Pokud uvažujeme uložení znaku „```A```“ na čtyřech bytech, může být uložen jako + - Little Endian – ```41 00 00 00``` + - Big Endian – ```00 00 00 41``` +- Způsob ukládání závisí na platformě (Windows LE), programovacím jazyku (Java vždy BE), aplikaci atd. +- Jaký způsob je použit, je důležité při čtení souboru pro správné načtení vícebytových znaků +- Charsety Unicode mohou pro identifikaci používat počáteční značku bytového pořadí + - Byte Order Mark (BOM) + - Zapisuje se na úplný začátek souboru + - Pro tento účel Unicode definuje dva kódové body + - ```U+FEFF``` – pevná mezera nulové délky (zero width no-break space) + - ```U+FFFE``` – není kód znaku (not a character code) + - Pro UTF-16 má BOM tvar ```FE FF``` pro BE a``` FF FE``` pro LE + - Pokud je značka načtena správně, pak by se pevná mezera nulové délky neměla ze své podstaty zobrazit + - Pokud je načtena nesprávně (zamění se BE za LE nebo naopak), opět by se neměla zobrazit, protože se jedná o neplatný znak + - BOM se může nebo nesmí vyskytovat, což je dáno definicí konkrétního charsetu + - U UTF-8 má BOM tvar ```EF BB BF``` + - Není vyžadována ani doporučována, nicméně není zakázána + - Může nastat problém se zdrojovými soubory ```.java```, které mohou být uloženy v UTF-8 + - Překladač javac nepředpokládá na začátku souboru BOM (i když není zakázáno, aby tam byla), některé editory ji tam však umístí program pak nelze přeložit + +### UTF-8 +- Bylo vytvořeno, aby se znaky Unicode daly zakódovat posloupností bytů, se kterými umí pracovat každá aplikace a každý souborový systém +- Obecně rozšířený a používaný charset + - Např. řetězce v .class souborech jsou uloženy v UTF-8 + - Ze zmíněných sedmi charsetů Unicode se UTF-8 používá v Evropě a v Americe pravděpodobně nejčastěji +- Pro texty využívající pouze znaky anglické abecedy je UTF-8 totožné s US-ASCII + - Využívá se jen jeden byte na jeden znak + - Soubory tak zabírají stejně místa, jako kdyby byly kódovány v US-ASCII +- Pro diakritické znaky se využívají dva byty, pro speciálnější znaky z BMP tři byty + - Protože diakritických znaků je např. v českém textu cca 10 %, velikost souboru s českým textem naroste oproti použití jednobytového kódování (např. windows-1250) pouze o cca 10 % +- Pro znaky mimo BMP se využívají čtyři byty +- Základní nevýhoda UTF-8 + - Znaky obecně nemají stejnou délku => není možné skočit přímo na určitý znak + - „Přeskoč prvních 20 znaků“ +- Princip kódování znaků v UTF-8 + - Aby bylo jasné, zda daný znak je uložen jako 1, 2, 3 nebo 4 byty, používá se MSB + - Principiálně je možné zakódovat pomocí UTF až 31 bitů + - ```1111 110u 10vv vvvv 10ww www 10xx xxxx 10yy yyyy 10zz zzzz``` +- Princip čtení UTF-8 + - Pokud má byte nastaveno MSB na ```1```, pak počet jedničkových bitů za ním udává počet následujících bytů za prvním bytem znaku, přičemž každý následující byte začíná ```10``` (viz Tab. 28.2) + - Pokud nečteme text od začátku a „trefíme“ se doprostřed vícebytového znaku, poznáme to podle bitů ```10``` => pak je třeba přeskočit všechny byty začínající ```10``` +- V UTF-8 je zbytečná BOM – je jen jedno možné pořadí bytů + - Podle specifikace není ani vyžadována ani doporučena, není však zakázána + - Některé aplikace však BOM u UTF-8 vyžadují a některé s ní naopak mají problémy + +#### UTF-16 +- Vychází z UCS-2, což je kódování ISO s pevnou šířkou 2 byty na znak, což pokryje celou BMP +- Protože však Unicode přešel na 21 bitů, 2 byty (16 bitů) nestačí (pro znaky mimo BMP) +- Proto nastupuje UTF-16, které některé znaky kóduje 4 byty (tj. dvěma znaky UCS-2) + - Oba „znaky“ se dohromady nazývají zástupné páry (surrogate pairs) + - Mezi UCS-2 a UTF-16 je podobný vztah jako mezi ASCII a UTF-8 +- UTF-16 se využívá pro uložení řetězců v operační paměti v Javě +- Při uložení UTF-16 do souborů se využívá BOM pro určení pořadí uložení bytů (LE nebo BE) + - Varianty UTF-16LE a UTF-16BE mají pořadí uložení bytů přímo určeno a BOM nesmí obsahovat + - Pokud BOM přesto obsahují, je ignorována +- Oproti UTF-8 zabírá pro běžné texty psané latinkou téměř dvojnásobek místa + - Pro texty psané pouze znaky anglické abecedy přesně dvojnásobek + +#### UTF-32 +- Kódování s pevnou šířkou 4 byty na znak + - Každý znak je uložen jako 4 byty + - Na 4 bytech jsou tak přímo uloženy kódové body Unicode + - Pouze 21 bitů je významových + - Prakticky odpovídá UCS-4 (kódování ISO, rovněž 4 byty na znak) +- Při uložení UTF-32 do souboru se rovněž využívá BOM pro určení pořadí uloženy bytů (LE nebo BE) + - Varianty UTF-32LE a UTF-32BE mají pořadí uložení bytů přímo určeno a BOM nesmí obsahovat + - Pokud ho přesto obsahují, je ignorován + +### Praktické použití v Javě +- Java vnitřně ukládá řetězce do paměti jako UTF-16, většina souborů je však uložena v UTF-8 nebo v různých jednobytových charsetech + - Při čtení a zápisu řetězců z/do souborů (i na standardní vstup a výstup) je tedy nutná konverze + +#### Nastavení charsetu při čtení a zápisu z/do textových souborů +- Konverzi provádějí třídy pro práci se soubory, jejichž název končí ```…Reader/Writer``` + - Jsou určeny pro práci se znaky +- Charset vstupního/výstupního souboru lze popsat instancí třídy ```Charset``` + - Metoda třídy ```Charset.forName(kódování)``` + - Vrátí instanci třídy ```Charset``` reprezentující daný charset na základě jeho jména + - Lze použít kanonické jméno i aliasy + - Metody z třídy ```Files``` pro čtení a zápis z/do souboru umožňují zadat charset souboru jako instanci třídy ```Charset``` + - Metoda ```Files.readAllLines(soubor, charset)``` + - Metoda ```Files.newBufferedReader(soubor, charset)``` + - Metoda ```Files.newBufferedWriter(soubor, charset)``` + +#### Správné zobrazení češtiny v konzoli Windows +- Od verze Javy 1.8 se čeština v konzoli Windows někdy zobrazuje správně, někdy však stále chybně + - Správně se zobrazují literály s diakritickými znaky zapsané přímo ve zdrojovém kódu + - Špatně se zobrazují řetězce načtené ze standardního vstupu a vypsané na standardní výstup + - Do verze Javy 1.7 včetně se zobrazovaly špatně i literály zapsané přímo ve zdrojovém kódu +- Problém je způsoben rozdílným standardním charsetem Windows (windows-1250) a konzole (implicitně IBM852 – lze změnit) + - Tyto charsety nejsou totožné (liší se v některých znacích) + - Java tak očekává na standardním vstupu a výstupu charset windows-1250, ale v konzoli je IBM852 +- Korektní zobrazení v Java programech v konzoli Windows lze zařídit nastavením odpovídajícího charsetu pro standardní vstup a standardní výstup + - Pro standardní vstup stačí nastavit charset v konstruktoru třídy Scanner + - Zadává se pouze název charsetu jako řetězec + - Standardní výstup funguje od Javy 1.8 korektně +- POZOR! + - Problémy se týkají pouze konzole (příkazové řádky) Windows + - Konzole IDE nástrojů (např. Eclipse) přebírají charset Windows (jsou to grafická okna) a čeština v nich funguje správně + +## Porovnání objektového a procedurálního programování +- Programovacích stylů je celá řada + - Mezi nejběžnější styly patří v současné době objektové a procedurální programování + +### Základní charakteristiky obou přístupů +- Oba přístupy se v některých aspektech podobají a v některých liší + +#### Objektové programování +- Java, kterou jsme se celý semestr zabývali, je primárně objektový jazyk +- V objektovém programování je řešený problém dekomponován na objekty představující objekty z reálného světa +- Zdrojový kód je tak členěn na třídy, které obsahují atributy (data) a metody (podprogramy – procedury a funkce), které se těmito atributy pracují + - Podle třídy lze vytvořit libovolné množství instancí (objektů), každá s vlastním nastavením hodnot atributů +- Díky použití objektů je program lépe členěn na víceméně samostatné jednotky (třídy) + - Lepší znuvupoužitelnost kódu + - Třída se poměrně snadno dá použít v jiném v jiném programu, protože je oddělená od dalších tříd +- Zapouzdřenost + jasně stanovená identita + - Díky přístupovým právům (viz Kap. 14.7.1) je zajištěn kontrolovaný přístup k datům (atributům) z vnějšku třídy + - Vše někomu patří – metody a atributy (proměnné) jsou vždy součástí tříd +- Kromě zapouzdřenosti existují dva další pilíře objektového programování + - Skládání (objekt obsahuje jiné objekty) a polymorfizmus + - Viz předměty KIV/PPA2 a KIV/OOP +- Objektové programování nabádá programátora k větší disciplíně + - Obsahuje více pravidel, která by se měla dodržovat + - Při jejich dodržení by měla vést k přehlednějšímu zdrojovému kódu +- Objektové programování nabádá k dekompozici problému (na objekty) + +#### Procedurální programování +- V procedurálním programování je problém dekomponován na jednotlivé činnosti +- Program tvoří jeden celek (ač může být často rozdělen do několika jednotek / zdrojových souborů – modulů) členěný na podprogramy (procedury a funkce) +- Procedury a funkce rovněž pracují s daty, ale nejsou s nimi přímo svázány v jednom celku jako v objektovém programování + - Procedury a funkce jsou umístěny „volně“, nejsou v žádné třídě + - Pro jednoduché problémy mohou být programy kratší, protože není potřeba vytvářet třídy +- Procedurální programování dává programátorovi větší volnost + - Pravidel je méně než v objektovém programování + - Pro složitější programy může být zdrojový kód méně přehledný (ale nemusí – záleží na programátorovi) +- Kombinace více přístupů + - Mnohé jazyky umožňují programovat jak procedurálně, tak objektově (a případně mohou obsahovat další přístupy) + - Programátor pak může kombinovat oba přístupy nebo používat jen jeden z nich podle svého uvážení + - Např. C++, PHP, Pascal (FreePascal, Delphi) + +### Jednotlivé rozdíly +- V následujících kapitolách budou ukázány hlavní rozdíly mezi objektovým a procedurálním programování + - Aby nebylo nutné učit se syntaxi nějakého procedurálního jazyka (např. C), budou příklady na procedurální programování ukázány v Javě +- Procedurální programování v Javě + - Java je primárně objektový jazyk a byla tak koncipována od svého vzniku + - Přesto je v ní možné „simulovat“ procedurální programování + - Celý program napsat do jedné třídy + - Další třídy používat pouze jako strukturovaný datový typ + - Používat pouze statické metody + - POZOR! + - Tento postup je použit pouze pro porovnání principů objektového procedurální programování + - Neznamená to, že by se tak v Javě mělo programovat + +#### Metody, procedury a funkce +- V procedurálním i objektovém programování jsou části výkonného kódu rozděleny do podprogramů, které je možné (opakovaně) volat v jiných částech kódu + - V objektovém programování se nazývají metody + - Lze je rozdělit na procedury (nemají návratovou hodnotu) a funkce (mají návratovou hodnotu) + - V procedurálním programování se nazývají rovnou procedury (nemají návratovou hodnotu) a funkce (mají návratovou hodnotu) + - Toto je pouze rozdíl v terminologii +- Metody v objektovém programování + - Jsou součástí konkrétní třídy + - Metody instance + - Při dobrém návrhu většina metod + - Volají se nad konkrétní instancí + - Mají přístup k atributům instance => díky tomu mají obvykle menší počet formálních parametrů (poměrně často nemají žádné parametry) + - Metody třídy + - Je možné je volat bez vytvoření instance + - Nemají přístup k atributům instance + - Data, se kterými mají pracovat, musí být do metody předány přes její formální parametry + - Nebo mohou pracovat s proměnnými třídy + - Nebo mohou pracovat s tzv. „globálními“ proměnnými + - Jsou velmi podobné procedurám a funkcím v procedurálním programování +- Procedury a funkce v procedurálním programování + - Volají se přímo jen svým jménem a skutečnými parametry + - Data, se kterými mají pracovat, musí být do procedury/funkce předány přes její parametry + - Nebo mohou pracovat s „globálními“ proměnnými +- Předávání parametrů do metody (procedury či funkce) + - Předání parametrů odkazem + - Ve formálním parametru se předá proměnná a s její hodnotou se v metodě (proceduře či funkci) pracuje + - Změna hodnoty provedená v metodě se projeví i vně metody + - Předání parametrů hodnotou + - Ve formálním parametru se předá kopie hodnoty proměnné a s touto hodnotou se v metodě (proceduře či funkci) pracuje + - Změna hodnoty provedená v metodě se neprojeví vně metody, protože se mění kopie + - Tento postup používá Java (a mnoho dalších jazyků) + - Způsob, který se použije, nezáleží na tom, zda se jedná o procedurální nebo objektové programování + - Způsob závisí na konkrétním jazyce + - Některé jazyky umožňují jeden nebo druhý způsob, přičemž druhého (neumožněného) způsobu je obvykle možno nějak dosáhnout + - Některé jazyky explicitně umožňují oba způsoby (např. C#, Pascal) + - Těla metod (procedur či funkcí) + - Těla metod, procedur a funkcí se v obou přístupech (objektový a procedurální) nijak neliší + - V obou případech obsahují výkonný kód metody (tj. příkazy, které provedou činnost metody/procedury/funkce) + +#### Globální proměnné +- V procedurálním programování je potřeba předat všechna potřebná data do procedur a funkcí pomocí parametrů + - Na rozdíl od objektových jazyků, kde metody instance mají přístup k atributům instance +- Často však také existuje možnost mít tzv. „globální proměnnou“, která je viditelná ve všech procedurách a funkcích programu + - Tato možnost často existuje v procedurálních i objektových jazycích explicitně (např. PHP), nebo se dá různými způsoby dosáhnout + - Např. v Javě jsou veřejné (statické) proměnné třídy viditelné odevšad + - Mimo třídu, kde jsou definovány, je potřeba volat je s názvem třídy + - Obecně platí, že metody, procedury a funkce mohou s takovou proměnnou pracovat, pokud není zastíněná lokální proměnnou se stejným jménem + +#### Homogenní strukturované datové typy (pole) +- S poli se pracuje v podstatě stejně, bez ohledu na to, zda používáme procedurální či objektové programování +- Konkrétní implementace pole závisí spíše na programovacím jazyku než na přístupu k programování + - Např. v Javě je pole instance speciální třídy, která kromě samotných prvků obsahuje i délku pole a další data + - Např. v C je pole jen posloupnost prvků stejného typu, které jsou umístěny za sebou v paměti počínaje určitou adresou délka pole není v poli uložena +- POZOR! + - Pokud v daném jazyce není součástí pole i jeho délka, je potřeba mít délku uloženou zvlášť (typicky v celočíselné proměnné) + - Nutné, abychom věděli, jak je pole dlouhé a nedostali jsme se při práci s polem mimo platné indexy + +#### Heterogenní strukturované datové typy +- Pokud je v objektovém jazyce potřeba uložit data různých datových typů do jednoho celku, použije se typicky objekt (instance třídy) +- V procedurálním jazyce objekty nejsou, ale možnost ukládat heterogenní data do společných celků typicky existuje + - Typicky se používají strukturované datové typy, které mají položky různých datových typů (podobně jako atributy instance), ale neobsahují žádné metody + - Lze si je představit jako třídy s veřejnými proměnnými instance bez metod + - Běžný obecný název je záznam (record) nebo struktura (struct) + - Konkrétní názvy a způsob deklarace se liší jazyk od jazyka \ No newline at end of file