Strukturované programování je metodika návrhu algoritmu, která je založena na dvou principech:
Tento datový typ specifikuje konečnou souvislou podmnožinu celých čísel. Umožňuje uživateli využít pět datových typů, které se od sebe liší rozsahem hodnot a tím i použitou velikostí paměti. Přehledná tabulka je v kapitole 3.1.1. DATOVÝ TYP INTEGER, nám však pro začátek postačí vědět, že typ integer má rozsah od -32 768 do 32 767 a zabírá 2 byty (16 bitů). Všechny typy integer jsou použitelné i bez přítomnosti matematického koprocesoru.
Pro hodnoty tohoto typu jsou definovány operace s výsledky rovněž typu integer:
+ | sčítání |
- | odčítání nebo unární operace změny znaménka |
* | násobení |
div | celočíselné dělení (celá část po dělení) |
mod | zbytek po celočíselném dělení (Tato operace pro dva argumenty i mod j je definována takto: je-li j <= 0, nastane při výpočtu chyba. Jinak se i mod j rovná hodnotě i - (k * j) pro takové celé k, pro které je 0 <= i mod j < j |
Operace +, - ,* jsou definovány pro všechny dvojice celých čísel, pokud výsledek leží v intervalu <-Maxint, Maxint>
Další operace, definované nad tímto typem, jsou relační:
= | rovnost |
<> | nerovnost |
< | menší než |
> | větší než |
<= | menší nebo rovno |
>= | větší nebo rovno |
Pokud hodnoty operandů splňují relaci, výsledkem je logická hodnota true (pravda), v opačné případě false (nepravda).
Standardní funkce, definované nad tímto typem (první dvě dávají výsledek typu integer, třetí typu boolean):
abs(i) | zjistí absolutní hodnotu čísla i |
sqr(i) | vypočte druhou mocninu čísla i |
odd(i) | vrátí logickou hodnotu true, pokud je i liché číslo, jinak vrátí logickou hodnotu false |
Tento datový typ specifikuje konečnou podmnožinu reálných čísel. Používá se pro vyjádření hodnot s pohyblivou desetinnou čárkou. V paměti počítače se hodnoty vyjadřují jako dvojice (M,N), kde M je mantisa a N je exponent. Rozsah hodnot typu real je od 2.9*10-39 do 1.7*10+38 a zabírá 6 bytů (48 bitů) v paměti. Další důležité věci si o tomto typu můžete přečíst v kapitole 3.1.6. DATOVÝ TYP REAL.
Pro hodnoty typu real jsou definovány operace s výsledky rovněž typu real:
+ | sčítání |
- | odčítání nebo unární operace změny znaménka |
= | násobení |
/ | dělení |
Dále jsou zde definovány relační operace stejně jako u typu integer a tyto standardní funkce:
abs(x) | absolutní hodnota |
sqr(x) | druhá mocnina |
sqrt(x) | druhá odmocnina |
sin(x) | vypočte sin(x) - argument x je v radiánech |
cos(x) | vypočte cos(x) - argument x je v radiánech |
arctan(x) | vypočte arctan(x) - výsledek je v radiánech |
ln(x) | přirozený logaritmus |
exp(x) | funkce ex |
Konverze mezi datovými typy integer a real:
Následující tabulky uvádějí povolené kombinace argumentů a odpovídající typy výsledků relačních operátorů, aritmetických a standardních funkcí:
a | b | a +, -, * b | a /b | a div, mod b | a =, <>, <, >, <=, >= b |
---|---|---|---|---|---|
integer | integer | integer | real | integer | boolean |
integer | real | real | real | -- | boolean |
real | integer | real | real | -- | boolean |
real | real | real | real | -- | boolean |
a | abs(a), sqr(a) | sin(a), cos(a), arctan(a), ln(a), exp(a), sqrt(a) | odd(a) |
---|---|---|---|
integer | integer | real | boolean |
real | real | real | -- |
Reálná čísla v Pascalu se zapisují ne s desetinnou čárkou, ale s desetinnou tečkou. Také pro exponent se používá neobvyklý zápis: místo 10-13 se používá e-13 nebo E-13. Pak tedy číslo 3,5478*10-14 se zapíše 3.5478E-14.
Je to takový datový typ, jehož hodnotami jsou znaky. Množina hodnot však není definována tímto typem, ale kódem znaků, který je v počítači implementován. Nejčastěji se používá kód ASCII (American Standard Code for Information Interchange), jeho evropská verze ISO a kód EBCDIC (Extended Binary Coded Decimal Information Code).Každý kód však musí splňovat čtyři základní body:
Znaky zapisujeme mezi apostrofy ('A', '5' - POZOR, tento zápis označuje znak 5, nikoliv číslo 5). Pokud chceme zapsat apostrof, musíme jeho zápis zdvojit (vypadá takto: '''').
Také na tomto datovém typu jsou definovány standardní funkce:
ord(x) | vrací ordinální hodnotu znaku x v dané množině znaků (ASCII tabulka, atd.) |
chr(x) | je inverzní funkce k funkci ord, x je hodnota typu integer, výsledkem je příslušný znak |
succ(x) | succ(x) = chr(ord(x) + 1) |
pred(x) | pred(x) = chr(ord(x) - 1) |
V Pascalu je typ řetězec posloupností znaků s počitadlem délky na začátku. Každý řetězec má pevnou velikost (implicitně 255 znaků), i když většinou obsahuje znaků méně. Příklad je zde:
var |
Jmeno: string; |
Titul: string[50]; |
Proměnná Jmeno je řetězcem 255 znaků, proměnná Titul může obsahovat maximálně 50 znaků, může však obsahovat i méně než 50 znaků. Řetězce tohoto typu se zapisují v apostrofech, např.:
'To je vse.' |
'That''s all.' |
Jak je vidět z předcházejícího příkladu, pokud chceme uložit apostrof jakožto znak, musí se tento apostrof zdvojit.
Tento datový typ můžeme také chápat jako pole znaků a s ním jako s datovým typem pole také takto pracovat. K jednotlivým znakům přistupujeme pomocí indexů 1 až 255. V paměti počítače je však řetězec určité délky o jeden znak delší, a to o první znak s indexem 0. Ten totiž (respektive jeho ASCII kód) udává délku řetězce.
Nad tímto typem existuje několik standardních operací a funkcí, které uvedeme v tabulce:
lenght (ret) | vrací dynamickou délku řetězce ret, výsledek je typu word |
copy (ret, poz, poc) | vrací podřetězec o délce poc, obsažený v řetězci ret, od stanovené pozice poz |
concat (ret1, ret2, ... , retn) | vrací spojení uvedených řetězců (obvykle se ale používá +) |
pos (podret, ret) | vrací pozici prvního výskytu podřetězce podret v řetězci ret, výsledek je typu word; při neúspěšném hledání vrací hodnotu 0 |
delete (ret, poz, del) | vymaže podřetězec ret délky del, začínající na pozici poz |
insert (podret, ret, poz) | vloží podřetězec podret do řetězce ret od pozice poz |
str (cis, ret) | převede číselnou hodnotu cis do řetězcové proměnné ret |
val (ret, prom, typ) | převede řetězcovou proměnnou ret na číselnou proměnnou prom, ppřeváděný řetězec může obsahovat pouze číslice, desetinnou tečku, znaménka a písmena e, E (inverzní procedura k str) |
+ | zřetězení dvou řetězců, výsledkem je opět řetězec; pokud je výsledný řetězec delší než 255 znaků, je zkrácen na délku 255 znaků |
Sekvencí příkazů rozumíme určitou skupinu příkazů (na
obrázku představovanou příkazy Příkaz 1, Příkaz 2 a Příkaz 3), které se
vykonávají za sebou - sekvenčně. Příkazem může být libovolný příkaz, který
neporuší sekvenci příkazů, nebo libovolná povolená řídící struktura.
Někdy však pravidla jazyka Pascal dovolují, aby se v některých konstrukcích použil je jeden příkaz (takovou konstrukcí je např. cyklus), my však potřebujeme v jediné smyčce cyklu použít více příkazů, dá se tento problém vyřešit tzv. složeným příkazem. Složený příkaz vytváří ze sekvence příkazů jeden příkaz. Jeho zápis v Pascalu vypadá následovně:
begin |
Příkaz 1; |
Příkaz 2; |
... |
Příkaz K |
end |
Poznámka: Za poslední příkaz před vyhrazené slovo end se středník nepíše, avšak i když jej použijete, v podstatě se nic neděje, není to chyba. Pouze jste vytvořili prázdný příkaz.
Větvením programu můžeme rozumět jako výběru mezi několika variantami následujících příkazů na základě splnění nebo nesplnění určité podmínky výběru. Toto větvení nám v Pascalu zajišťují příkazy if a case. Zde si vysvětlíme příkaz if a v podkapitole Přepínače příkaz case.
Schéma, umístěné nalevo od tohoto textu, nám popisuje tzv. neúplný
příkaz if. V pascalském zápisu vypadá takto:
if Podmínka then Příkaz1 ; |
a provede se tak, že se nejprve vyhodnotí podmínka za příkazem if a pokud má hodnotu true, provede se Příkaz1, pokud má hodnotu false, neprovede se nic, příkaz je bez účinku.
Toto schéma nám popisuje úplný příkaz if.
Ten, narozdíl od neúplného, řeší možnost vykonání příkazu i tehdy, jestliže
hodnotou vyhodnocení podmínky je false. V Pascalu vypadá tento
příkaz takto:
if Podmínka then Příkaz1 |
else Příkaz2 ; |
a vykoná se tak, že se nejprve vyhodnotí podmínka za
příkazem if, pokud má hodnotu true, vykoná se
Příkaz1 a pokud má vyhodnocená podmínka hodnotu false, provede se
Příkaz2.
Za vyhrazenými slovy then a else (if, then,
else se nazývají vyhrazená slova, stejně jako begin,
end, a další) nemusí stát pouze jeden příkaz, ale i více
příkazů, musí však být uzavřeny do složeného příkazu begin - end.
Příkladem může být část programu, ve které je jasně vidět význam obou příkazů:
if (a > b) then a := a - b |
else b := b - a ; |
if (a > c) then |
begin |
s := s + a ; |
z := z * c |
end |
else c := c - a ; |
if (a > d) then s := s + a |
else begin |
a := -a ; |
z := z + 1 |
end ; |
Příkazy cyklů nám umožňují opakování příkazů nebo sekvencí příkazů vícekrát. Jazyk Pascal nabízí tři druhy cyklů: cyklus řízený proměnnou: for a cykly řízené splněním či nesplněním podmínky: while a repeat.
Tento cyklus se používá pro daný konečný počet
opakování určitého příkazu nebo sekvence příkazů. Počet opakování je dán tzv.
řídící proměnnou, která musí být ordinálního typu (typu integer) a musí být
deklarována v té části programu, ve které se používá.
Cyklus for se používá ve dvou tvarech:
for ridici_prom := pocatecni_hodn to koncova_hodn do |
begin |
Prikaz1 ; |
Prikaz2 ; |
... |
PrikazN ; |
end; |
a
for ridici_prom := pocatecni_hodn downto koncova_hodn do |
begin |
Prikaz1 ; |
Prikaz2 ; |
... |
PrikazN ; |
end; |
Rozdíl mezi oběma formami zápisu je pouze v tom, že v prvním případě se hodnota řídící proměnné zvyšuje od počáteční hodnoty ke koncové hodnotě o jedničku při každém opakování, kdežto ve druhé případě se hodnota řídící proměnné snižuje od počáteční ke koncové hodnotě o jedničku při každém opakování. Aby měl cyklus smysl, počáteční hodnota musí být v prvním případě menší nebo rovna než koncová hodnota. Ve druhém případě musí být větší nebo rovna než koncová hodnota.
A příklad:
for rp := 1 to 10 do |
begin |
pole[rp] := 15 * rp ; |
a := 10 + rp / 2 ; |
end; |
Tento cyklus se používá v těch případech, kdy neznáme
přesný počet opakování. Je řízen oproti cyklu for podmínkou
(výrazem typu Boolean), jejíž splnění má za následek opětovné provedení
vnořeného příkazu nebo příkazů. Nesplněním této podmínky se cyklus přeruší.
V Pascalu má tento cyklus tvar:
while Podminka do Prikaz ; |
a vykonává se takto: nejprve se vyhodnotí logická Podmínka, je-li výsledkem hodnota true, provede se příkaz Příkaz a opět se vyhodnocuje podmínka tak, jak to ukazuje obrázek vlevo. Pokud je opět hodnotou true, opět se provádí Příkaz a tak to jde pořád dokola. V okamžiku, kdy hodnotou podmínky je false, cyklus končí. Z toho vyplývá, že cyklus nemusí proběhnout ani jednou, a to pokud hned v prvním průchodu cyklem je hodnotou logické podmínky hodnota false.
Pokud chceme v těle cyklu vykonávat více příkazů, musíme je uzavřít do složeného příkazu pomocí begin - end.
Tento druh cyklu se také používá v případech, kdy neznáme
přesný počet opakování. Je také řízen podmínkou (výrazem typu Boolean),
avšak oproti předchozímu cyklu je opětovné provádění cyklu zajištěno nesplněním
podmínky Podmínka. V Pascalu má cyklus tvar:
repeat |
Příkaz; |
until Podmínka ; |
a vykonává se takto: nejprve se provede příkaz Příkaz a poté se vyhodnocuje logická Podmínka. Pokud má hodnotu false (POZOR ! NE TRUE - jako u while), cyklus se opakuje a opět se provádí Příkaz a poté se opět vyhodnocuje Podmínka. Pokud má podmínka hodnotu true, cyklus skončí. Z toho vyplývá, že cyklus proběhne vždy alespoň jednou.
Změnou oproti předchozímu cyklu je to, že pokud chceme v těle cyklu vykonávat více příkazů, nemusíme je uzavírat mezi begin - end, neboť sám příkaz repeat - until nám mezi těmito dvěma vyhrazenými slovy nabízí dost místa pro spoustu příkazů, které chceme provést.
Přepínač umožňuje také větvit strukturu programu,
podobně jako příkaz if, pouze s tím rozdílem, že přepínač může
volit mezi několika (tedy dvěma i více) variantami na základě vyhodnocení podmínky.
V jazyce Pascal je tímto přepínačem příkaz case.
Obrázek vpravo ukazuje, jak vypadá vývojový diagram tohoto příkazu, v Pascalu vypadá příkaz case následovně:
case Podminka of |
Vysledek1 : Prikaz1 ; |
Vysledek2 : Prikaz2 ; |
Vysledek3 : Prikaz3 ; |
... |
... |
VysledekN : PrikazN |
else |
PrikazP |
end; |
a zrealizuje se tak, že se nejprve vyhodnotí Podmínka za slovem case a potom se vykoná příkaz PříkazX předznačený hodnotou VysledekX, která se rovná hodnotě, získané vyhodnocením Podmínky. Nesmíme zapomenout na jednoznačnost předznačení příkazů, aby byla zaručena jednoznačnost celého příkazu case. Jinak řečeno: VysledekX musí být různý od VysledekY pro každé X různé od Y. Naproti tomu Pascal připouští i předznačení příkazu PříkazX i několika různými hodnotami VysledekY. Navíc platí i další podmínky. Podminka musí být ordinálního typu, dále část else není povinná, a také příkaz PrikazX může být i několik příkazů, avšak opět uzavřených mezi begin a end.
A malý příklad:
case den of |
pondeli .. patek : writeln('Tento den je pracovni den.') ; |
sobota : writeln('Tento den je sobota.') ; |
else |
writeln('Tento den je nedele.') ; |
end; |