WICHTERLOVO GYMNÁZIUM, OSTRAVA-PORUBA. Programování MATURITNÍ OTÁZKY



Podobné dokumenty
Maturitní otázky z předmětu PROGRAMOVÁNÍ

Programovací jazyk Pascal

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

NPRG030 Programování I, 2016/17 1 / :58:13

NPRG030 Programování I, 2010/11

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Úvod do programování

ALGORITMIZACE A PROGRAMOVÁNÍ

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Programování 2 (NMIN102) Soubory. RNDr. Michal Žemlička, Ph.D.

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

Sada 1 - Základy programování

Paměť počítače. alg2 1

Algoritmizace řazení Bubble Sort

Algoritmizace prostorových úloh

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Programovací jazyk. - norma PASCAL (1974) - implementace Turbo Pascal, Borland Pascal FreePascal Object Pascal (Delphi)

Algoritmizace prostorových úloh

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Algoritmizace. 1. Úvod. Algoritmus

Datové typy a struktury

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Příklady: (y + (sin(2*x) + 1)*2)/ /2 * 5 = 8.5 (1+3)/2 * 5 = /(2 * 5) = 1.3. Pavel Töpfer, 2017 Programování 1-3 1

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Sada 1 - Základy programování

Algoritmizace a programování

Struktura programu v době běhu

VISUAL BASIC. Práce se soubory

3 Co je algoritmus? Trocha historie Definice algoritmu Vlastnosti algoritmu... 3

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

O datových typech a jejich kontrole

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Aplikovaná informatika. Podklady předmětu Aplikovaná informatika pro akademický rok 2006/2007 Radim Farana. Obsah. Obsah předmětu

Úvod do programování. Lekce 1

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty

dovolují dělení velkých úloh na menší = dekompozice

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

Algoritmizace a programování

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

6 Příkazy řízení toku

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

6. Příkazy a řídící struktury v Javě

NPRG030 Programování I, 2015/16 1 / :25:32

Identifikátory označují objekty v programu používané (proměnné, typy, podprogramy).

Programování v C++, 2. cvičení

Program a životní cyklus programu

Sada 1 - Základy programování

Pole a kolekce. v C#, Javě a C++

Algoritmizace prostorových úloh

Výukový materiál zpracován v rámci projektu EU peníze školám

5 Přehled operátorů, příkazy, přetypování

Algoritmizace prostorových úloh

Sada 1 - Základy programování

VY_32_INOVACE_08_2_04_PR

přirozený algoritmus seřadí prvky 1,3,2,8,9,7 a prvky 4,5,6 nechává Metody řazení se dělí:

Pseudonáhodná čísla = algoritmicky generovaná náhrada za náhodná čísla

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

Lekce 01 Úvod do algoritmizace

Základy programovacího jazyka Turbo Pascal

Ing. Igor Kopetschke TUL, NTI

1. D Y N A M I C K É DAT O V É STRUKTUR Y

NPRG030 Programování I, 2017/18 1 / :22:16

Tabulkový procesor. Základní rysy

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Typové a netypové soubory

Časová a prostorová složitost algoritmů

NPRG030 Programování I, 2018/19 1 / :03:07

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Třídění dat. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_26 04

Zápis programu v jazyce C#

PODPROGRAMY PROCEDURY A FUNKCE

Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky -

2 Strukturované datové typy Pole Záznam Množina... 4

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Řídicí struktury. alg3 1

Iterační výpočty. Dokumentace k projektu č. 2 do IZP. 24. listopadu 2004

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

Práce se soubory. Základy programování 2 Tomáš Kühr

Úvod do programování 6. hodina

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

Binární soubory (datové, typované)

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Algoritmizace prostorových úloh

ADT/ADS = abstraktní datové typy / struktury

Transkript:

WICHTERLOVO GYMNÁZIUM, OSTRAVA-PORUBA Programování MATURITNÍ OTÁZKY Ostrava 2008 Tomáš Vejpustek

1 Algoritmus a jeho vlastnosti algoritmus a jeho vlastnosti, formy zápisu algoritmu ověřování správnosti algoritmu, krokovací tabulka program jako forma zápisu algoritmu základní algoritmické konstrukce sekvence, podmínka, cyklus Co programovací jazyky, přijdou tam taky? Algoritmus je přesný návod či postup, kterým lze vyřešit daný typ úlohy. Může se objevovat v jakémkoli vědním odvětví (např. matematika). Heuristika je postup, který nedává přesné řešení problému, ale v krátkém čase. Přesnému řešení se jen blíží, ale obecně přesnost řešení nelze dokázat. Často se používá, z důvodu, že algoritmus neexistuje nebo je příliš složitý a tudíž časově náročný. Slovo algoritmus zlatinštěná, špatně použitá a zkomolená podoba jména významného arabského matematika Al-Chórezmího (nebo Chwazírmího angl. Al-Kchwarizmi) otce algebry, podle jeho díla, které představuje indickou číselnou soustavu a počítání v ní od toho pak latinsky provádění aritmetiky pomocí arabských číslic. Později býval používán jako označení různých matematických postupů. 1.1 Algoritmy a stroje Algoritmus přináší dvě výhody: 1. Zobecnění problému tedy abstrakce neřeší jeden problém, ale obecněji typ problému, viz níže Hromadnost. 2. Zjednodušení problému přesný postup může vykonat i stroj. Stroje používají algoritmy z obou výše uvedených důvodů. Každý problém se dá zjednodušit na dílčí kroky, které může provést i stroj a zároveň umožňují řešit více problémů podle jednoho vzoru. Je možné zmínit něco o Turingově stroji (nekonečná páska papíru, hlava pozor, to s tím úředníkem je zjednodušení). 1.2 Vlastnosti algoritmu Resultativnost Algoritmus má alespoň jeden výstup odpověď na problém, který řeší. Vede od zpracování hodnot k výstupu. Zároveň je ukončený musí skončit v konečném počtu kroků (není jasné, jestli to není nová vlastnost). Determinovanost V každém kroku je známý následující nestane se to, že najednou není jasné, co dělat. 1

Hromadnost Abstrakce řeší typ problému, ne jen jeden konkrétní problém (např. součin dvou celých čísel, ne kolik je 5 7) Každá operace by měla být elementární. 1.3 Návrh Proměnná je způsob reprezentace objektu, jehož hodnota se může měnit. vstupní proměnné tj. to, co algoritmus bude přijímat, bez kterých jej nelze realizovat. vstupní podmínky určují přípustné hodnoty pro vstup. výstupní proměnné tedy výsledek, řešení problému. výstupní podmínky požadovaný vztah mezi vstupními a výstupnímy proměnnými. 1.4 Zápis 1. Slovní 2. Grafický např. vývojové diagramy 3. Matematický vztahem mezi veličinami, soustavou rovnoc... 4. Počítačový program program je zaznamenaný postup počítačových operací, který popisuje praktickou realizaci algoritmu. Někde mezi slovním a programovým zápisem je kvasilogický zápis používá prvky vyšších programovacích jazyků. 1.5 Ověřování správnosti Algoritmus je správný, když pro všechny vstupní proměnné splňující vstupní podmínky generuje výstupní proměnné splňující výstupní podmínky. Jedinným pravým ověřením jsou matematické důkazové metody, ostatní prostředky slouží jako heuristika. Využívá se sledování programu krok po kroku (tzv. krokování) například za pomoci testovací tabulky, která sleduje hodnoty všech vnitřních proměnných krok po krok. Běžnou praxí u komerčních programů jsou zkoužky v provozu (tzv. beta verze programů). 2

