Předchozí strana Obsah Další strana

2. STRUKTUROVANÉ PROGRAMOVÁNÍ


  1. Datové typy (na úvod)
    1. Datový typ Integer
    2. Datový typ Real
    3. Datový typ Char
    4. Datový typ String
  2. Povolené řídící struktury
    1. Sekvence příkazů
    2. Větvení
    3. Cykly 
      1. Cyklus FOR
      2. Cyklus WHILE
      3. Cyklus REPEAT
  3. Přepínače

Strukturované programování je metodika návrhu algoritmu, která je založena na dvou principech:

  1. Složitou úlohu rozdělíme na dílčí úkoly, které řešíme samostatně a metodou shora dolů propojíme úlohu v jeden celek.
  2. Při návrhu řešení dílčích úloh použijeme pouze povolené řídící struktury, které si rozebereme v následujících podkapitolách.

 

2.1. DATOVÉ TYPY

2.1.1. DATOVÝ TYP INTEGER

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

2.1.2. DATOVÝ TYP REAL

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:

integer --> real:
tato konverze je implicitní: pokud proměnná X typu integer má hodnotu 2 a Y je typu real, po přiřazovacím příkazu Y := X bude mít proměnná Y hodnotu 2.0
real --> integer:
tato konverze implicitní není a proto jsou pro ni zavedeny dvě funkce:

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.

2.1.3. DATOVÝ TYP CHAR

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)

2.1.4. DATOVÝ TYP STRING - ŘETĚZEC

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ů

 

2.2. POVOLENÉ ŘÍDÍCÍ STRUKTURY

2.2.1. SEKVENCE PŘÍKAZŮ

obr01.gif (755 bytes)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.

2.2.2. VĚTVENÍ

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.

obr03.gif (1122 bytes) 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.

 

 


 

obr04.gif (1052 bytes)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

2.2.3. CYKLY

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.

2.2.3.1. CYKLUS FOR

obr05.gif (1650 bytes)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
2.2.3.2. CYKLUS WHILE

while.gif (1002 bytes)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.

2.2.3.3. CYKLUS REPEAT

repeat.gif (1023 bytes)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.

 

2.3. PŘEPÍNAČE

obr02.gif (1889 bytes)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

Předchozí strana Obsah Další strana