1.6 Základní konstrukce Sekvence (tady si nejsem tak jistý) po sobě jdoucí příkazy (jako vstup, výstup, přiřazení apod.) Přiřazení, vstup, výstup. Podmínka Větvení algoritmu na základě pravdivosti výrazu (týkající se např. hodnot proměnných apod.) Cyklus Sekvence je opakována vícekrát. 1. S danným počtem opakování 2. S podmínkou na začátku/konci pokračuje ve vykonávání sekvence na základě pravdivosti výrazu. 3

2 Strukturované programování. Programovací jazyk Pascal. pravidla pro strukturované programování struktura programu v jazyce Pascal prostředky pro dodržení zásad strukturovaného programování v jazyce Pascal lokální a globální proměnné ladění programu, direktivy překladu Co více k ladění? Strukturované programování označuje programovací techniku, kdy se implementovaný algoritmus rozděluje na dílčí úlohy. K implementaci v programu se používá vybraných řídících struktur. Ruší příkaz skoku (např. GOTO). Strukturované programování pracuje nejčastěji s tak zvaným top-down designem, kdy se nejprve navrhne jak má program v zásadě pracovat a problém se pak rozděluje do menších částí. Tento postup by správně měl končit až u elementálních částí. Pascal patří mezi imperativní (tj. příkazové pomocí příkazů popisuje algoritmus) procedurální programovací jazyky. Byl vyvinut především jako programovací jazyk na výuku strukturovaného programování (Niklaus Wirth, Curych). Základem je blok, konstrukce obsahující deklarace a příkazy. Tvoří rozsah platnosti deklarovaných objektů. Bloky se můžou vnořovat, s čímž se nejčastěji setkáváme u procedur a funkcí základních stavebních jednotek strukturovaného programování (také podprogramy). Hlavička Definuje název bloku a jeho vztah k programu. Co k ní? Deklarační část Definuje významy identifikátorů použitých v bloku. Příkazová část Vlastní výpočetní část. Sekvence příkazů oddělená středníkem. Uzavřena mezi klíčová slova begin a end. 2.1 Povolené názvy Názvy idintefikátorů, tj. název programu, typu, proměnné či konstanty, procedury a funkce. Každý název je unikátní žádné dva různé objekty nemůžou mít stejný název. Pascal není case sensitive. Délka menší než 63 znaků. Bez speciálních znaků a mezery (ale číslice a podtržítko ano) 4

Nesmí začínat číslicí Nesmí se shodovat se žádným klíčovým slovem programu. Doporučuje se také nepoužívat českou diakritiku. 2.2 Struktura programu program [název programu]; uses [knihovna1], [knihovna2],... ; const [konstanta1] = hodnota;... type [typ] = definice typu;... var [globální proměnná] : typ;... podprogramy procedury a funkce begin algoritmická konstrukce end. Identifikátory, klíčová slova a čísla od sebe musí být odděleny prázdným znakem (mezera, konec řádku, apod.). Pro lepší přehlednost zdrojového kódu je dobré vnořené bloky odsazovat (např. tabulátorem). 2.3 Platnost proměnných Tedy místo v programovém kódu, z kterého lze k objektu přistupovat doba přidělení paměti. Globální platí v celém programu ve všech podprogramech. Jsou definovány v deklarační části hlavního programu. Také obecné proměnná bloku ve vyšší úrovni. Lokální platí pouze v daném bloku a blocích v něm vnořených. Definována v deklarační části daného bloku. Dynamické Platnost definována programátorem. Viz níže Je zde výjimka pro stejné názvy identifikátorů. Pokud je název globální a lokální proměnné stejný, lokální proměnná tu globální překrývá. 5

2.4 Direktivy překladu Programovací jazyk slouží k zápisu programu a je speciálním programem překladačem (kompilátorem) převeden do strojového kódu počítače čímž je vytvořen spustitelný program. Direktivy překladu informují překladač, jak má ke zdrojovému kódu přistupovat, například co se týče vyhodnocování chyb. Nejčastější jsou přepínače {$±název}. Názvem bývá jeden znak. 6

3 Deklarace datových typů a konstant datových typů rozdělení datových typů a jejich popis operace nad ordinálními datovými typy množina přípustných hodnot a množina operací operace a funkce pro jednoduché standardní typy datová šířka jednotlivých datových typů konstanty s definovaným typem Co výčtový datový typ? Název proměnných viz Povolené názvy identifikátorů 2.1. 1. Jednoduché (a) Desetinné číslo s pohyblivou desetinnou čárkou (b) Ordinální celočíselné (c) boolean pravda/nepravda 2. Strukturované složeno z více typů (ať už jednoduchých nebo strukturovaných) (a) Pole (b) Záznam (c) Množina (d) Soubor 3. Ukazatel obsahuje adresu v paměti 3.1 Inicializace proměnných Než se proměnné použijí poprvé pro numerické či jiné operace, je dobré je inicializovat, tedy přiřadit jim nějakou hodnotu. Jejich hodnota po definici totiž nemusí být nulová. 7

3.2 Celočíselné typy Jejich hodnota může být interpretována jako celé číslo. Integer Nejběžnější typ ( 32768 32767, velikost 2 B ±2 15, znaménkový bit a nula) Nejdůležitější operace pro něj definované: relační operace (<, >, =) + sčítání - odčítání nebo unární změna znaménka * násobení div celočíselné dělení mod zbytek po celočíselném dělení Tyto platí i pro další celočíselné typy s výjimkou char Longint Podobný typu integer, větší rozsah ( 2147483648 2147483647, velikost 4 B ±2 31, znaménkový bit a nula) Byte Nezáporný (0 255, 1 B) Vhodné použití např. jako řídící proměnná cyklu Word Větší nezáporný (0 65535, 2 B) Char zvláštní typ znak ASCII (American Standard Code for Information Interchange) kódu (velikost 1 B) Přestože se dá brát jako celé číslo, mnoho operací s celými čísly pro něj Pascal neumožňuje. Existují pro něj speciální funkce: chr() převede číslo na znak odpovídající jemu kódu. ord() převede znak na odpovídající číslo succ() vrací násladující znak ( d e ) pred() vrací předchozí znak ( d c ) 3.3 Desetinné typy Lépe typy s pohyblivou desetinnou čárkou. Pozor! V Pascalu se místo ní používá desetinná tečka. V paměti je tvoří dvě celá čísla (a bit pro znaménko): 1. Mantisa tj. významové číslice (v paměti bez desetinné čárky) 2. Exponent Z toho vyplývá druhý možný zápis exponenciální: 5.45E 3 = 0, 00545 Kromě celočíselných operací je definováno i dělení a jiné matematické funkce. Převody mezi číselnými typy: 8

Z celočíselných na desetinná je implicitní (automatický). Z desetinných na celočíelných nelze existují speciální zaokrouhlovací funkce. Real Základní typ (velikost 6 B, zhruba 10 39 10 38 ) Single 4 B 1, 5E 45 3, 4E38 Double 8 B 5E 324 1, 7E308 3.4 Typové konstanty Při definici konstanty můžeme definovat kromě její hodnoty i její typ. Nejedná se pak o pravou konstantu, protože ji za běhu programu můžeme měnit. const K : byte = 4; 9

4 Datový typ řetězec popis a deklarace typu řetězec, deklarace konstanty kompatibilita typů char a string řetězec jako pole znaků základní procedury a funkce pro práci s řetězci konverze mezi datovým typem string a číselnými datovými typy Řetězec je homogenní typ příbuzný poli jedná se o řetězec znaků. Pascal má zabudouvanou podporu pro řetězce datový typ string. Ten může mít až 255 znaků. Může mít definovanou i jinou, menší, velikost. Ta za běhu programu nelze měnit. var jmeno : string[50]; V paměti zabírá (velikost+1) B nultý znak označuje jeho délku. Nezaplněné znaky řetězce jsou nedefinované znaky. 4.1 Řetězcové konstanty Hodnota řetězcové konstanty je umístěna mezi dvě jednoduché uvozovky ( ). const pozdrav[4] = ahoj ; 4.2 Operace s řetězci Řetězce je možno navzájem přiřazovat i nestejně velké. Pokud se řetězec do proměnné nevejde celý, je ořezán na danou velikost. Je možné přistupovat k jednotlivým znakům řetězce ten se v tomto případě chová jako pole typu char. Číslování je od jedničky: var radek : string; begin radek[1] := A ; radek[2] := C ; succ(radek[2]) = D ; Relační operace podle pořadí znaků v ASCII. Spojování řetězců operátorem +. Length() vrací aktuální délku řetězce. 10

Pos() vrací polohu podřetězce v řetězci. Copy(S, index, count) vrací část řetězce count znaků od čísla znaku index. Concat(S1, S2, S3,... ) spojuje řetězce. Insert(Source, S, index) vloží řetězec source do řetězce S od znaku index. Delete(S, index, count) vymaže count znaků od znaku index. Str(cislo,retezec) převede číslo na řetězec. Val(retezec,cislo,chyba) pokusí se převést řetězec na číslo. Pokud je převod úspěšný, chyba je 0, jinak vrací pozici prvního nepřípustného znaku. 11

5 Datový typ pole deklarace typu pole a proměnné typu pole deklarace konstant načítání a výpis prvků pole Dvě věci mám jisté jen pro turbopascal přiřazování polí a omezení velikosti indexovacího typu Pole je strukturovaná proměnná složená z více proměnných stejného typu. Jeho prvky jsou uspořádané a přístupné přes indexování podle pořadí v poli. Má pevně danou velikost tedy počet prvků. 5.1 Pole v Pascalu Deklarace: array [ typ indexu ] of datový typ typ indexu Udává nejen počet prvků, ale i způsob, kterým se k nim bude přistupovat. Pole může být indexováno pouze ordinálními (celočíselnými) typy, které bývají navíc omezeny velikostí (2 B) Pascal umožňuje: Stanovení počtu prvků array[5] of Indexují se od jedničky, nikoli od nuly! Stanovení intervalu array[1..40] of Pozor! Používají se dvě tečky místo tří. Pozn.: char je také ordinální typ, a proto array[a..z] of je možné datový typ Udává datový typ jednotlivých prvků. Může být i další pole. Práce s jednotlivým členem: var pole : array[1..4] of integer; pole[1] := 5; Pozor! Pokud chceme pole předávat proceduře nebo funkci, musíme si jej nadefinovat jako typ: type pole_t = array[1..4] of integer; procedure nacti(var pole : pole_t)... 5.2 Pole jako konstanta Je možné definovat pole i jako konsantu (která vlastně konstanta není viz datové typy. Hodnoty prvků se pak zadávají v pořadí od prvního do posledního oddělené čárkami. const pole : array[1..4] of integer = (25, 30, 18, 22); 12

5.3 Operace s poli S poli není možno provádět většinu matematických operací jako je sčítání odčítání apod. Nemohou být ani porovnávána. Přiřadit pole poli je možné pouze, pokud jsou stejného typu, tedy mají stejné indexování a stejný typ prvku. Všechny operace prováděné s jednotlivými prvky (matematické, načítání, výpis) se provádějí většinou pomocí cyklů s daným počtem opakování. Viz cykly. const N = 10; var cislo : array[1..n] of integer; begin for i := 1 to N do begin cislo[i] = i*i+i+1; end; end. 13

6 Datový typ záznam deklarace typu záznam a proměnné typu záznam deklarace konstant přístupy ke složkám záznamu způsoby uchování záznamů v operační paměti a na externím médiu Záznam je heterogenní posloupnost skládající se z určitého počtu po sobě jdoucích položek různých typů. Položky jsou v paměti umístěné za sebou a jejich počet není omezen (pouze velikost záznamu musí být menší než 65535 B). type název = record položka : typ;... end; K jednotlivým položkám záznamu se přistupuje tečkovou notací s pomocí tečky a jejich názvu. záznam.položka Záznamy stejného typu lze sobě navzájem přiřazovat (pokud přiřazovaný záznam není prázdný). 6.1 Konstanty Hodnota se konstantám přiřazuje přes jednotlivé položky: type souradnice = record X, Y : integer; end; const pocatek : souradnice = (X: 0, Y: 0); 6.2 Operace nad záznamem Pokud provádíme více operací s prvky záznamu, můžeme s výhodou využít blokové konstrukce: with záznam do Ve vnořeném bloku nemusíme prvky záznamu adresovat skrze tečkovou notaci ale přímo jejich názvy. 14

6.3 Variantní záznam Pascal umožňuje, aby měly dva záznamy jednoho typu různé položky (jakýsi předek dědičnosti objektů), a to v závislosti na jiném jeho prvku přepínači: type souradnice = record case polarni : boolean of true : (X,Y : real); false : (delka, uhel : real); end; Přepínač může být pouze jeden a je vždy ordinální. Variantní část je vždy na konci. Variantní část zabírá v paměti tolik místa, kolik zabírá její paměťově nejnáročnější varianta. Kontrola přístupu ke správné variantě je na autorovi programu. Při definici konstanty je třeba nejprve uvést hodnotu přepínače a až pak hodnoty prvků ve variantní části. 6.4 Záznamy a relace Vzhledem k možnosti prvků různého typu je možno záznam s výhodou využít pro relační databázi, kde položky jsou jednotlivé atributy. 15

7 Dynamické proměnné popis dynamické proměnné z hlediska práce s pamětí srovnání se statickou proměnnou metody práce s dynamickou proměnnou tvorba seznamů a stromů Terminologií (lineární versus kruhové) si nejsem jist. Binární strom synové. Navíc, co ty regulérní výrazy? Na rozdíl od statické proměnné, o jejíž vytvoření se stará překladač sám a která je platná v jednom bloku, vytváření a ničení dynamické proměnné je řízeno autorem programu. 7.1 Ukazatele Vytváření dynamických proměnných se děje skrze ukazatele. Ukazatel je specifický datový typ, který obsahuje adresu paměti, říkáme tedy, že ukazuje na místo v paměti. Má jednotnou velikost, 4 B. Ukazatel sám o sobě je proměnná statická a jeho správu řeší překladač. Ukazuje ale na úsek paměti. Rozlišujeme ukazatele: typové ukazují na konkrétní typ univerzální (netypové) typ pointer kompatibilní se všemi ukazateli Ukazatele si můžeme pouze přiřazovat a to pouze ukazatele stejného typu. Existuje významná ukazatelová konstanta nil, která značí, že ukazatel na nic neukazuje. Pomocí operátoru @ nebo funkce addr() můžeme získat adresu statického objektu. var uk_cislo : ^integer; cislo : integer; begin uk_cislo := @cislo;... 7.2 Alokace a uvolnit Tedy proces vytvoření dynamické proměnné. Je úzce vázána na ukazatel, který pak na nově vytvořenou proměnnou ukazuje. Paměť se bere z místa označeného heap (halda). Jeho velikost záleží na překladači (kde lze nastavit). new(ukazatel); přidělí paměť typu daného typem ukazatele 16

Alokací se přidělí ukazateli místo v paměti a program jej rezervuje, takže nemůže být znova přiděleno. K dynamické proměnné se přistupuje pomocí ^. var uk_int : ^integer; begin new(uk_int); uk_int^ := 6;... Chceme-li uvolnit paměť a tím zrušit proměnnou: dispose(ukazatel); Uvolněný ukazatel má hodnotu nil. Pokusíme-li se uvolnit nenaalokovanou paměť, program skončí chybou. Poznámka: Lze použít i procedury GetMem(var P : Pointer; Velikost : word) a FreeMem(var P : Pointer; Velikost : word) zvláště pracujeme-li s univerzálním ukazatelem. 7.3 Chyby při práci s dynamickými proměnnými Přidělování paměti je plně v rukou autora programu. Platí ale, že to, co bylo naalokováno musí být také uvolněno. Při práci s ukazateli se v zásadě můžeme dopustit dvou chyb: 1. Ztracení ukazatele na paměť. Zůstane naalokovaná paměť, na kterou nevede žádný ukazatel, nelze tedy uvolnit. Často vede až k přetečení haldy (heap overflow). Může se přihodit především ve dvou případech: Alokace nové paměti na ukazatel, kterou má už paměť přidělenou má: new(uk_int); new(uk_int); a paměť je ztracená Přiřazení adresy ukazateli, který má přidělenou paměť: new(uk_int); uk_int := uk_int2; a paměť je ztracená Obojí v případě, že neexistuje ještě jeden ukazatel ukazující na danou paměť. 2. Ukazatel na nealokovanou paměť. Můžeme pomocí něj měnit obsah paměti, která pak může přidělena jiné proměnné. Špatně se odhaluje. Obecně se děje, pokud dva ukazatelé ukazují na stejné místo v paměti a pak pomocí jednoho z nich paměť uvolníme: new(uk_int); uk_int2 := uk_int; 17

dispose(uk_int2); uk_int := 3; a už máme v paměti zmatek Není také dobré předpokládat, že nově vytvořené ukazatele budou mít hodnotu nil. Viz inicializace proměnných (datové typy). 7.4 Dynamické struktury Využívají dynamických proměnných, čímž získávají výraznou výhodu nemají pevně danou velikost. Jejich velikost je ale omezená velikostí haldy. Implementačně je základem dynamické struktury uzel nejčastěji typu record, který obsahuje datovou část a jeden nebo více ukazatelů na další uzly. Každá struktura má základní uzel, na něhož máme ukazatel. Na ostatní uzly je možné se z něj dostat. Pokud ztratíme adresu základního uzlu, je celá struktura ztracena a zabírá už jen paměť. 7.4.1 Spojové seznamy Vytváří uspořádanou strukturu podobnou poli. Na rozdíl od polí je ale přístup k jednotlivým prvkům operačně a tím časově náročný, protože je potřeba projít všechny předchozí prvky. Proto se u setřízených seznamů zavádí indexování ukazatele na některé uzly seznamu (např. pro seznam jmen ukazatele na první jména pro písmena v abecedě). Z hlediska implementace rozlišujeme seznamy na: jednosměrné každý uzel nese ukazatel na následující uzel obousměrné každý uzel nese ukazatel na předchozí a následující uzel lineární jasně daný začátek a konec (nejčastěji prázdnými ukazateli) kruhové poslední uzel ukazuje na první (a v případě obousměrného i první na poslední) Nejčastěji používané jsou jednosměrný lineární seznam pro jeho nenáročnost na paměť a obousměrný kruhový seznam pro jeho jednodušší a časově méně náročnou správu. Logicky pak rozlišujeme dva typy: Zásobník LIFO (Last-In-First-Out) pracuje se pouze s vrcholem, první vložený prvek je odebrán jako poslední. Potřebně operace: vytvoření prázdného zásobníku vložení prvku na vrchol zásobníku odebrání prvku z vrcholu zásobníku testování prázdnosti zásobníku 18

Fronta FIFO (First-In-First-Out) pracuje se začátkem i koncem, první vložený prvek je také první odebrán. Potřebné operace: vytvoření prázdné fronty vložení prvku na konec fronty odebrání prvku ze začátku fronty test prázdnosti fronty 7.4.2 Binární strom Každý uzel má ukazatele na syny. Z kořene (tj. uzel, který není synem žádného uzlu) se dá dojít do všech listů (bez synů). Lze implementovat i pomocí pole (pro indexy jsou důležité mocniny dvou). Nejčastěji bývá používán jako binární vyhledávací strom, halda (neplést s haldou uložištěm) nebo pro analýzu regulérních výrazů. 19

8 Příkazy (procedury) vstupu ze standardního zařízení syntaxe příkazů read a readln uživatelsky přívětivý vstup dat vstup posloupnosti dat se zarážkou vstup dat z externího souboru, standardní input soubor. Pascal má standartně zabudovaný bufferovaný vstup. Z klávesnice se do bufferu vyrovnávací paměti načte určitý počet znaků a až pak se předají programu. Buffer je 128B, má tedy kapacitu 128 znaků. Naplní se při ukončení řádku, tedy když uživatel stiskne klávesu enter. Konec řádku je značen řídícími znaky chr(13) CR (carriage return) a chr(10) LF (line feed). CR vrací kurzor na začátek řádku, LF jej posunuje na další řádek. Do bufferu se načítá pouze CR. Další možný řídící znak je chr(26) EOF, kterým se standartně označuje konec souboru. Vyvolat jej můžeme například kombinací kláve ctrl+z. Buffer tedy končí znakem CR nebo EOF, proto může uživatel najednou zadat jen 127 znaků. Výše uvedená reprezentace konce řádku řádku platí jen v některých operačních systémech (DOS, Windows a další), pro přenositelnost je proto lepší pro kontrolu konce řádku použít funkci eoln. 8.1 Příkazy vstupu Dva základní příkazy jsou read a readln. Jako parametr se uvádí proměnná, do které načítají. Těch může být i více za sebou. Načítá pouze jednoduché typy (kromě boolean) a řetězec. Podle typu proměnné program načte (ukončující znak bufferu se nikdy nezačítá): char jeden znak string znaky do řetězce dokud se nezaplní a nebo neskončí buffer číselné typy posloupnost znaků tvořící zápis čísla v desítkové soustavě (i se znaménkem). Může před ním být libovolný počet prázdných znaků a končí prázdným znakem nebo s bufferem. U desetinných typů je možný i exponenciální zápis. Oproti read načte readln data do danných proměnných a zbytek bufferu zahodí. Příkazu readln bez parametru se využívá jako konstrukce pro pokračování stiskněte enter. 20

8.2 Kontrola vstupu Zatímco načítání typů char a string je relativně bezproblémové, závažný problém nastává při načítání čísel. Uživatel může zadat i jiné znaky než prázdné a číselné, což způsobí, že program skončí chybou. 1. Jednodušší možností je načtení řádku do řetězce a následné převedení na číslo pomocí val(), kdy při chybě vrácené val() uživatele požádáme o opětovné zadání čísla viz také zadávání se zarážkou. 2. Složitější, avšak přívětivější cesta je načítání po znacích funkcemi jednotky crt, kdy uživateli nedovolíme nečíselné znaky. Problémy zde přináší zvláště desetinná tečka (!) a exponenciální zápis desetinných čísel. Po zadání opět pracujeme s val(). 8.3 Uživatelská přívětivost Pokud se má uživateli s programem dobře pracovat, měli bychom dodržet pár zásad: Uživatel musí vědět, co má zadat, pokud možno co nejpřesněji. Zadejte své telefonní číslo (9 číslic bez mezer): _ (to už je trochu extrém, ale znáte uživatele) Uživatel by neměl zadávat více hodnot najednou pouze jedna hodnota na řádek. Pro zadávání čísel je užitečná kontrola platných číslic viz výše. 8.4 Zadávání se zarážkou Využívá se ho tehdy, má-li vstup splňovat určité podmínky. Například má-li se jednat o číslo, popřípadě číslo z nějakého intervalu. Využívá cyklu s podmínkou na konci a nutí uživatele stále zadávat, dokud vstup nesplňuje výstupní podmínku. 8.5 Standartní vstupní soubor Standartní vstupní soubor je textový. Je tvořen znaky rozdělenými do řádků. Ty jsou odděleny znaky CR a LF (opět závisí na OS). Soubor končí znakem EOF. Načítá se také pomocí read() a readln(), kde se před seznam proměnných umístí identifikátor souboru. Doporučuje se testovat pomocí funkce eof(identifikátor souboru), zda jsme již nedosáhli konce souboru. 21

9 Příkazy (procedury) výstupu na standardní zařízení syntaxe příkazů write a writeln formátovaný výstup výstup do diskového souboru Obrazovka je rozdělena souřadnicovou sítí na řádky a sloupce. Pozice znaku pak určuje jeho souřadnice. Operační systém si vždy pamatuje pozici, na kterou bude vložen další znak. Tato pozice je na obrazovce označena kurzorem. Standartní výstup je podřízen univerzálnímu zpracování textových souborů, a proto umožňuje jen základní výpisové operace. Pokročilejší práci s obrazovkou umožňuje jednotka crt. Základní příkazy pro výstup jsou write a writeln. Obě mají jako parametry vypisované proměnné. Procedura writeln ještě navíc nakonec vytiskne znaky pro konec řádku. Dochází ke konverzi všech proměnných na řetězec. 9.1 Formát výstupu Jedná se hlavně o oddělení jednotlivých proměnných. Klasikou jednoho řádku je oddělení řetězcovou konstantou, především mezerou ( ), jde ale také vytvořit tabulku, napíšeme-li proměnné ve formátu: proměnná : délka Pokud je délka výstupní interpretace proměnné menší, doplní se zleva mezerami, pokud je větší, zachová se celá proměnná. Zvláštnosti některých typů: boolean vypisován jako TRUE nebo FALSE desetinná čísla znaménko, jedna významová číslice, desetinná tečka, zbytek významových číslic, E, exponent. Může být vypsáno jako klasické desetinné číslo: proměnná : délka : počet desetinných míst 9.2 Standartní výstupní soubor Standartní výstupní soubor je textový. Pracuje se s ním stejně jako se standartním výstupem na obrazovku (výstup na obrazovku se řídí výstupem do textového souboru), jen u procedur write a writeln patří před seznam proměnných identifikátor souboru. 22

10 Sekvence a podmínka syntaxe a sémantika přiřazovacího příkazu způsob vyhodnocení přiřazovacího příkazu překladačem syntaxe a sémantika úplného a neúplného podmíněného příkazu, vývojový diagram podmíněného příkazu příkaz case vnořené podmíněné příkazy Má tam cenu dávat ty zbytečné konstrukce Co vnořené podmínky? 10.1 Přiřazovací příkaz proměnná := výraz Realizuje přiřazení hodnoty proměnné. Nejdříve je vyhodnocena pravá strana a pak je přiřazena proměnné na levé straně. Typ výsledku výrazu musí být kompatibilní s proměnnou (tj. musí se na ni dát převést). Všechny proměnné ve výrazu by měly mít definovanou hodnotu! 10.2 Typ boolean Specifikuje logické hodnoty pravda (TRUE) a nepravda (FALSE) má velikost 1 B (menší už prostě nemůže být). Platí TRUE > FALSE. Základní operace jsou: AND logický součin OR logický součet NOT negace (unární) Získáváme jej také porovnáváním proměnných. Celkově ale mluvíme o výrazu, který je typu boolean, tedy jeho výsledkem je pravda nebo nepravda. 10.3 Podmínka Podmíněný příkaz je základním větví konstrukcí. Umožňuje na základě hodnoty výrazu typu boolean provést jeden nebo druhý příkaz nebo blok. Po jeho provedení program pokračuje dále. if výraz then 23

1. Neúplná podmínka je-li výraz pravdivý, provede se příkaz (nebo blok), je-li nepravdivý, neprovede se nic. if výraz then begin... end; 2. Úplná podmínka má dvě větve. Využívá klíčového slova else if výraz then begin... end else begin... end; Poznámka: Na konci posledního příkazu, nebo end před else se nepíše středník! Poznámka: mezi začínajícími programátory se vyskytují dvě zbytečné konstrukce, které se dají zjednodušit: 1. if vyraz = true then if výraz then 2. if výraz then proměnná := true else proměnná := false; proměnná := výraz; 10.4 Selektor Příkaz case větví program na základě hodnoty ordinálního (celočíselného) výrazu. case výraz of hodnota : příkaz;... hodnotan : příkazn else příkaz end; Část else se provede, pokud výraz nenabyde žádné z uvedených hodnot a není povinná. Na konci posledního příkazu nebo end (místo příkazu vždy může být blok) před else se opět nepíše středník. 24

11 Cyklus cykly s podmínkou na začátku a na konci a rozdíly mezi nimi podmínka opuštění cyklu, tělo cyklu, parametr cyklu načítání dat se zarážkou záměna cyklů while a repeat cykly se známým počtem opakování požadavky na řídící proměnnou cyklu Podmíněné cykly vykonávají opakovaně příkaz (nebo blok) v závislosti na hodnotě výrazu typu boolean, tedy v případě, že předem neznáme počet opakování. V zájmu resultativnosti algoritmu a konečnosti programu je dobré věnovat pozornost podmínce cyklu. 11.1 Podmínka na začátku Cyklus se opouští nesplněním podmínky. Nejprve se vyhodnotí podmínka, pak provede tělo cyklu. Počet průchodů tělem může být tedy nulový. while výraz do begin... end; 11.2 Podmínka na konci Cyklus se opouští splněním podmínky. Nejprve proběhne tělo, pak se vyhodnotí podmínka. Tělo je tedy vždy alespoň jednou provedeno. repeat... until výraz; 11.3 Záměna podmíněných cyklů Oba cykly s podmínkou jsou zaměnitelné. Při rozhodování mezi nimi vždy vybíráme ten, kterým lze vyjádřit algoritmus snadněji. Při záměně je třeba vždy znegovat podmínku jeden z cyklů se ukončuje při splnění, druhý při nesplnění. while repeat: Cyklus repeat vložíme do podmínky původního cyklu. repeat while: Před cyklus while zkopírujeme tělo cyklu. 25

11.4 Zadávání dat se zarážkou Používá se, pokud chceme od uživatele data splňující určitou podmínku (např. číslo). Využívá se cyklus načítající data, dokud nesplňují podmínku. 11.5 Cyklus s dvěmi podmínkami Pokud má cyklus dvě podmínky, z nichž jedna stačí, aby se ukončil, kontrolujeme po proběhnutí cyklu, která z podmínek jej ukončila: while výraz1 and výraz2 do příkaz; if výraz1 then... Tento cyklus se využívá především při procházení struktur (např. polí nebo seznamů), kdy se zároveň kontroluje hodnota položky a jestli nebyl překročen rozsah struktury. 11.6 Cyklus s daným počtem opakování Pro cyklus s předem daným počtem opakování. for proměnná := dolní to horní do begin... end; Řídící proměnné se přiřadí hodnota výrazu dolní. Pokud je řídící proměnná menší nebo rovna výrazu horní, proběhne tělo cyklu. Po každém proběhnutí těla cyklu je řídící proměnné přiřazen její následovník (tj. zvýší se o 1). Řídící proměnná musí být ordinální. S řídící proměnnou lze pracovat v těle cyklu pak je ale třeba dávat pozor, aby byl cyklus vždy konečný. Pokud horní < dolní, neprovede se tělo cyklu ani jednou. Je možné aby se řídící proměnná snižovala. Cyklus má pak syntaxi: for proměnná := horní downto dolní do Dolní a horní mez se vyhodnotí pouze na počátku (v průběhu cyklu se nemění), oproti podmíněným cyklům, kdy se výraz vyhodnocuje průběžně. 26

12 Procedury bloková struktura procedury procedury s parametry a bez parametrů, formální parametry procedury uživatelem definované procedury a procedury implementované v jazyce Pascal lokální a globální objekty (proměnné, procedury, funkce) parametry volané hodnotou a odkazem volání procedur Procedura je druh podprogramu, který nevrací svým voláním žádnou hodnotu. Využívá se především na dělení programu do menších částí tedy základ strukturovaného programování a k jako výkonný podprogram. Často obsahuje pracuje se vstupem nebo výstupem. Je to prvek blokové struktury (viz Strukturované programování), je v něm tedy možné definovat vlastní (lokální) proměnné, konstanty, typy a dokonce další podprogramy. Hlavička const definice konstant type definice typů var definice proměnných Definice podprogramů begin Příkazy end; Všechny definované konstanty, typy, proměnné a podprogramy jsou lokální tj. jsou přístupné pouze z daného bloku a do něj vnořených bloků. Zároveň překrývají globální objekty stejného názvu. 12.1 Hlavička 1. Bez parametrů: procedure identifikátor; 2. S parametry: procedure identifikátor(seznam parametrů); Procedura volá svým identifikátorem se seznamem svých parametrů. printhello; print(hello ); Formální parametry mohou být různého typu a mohou být předávány různým způsobem. Uvedením parametru v hlavičce procedury prakticky vytváříme 27

lokální proměnnou daného názvu. Pozor! Pokud předáváme parametry strukturovaného typu, musí být nadefinován v typové části nadřazeného bloku. Např. pole : array[1..5] of integer nejde v hlavičce vůbec použít. Skutečný parametr je proměnná stejného typu jako formální parametr, kterou mu přiřazujeme. parametr : typ Při předávání hodnotou si program v paměti vytvoří novou lokální proměnnou a do ní zkopíruje obsah skutečného parametru. Od té doby nemá proměnná se skutečným parametrem žádný vztah a její změna jej nijak neovlivňuje. Předávání hodnotou má především tu výhodu, že nemůže dojít ke změně skutečného parametru, proto se používá standartně, pokud skutečný parametr nechceme měnit. Přesto se nedoporučuje používat jej pro velké strukturované typy (např. pole), protože celá proměnná se kopíruje, což by bylo náročné na paměť. var parametr : typ Při předání odkazem vznikne proměnná obsahující odkaz na skutečný parametr. Všechny změny na proměnné se tedy provádějí na skutečném parametru. Předávání odkazem se používá pouze tehdy, je-li účelem podprogramu měnit skutečný parametr. Toho využívá také, pokud má parametr tvořit jistou formu výstupu. Také se používá pro právi s velkými datovými strukturami, ačkoli to není bezpečné a je třeba si dávat pozor. Parametry stejného typu se oddělují čárkou, různé typy středníkem. 12.1.1 Netypový parametr Odkazem může být předán i parametr bez udání typu. Ten se pak chová jako hodnota, na kterou ukazuje univerzální ukazatel (typ pointer viz DDS). Před použitím je většinou třeba jej přetypovat. Jeho použití není ale příliš časté. var identifikátor 12.2 Zásady tvorby podprogramů Při tvorbě podprogramů obecně je dobré se řídit několika pravidly: Dílčí úkoly programu by měl být prováděny podprogramy. Pokud se v programu opakuje kód, je dobré uvažovat o použití podprogramu. Všechny globální proměnné, které podprogram potřebuje se mu mají předat podprogram je pak obecnější a víceúčelovější. Poslední uvedená zásada je častou chybou dochází tím k předčasné optimalizaci, která se projeví například v případě znovupoužití kódu nebo rozšiřování programu. 28

12.3 Rekurze Pascal umožňuje, aby poprogram volal sám sebe. Využívá se toho například při procházení stromu nebo rekurzivních matematických řádách (faktoriál apod.). Vždy je třeba určit výstupní podmínku, při které se rekurze ukončí, aby nedošlo k zacyklení. Rekurze je z hlediska efektivity algoritmu nevýhodná, protože při volání podprogramu se provádí pomocné akce (vytvoření lokálních proměnných a další), proto se doporučuje ji používat jen pokud příliš nezáleží na efektivitě algoritmu a rekurzivní zápis je výrazně jednodušší, nebo nerekurzivní algoritmus vůbec není znám. Alternativou k rekurzi jsou cykly. 29

13 Funkce bloková struktura funkce formální parametry funkce uživatelem definované funkce a funkce implementované v jazyce Pascal lokální a globální objekty (proměnné, procedury, funkce) přiřazení hodnoty funkcí rozdíl mezi procedurou a funkcí volání funkcí Funkce je druh podprogramu, který svým voláním předává hodotu. Jeho využití je především matematické, v rámci funkce by neměl být prováděn vstup ani výstup 1. Je to prvek blokové struktury (viz Strukturované programování), je v něm tedy možné definovat vlastní (lokální) proměnné, konstanty, typy a dokonce další podprogramy. Hlavička const definice konstant type definice typů var definice proměnných Definice podprogramů begin Příkazy end; Všechny definované konstanty, typy, proměnné a podprogramy jsou lokální tj. jsou přístupné pouze z daného bloku a do něj vnořených bloků. Zároveň překrývají globální objekty stejného názvu. 13.1 Hlavička Lze volat i bez parametrů, čož se ale většinou nedělá, vzhledem k jejímu použití (viz Zásady tvorby podprogramů). Výstupní typ nesmí být strukturovaný. function identifikátor(seznam parametrů) : typ funkce; Funkce se volá svým identifikátorem a seznamem parametrů. Protože má výstupní hodnotu, musí být součástí výrazu ze syntaktického hlediska je výrazem, ne příkazem. V těle funkce musí být identifikátoru funkce přiřazena hodnota výstupní hodnota funkce. 1 Alespoň co se Pascalu, výukového programovacího jazyka, týče. Jinak je běžnou praxí například používat funkce, které vrací úspěšnost operace apod. 30

Formální parametry mohou být různého typu a mohou být předávány různým způsobem. Uvedením parametru v hlavičce procedury prakticky vytváříme lokální proměnnou daného názvu. Pozor! Pokud předáváme parametry strukturovaného typu, musí být nadefinován v typové části nadřazeného bloku. Např. pole : array[1..5] of integer nejde v hlavičce vůbec použít. Skutečný parametr je proměnná stejného typu jako formální parametr, kterou mu přiřazujeme. parametr : typ Při předávání hodnotou si program v paměti vytvoří novou lokální proměnnou a do ní zkopíruje obsah skutečného parametru. Od té doby nemá proměnná se skutečným parametrem žádný vztah a její změna jej nijak neovlivňuje. Předávání hodnotou má především tu výhodu, že nemůže dojít ke změně skutečného parametru, proto se používá standartně, pokud skutečný parametr nechceme měnit. Přesto se nedoporučuje používat jej pro velké strukturované typy (např. pole), protože celá proměnná se kopíruje, což by bylo náročné na paměť. var parametr : typ Při předání odkazem vznikne proměnná obsahující odkaz na skutečný parametr. Všechny změny na proměnné se tedy provádějí na skutečném parametru. Předávání odkazem se používá pouze tehdy, je-li účelem podprogramu měnit skutečný parametr. Toho využívá také, pokud má parametr tvořit jistou formu výstupu. Také se používá pro právi s velkými datovými strukturami, ačkoli to není bezpečné a je třeba si dávat pozor. Parametry stejného typu se oddělují čárkou, různé typy středníkem. 13.1.1 Netypový parametr Odkazem může být předán i parametr bez udání typu. Ten se pak chová jako hodnota, na kterou ukazuje univerzální ukazatel (typ pointer viz DDS). Před použitím je většinou třeba jej přetypovat. Jeho použití není ale příliš časté. var identifikátor 13.2 Zásady tvorby podprogramů Při tvorbě podprogramů obecně je dobré se řídit několika pravidly: Dílčí úkoly programu by měl být prováděny podprogramy. Pokud se v programu opakuje kód, je dobré uvažovat o použití podprogramu. Všechny globální proměnné, které podprogram potřebuje se mu mají předat podprogram je pak obecnější a víceúčelovější. Poslední uvedená zásada je častou chybou dochází tím k předčasné optimalizaci, která se projeví například v případě znovupoužití kódu nebo rozšiřování programu. 31

13.3 Rekurze Pascal umožňuje, aby poprogram volal sám sebe. Využívá se toho například při procházení stromu nebo rekurzivních matematických řádách (faktoriál apod.). Vždy je třeba určit výstupní podmínku, při které se rekurze ukončí, aby nedošlo k zacyklení. Rekurze je z hlediska efektivity algoritmu nevýhodná, protože při volání podprogramu se provádí pomocné akce (vytvoření lokálních proměnných a další), proto se doporučuje ji používat jen pokud příliš nezáleží na efektivitě algoritmu a rekurzivní zápis je výrazně jednodušší, nebo nerekurzivní algoritmus vůbec není znám. Alternativou k rekurzi jsou cykly. 32

14 Datový typ soubor soubor fyzický a soubor jako proměnná textový soubor, typový soubor, soubor bez udání typu čtení ze souboru a zápis do souboru procedury a funkce pro práci se soubory zásady pro práci se souborem Zajímavé jsou předdefinované proměnné Output a Input standartní výstup a vstup, typ text. Je také možno zmínit vazbu na relační databázi. Soubor je uspořádaná pojmenovaná kolekce dat, která je uložená v trvalém uložišti. Trvalém v tom smyslu, že zůstává přístupný jiným programům poté, co program, který jej vytvoři, skončil. Fyzicky se jedná o sekvenci bytů. Ty můžou reprezentovat data různého typu. V programu je soubor spojen s jednou proměnnou souborového typu. Rozlišujeme tři typy souborů: 1. Typový soubor má udaný typ (i strukturovaný jen součástí struktury nesmí být soubor) Bere se jako sekvence proměnných danného typu. identifikátor : file of typ 2. Textový soubor standartní vstupní a výstupní soubor Bere se jako sekvence znaků. identifikátor : text 3. Netypový soubor bez udání typu. Používá se, když není třeba brát ohled na vnitřní formát. Bere se obecně jako sekvence bytů. identifikátor : file 14.1 Spracování souboru Datovému typu soubor nepřísluší žádné operace, ani přiřazování, veškerá manipulace se provádí pomocí standartních procedur. 1. Spojení proměnné se souborem. Děje se pomocí procedury assign: assign(proměnná soborového typu, název souboru); 2. Otevření souboru. Děje se pomocí procedur reset, rewrite a append (pouze textové). Jejich použití závisí na typu souboru. 3. Zpracování souboru. Děje se především pomocí procedur read a write a pomocných funkcí. Opět závisí na typu. Základní kontrolní funkce je eof, která vrací true, jestliže program dosáhl konce souboru. 33

4. Zavření souboru. Je nutné, aby s jistotou došlo k zápisu na disk (a nedošlo ke ztrátě dat). close(identifikátor souboru); 14.2 Textový soubor rewrite vytvoří nový prázdný soubor, popřípadě vymaže existující. Přístup pro psaní. reset otevře existující soubor na začátku. Pouze pro čtení. append otevře existující soubor pro zápis na konec souboru. Vstup je prováděn pomocí procedur readln a read (která ale neumí načíst konec řádku). Více k standartnímu souboru viz Standartní vstup. 14.3 Typový soubor Procedura rewrite otevře nový soubor nebo vymaže existující. Co udělá se souborem procedura reset záleží na konstantě FileMode : byte. 0 pouze pro čtení 1 pouze pro zápis 2 pro čtení i pro zápis standartní hodnota Zpracování typových souborů je sekvenčně-indexové. Funkce write(identifikátor souboru, proměnné typu souboru) a read(viz předchzí) čtou a zapisují komponenty sekvenčně od aktuální pozice v souboru, tu však lze nastavit explicitně. K tomu slouží podprogramy: FileSize vrací velikost souboru v komponentách FilePos vrací aktuální pozici (první komponenta má pozici 0). Seek nastavuje aktuální pozici na dannou hodnotu. Truncate Odstraní aktuální komponentu a všechny následující. 14.4 Ošetření vstupu Zpracování souboru je kritická situace, kdy může dojít k chybám, nad kterými nemá program (a někdy ani uživatel) kontrolu, jako například neexistující soubor otevíraný ke čtení (časté), už otevřený soubor nebo vadné médium. Tyto chyby program standartně ukončí, Pascal ovšem umožňuje ošetření těchto vstupně-výstupních chyb. Uživatelské ošetření IO (input/output) operací se nastavuje pomocí direktivy {$I}. {$I-} kontroluje uživatel (program se neukončí běhovou chybou) {$I+} kontroluje program Po každé chybné IO operaci můžeme vyvolat číslo chyby pomocí funkce IOResult. Nulová hodnota značí úspěšnou operaci. 34

15 Matice a operace s nimi datové struktury pro uložení matic základní matematické operace s maticemi Matice je v Pascalu reprezentována dvojrozměrným polem, které je ve skutečnosti polem polí: matice : array[1..n] of array[1..n] of integer zkráceně matice : array[1..n,1..n] of integer Podobně jako u pole (viz datový typ pole), můžeme dvě matice stejného typu navzájem přiřazovat a k jednotlivým prvkům matice přistupujeme pomocí indexů: matice[3,3] := 5; To, že je matice prakticky pole polí nám umožňuje operovat také s jednotlivými řádky. Například pokud je chceme prohodit nebo vynulovat. Při práci s jednotlivými prvky matic využíváme nejčastěji vnořené cykly (jeden pro řádky, druhý pro sloupce). 15.1 Operace s maticemi Z matematického hlediska je pro matici významná hlavní diagonála prvky s indexem [i,i]. 1. Nulování (a stejně inicializace) vynuluje se první řádek a přiřadí ostatním. 2. Načítání vnořené cykly s danným počtem opakování. Konvenčně vnější cyklus prochází řádky. 3. Výpis opět dva vnořené cykly 4. Transponování přehození řádků a sloupců 5. Násobení konstantou 6. Lineární kombinace matic (součet, rozdíl a další) 7. Násobení C mn = A ms B sn c ij = s k=1 a ik b kj Bude potřeba tří cyklů dvou, které projdou všechny prvky matice C a jednoho pro proměnnou k. 35

16 Třídící a vyhledávací algoritmy třídící algoritmy (insert sort, select sort, buble sort) efektivita třídicích algoritmů vyhledávání v nesetříděném souboru dat (lineární vyhledávání se zarážkou a bez zarážky) vyhledávání v setříděném souboru dat (binární vyhledávání) srovnání vyhledávacích metod Třídící algoritmus je algoritmus, který seřadí prvky seznamu podle určitého klíče. Nejčastěji se řadí podle numerické velikosti čísel nebo abecedně. Z formálního hlediska musí výstup splňovat: 1. Výstup je v nesestupujícím pořadí (tj. hodnota klíče prvku je menší nebo rovna klíči dalšího prvku) 2. Výstup je permutace vstupu. Nejčastěji se setřizují pole nebo seznamy (viz DDS). 16.1 Asymptotická složitost Je to způsob klasifikace algoritmů jak se bude měnit chování algoritmu když se změní velikost vstupních dat (počet prvků). Jednoduše řečeno, pokud je náročnost O ( N 2), zvýšíme-li počet prvků dvakrát, prodlouží se trvání procesu čtyřikrát. Nejčastější náročnosti třídících algoritmů jsou: O ( N 2) kvadratická: Většina jednoduchých algoritmů. O (N log N) lineárnělogaritmická: Většina sofistikovanějších (a složitějších) algoritmů. Operace s vyšší složitostí než je polynomiální ( O ( N X)) nemají z praktického hlediska (při větším objemu vstupních dat) využití. 16.2 Klasifikace Kromě asymptotické složitosti se třídící algoritmy ještě dají klasifikovat: Stabilita Pokud jsou v seznamu dva prvky se stejnou hodnotou, stabilní algoritmus zaručí, že po setřízení jsou ve stejném pořadí vůči sobě. Nestabilní algoritmus to nezaručuje. Přirozenost Přirozený algoritmus rychleji zpracuje už seřazený seznam. Nepřirozený spracovává všechny seznamy stejně rychle. 36

Dodatečná paměť Většinou závisí na počtu prvků uvádí se stejně jako asymptotická složitost. O(1) znamená, že dochází k setřízení na původním místě. Princip Existuje několik základních druhů algoritmů, přičemž některé algoritmy kombinují více z nich. V pokročilejších algoritmech se často používá řazení slučováním, také metoda rozděl a panuj, kdy se soubor dělí na menší části (většinou rekurzivně), které se potom slučují určitým způsobem. Obecně platí, že každý algoritmus je svými parametry vhodný pro jinou situaci a neexistuje žádný univerzální, který by byl nejvhodnější pro všechny. 16.3 Bubble sort Metoda přirozená a stabilní, sice nejjednodušší, ale nejpomalejší (O ( N 2) ). Nejrychlejší je pouze v případě, pokud je seznam už setřízen (pak má složitost O (N)). Nevyžaduje pomocnou paměť (z praktického hlediska jen jednu pomocnou proměnnou). Prochází seznam a porovnává sousední prvky. Pokud nejsou ve správném pořadí, prohodí je. V tom pokračuje, dokud není seznam setřízen (většinou je potřeba větší množství průchodů seznamem). Pro praktické účely není příliš vhodný, protože je pomalý a oproti algoritmům se stejnou náročností vyžaduje velké množství zápisů do paměti. 16.4 Shell sort Svým způsobem vylepšený bubble sort, který vychází z vysledovaných vlastností posloupností, kdy se každý prvek v průměru přesune o jednu třetinu její délky. Není stabilní a její přirozenost není jednoznačná. Složitost zatím nejlepší varianty byla experimentálně odvozena na O ( N log 2 N ). Implemetnačně se velmi podobá bubble sortu, jen se pracuje s určitým krokem v závislosti na velikosti posloupnosti. Porovnávají se vždy prvky vzdálené od sebe o krok, který se při každém průchodu posloupnosti zmenšuje, až na jedna. Zatím nejúspěšnější posloupnost kroků je: 1, 4, 10, 23, 57, 132, 301, 701 16.5 Selection sort Přirozený a stabilní algoritmus s kvadratickou složitostí. Pro jednoduchou implementaci, relativně malý počet zápisů do paměti a třízení na místě se často používá pro malé objemy dat. Je výhodný pro pole, pro seznamy je lepší insertion sort. Vyhledá v poli nejmenší prvek a prohodí jej s prvním prvkem. Dále pokračuje v nesetřízené části pole, která se tím neustále zmenšuje. 37

16.6 Insertion sort Přirozený a stabilní algoritmus s kvadratickou složitostí (pro už setřízené pole má lineární složitost). Nevhodný pro pole (velký počet zápisů do paměti), alternativa selection sortu pro seznamy, kde třídí na místě. Vyhledá v seznamu nejmenší prvek a vloží jej na začátek. Dále pokračuje v nesetřízené části a nejmenší prvky na konec setřízené části. Implemetace pro pole vyžaduje buď posouvání prvků (což je náročné na operace a zápis do paměti) a nebo vkládání do nového pole (což vyžaduje další paměť). 16.7 Quick sort Známý a relativně jednoduchý algoritmus s průměrnou složitostí O (N log N), která může vzrůst až na kvadratickou. Prakticky je na pseudonáhodné posloupnosti jeden z nejrychlejších algoritmů (i rychlejší než Heapsort a Mergesort, které jsou formálně rychlejší). Lze dobře paralelizovat. Ze seznamu se vybere pivot, podle kterého se rozdělí na dvě části. Na ty se tento postup rekurzivně opakuje. Pivot je prvek, který by měl seznam rozdělit na stejně velké části. Optimálně je to medián. 16.8 Merge sort Formálně rychlejší než quick sort v nejhorším případě má složitost O (N log N) a celkově provádí méně porovnání. Na druhou stranu vyžaduje více dodatečné paměti. Je nejčastěji nejlepší volbou pro seznamy (DDS), navíc se dá dobře paralelizovat. Seznam se rozdělí na dvě přibližně stejné části. Ty se dále rekurzivně rozdělují až na jednotlivé prvky. Ty se pak postupně po částech spojují (na začátek výsledné větší části se vždy přidá menší z prvních prvků vstupních částí). 16.9 Heap sort Jeho výhoda je maximální složitost O (N log) a třízení na místě. Není ale žádný zřejmý způsob jak jej paralelizovat a je nestabilní. Využívá speciální strukturu, binární haldu (heap) jistý druh binárního stromu, která je nejprve vytvořena a pak jsou z ní odebírány kořenové prvky. 16.10 Lineární vyhledávání Prochází postupně seznam, dokud nenarazí na hledaný prvek. Využívá se u nesetřízených seznamů a má složitost O (N). Většinou využívá cyklu se dvěmi podmínkami (překročení seznamu a rovnost prvků). Lineární vyhledávání se zarážkou spočívá v nahrazení dvou podmínek jednou. Prvek s požadovanou vložíme za konec seznamu (nárazník) a kontrolujeme pouze rovnost prvků. Na konci pak zkontrolujeme index nalezeného prvku. 38