DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
Cykly – Intermezzo Rozhodl jsem se za adit do série n kolika lánk o základech programování v Delphi/Pascalu malou vsuvku, která nám pom že pochopit principy a zásady p i používání tzv. cykl . Mnoho ástí i jednoduchých algoritm používá práv této „opakující se“ struktury. Pokud z staneme v teoretické rovin , m žeme hovo it o dvou základních druzích cykl , které m žeme využít. Pokud budeme obecn hovo it o cyklických strukturách, mohli bychom najít i celou adu dalších struktur, které využívají možnosti opakování. (Tady bych za adil použití tzv. náv stí - LABEL, nebo také využití tzv. rekurzivního volání procedury nebo funkce. Tato témata ovšem rozhodn nepat í do základního kurzu programování.) Cykly, o kterých si budeme povídat, najdeme v defini ní struktu e Delphi celkem t i: • While - do • Repeat - until • For – do Obecn lze tyto cykly také rozd lit podle toho, zda p i použití p edem známe po et opakování, totiž že ho také sami volíme (cyklus FOR), nebo p edem po et opakování neznáme a závisí na ur ité podmínce (WHILE a REPEAT). Cyklus se tedy opakuje tak dlouho, dokud platí ur itá podmínka zadaná ze strany programátora. Oba zp soby nalézají uplatn ní v programování, lze ovšem íct, že první skupinu vždy mohu nahradit druhou a ne naopak, jinými slovy, vždy mohu cyklus FOR nahradit cyklem nap íklad WHILE, obrácen to ovšem nejde vždycky.
FOR cyklus Tento cyklus je asi nejjednodušší a použijeme ho všude tam, kde máme jasn daný po et opakování. Typickým p íkladem pro použití tohoto cyklu je nap íklad práce s tzv. polem, (S tímto datovým typem se seznámíme v další lekci.) což by se do praxe dalo p evést jako práce s n jakou maticí nebo vektorem. Abychom se v tuto chvíli mohli s použitím cyklu seznámit, volím úpln jiný p íklad a zkusím vypsat na obrazovku posloupnost ísel 1 – 10. Bez použití cyklu bych mohl napsat takovouto ást programu: writeln(1); writeln(2); writeln(3); writeln(4); writeln(5); writeln(6); writeln(7); writeln(8); writeln(9); writeln(10);
Kdybych dostal za úkol vypsat adu ísel 1 – 1000, bylo by to pro m ur it dost nepohodlné… Proto zvolím ješt jiný zp sob a použiji cyklus. V tomto p ípad p edkládám celý program, aby bylo patrné, že jsem pro tuto pot ebu musel ješt navíc deklarovat prom nou i:
1
DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
program CyklusApp; {$APPTYPE CONSOLE} uses SysUtils; Var i: integer; BEGIN for i:= 1 to 10 do writeln(i); readln; END.
Cyklus FOR p i azuje po jedni ce do prom nné i postupn hodnoty 1-10. Za p íkazem DO následuje p íkaz, který se má vykonat. Jestliže by bylo zapot ebí provést v cyklu více p íkaz , uzav ou se do bloku begin – end: for i:= 1 to 10 do begin write('Vypisuji cislo: '); writeln(i); end;
Obr. 0-1 Výsledek použití cyklu FOR.
Abych tuto strukturu popsal kompletn , je t eba p iznat, že cyklus nemusí opakovat provedení ur itých p íkaz programu vždy od menšího ísla k v tšímu, ale také naopak, nap íklad od 10 do 1, což by se dalo v programu zapsat nap íklad takto: for i:= 10 downto 1 do begin write('Vypisuji cislo: '); writeln(i);
2
DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
end;
Obr. 0-2 Obrácený cyklus FOR
WHILE cyklus Všude tam, kde p edem není jasný po et opakování, m žeme použít tento cyklus. Za p íkazem WHILE vždy následuje podmínka, která ur uje, kolikrát nebo jak dlouho se bude cyklus opakovat, p estože p edem nejsme schopni íci, kolik takových opakování bude. V tomto sm ru m žeme snadno sklouznout do ošemetné situace, kdy se program tzv. zacyklí, což znamená, že nikdy nebude dosažena podmínka, která by cyklus ukon ila, jinak bych mohl íct, že podmínka, za které se provád jí p íkazy v cyklu, bude platit vždy a nikdy se nezm ní. Je tedy d ležité podmínce v novat pozornost obzvlášt v p ípad , že s programováním za ínáme. Následovat by m l p íkaz DO a za ním jeden, nebo skupina p íkaz , které se v cyklu mají provád t. Hned na úvod si m žeme ukázat, když jsem o tom už v p edcházejících odstavcích mluvil, jakým zp sobem tedy nahradíme FOR cyklus cyklem WHILE jen proto, abychom si ukázali správnou syntaxi, tedy zápis, v programovém jazyce: i:= 1; while i<=10 do begin write('Vypis pomoci WHILE cyklu, cislo: '); writeln(i); i:= i+1; end;
3
DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
Obr. 0-3 Výpis ady ísel pomocí WHILE cyklu
Oproti cyklu FOR musím sám zvyšovat hodnotu prom nné i, takže za výpisem ísla následuje ješt ádek s p íkazem, se kterým se jako programátor setkáte asto, kdy do prom nné p i azuji její stávající hodnotu a navíc zvyšuji o jinou hodnotu, v tomto p ípad o jedni ku. Což bych mohl také nahradit procedurou inc(i): i:= i+1;
Dokud bude spln na podmínka cyklu, že hodnota prom nné i bude menší nebo rovna 10, bude se provád t blok p íkaz v cyklu. Navíc se v cyklu hodnota prom nné zvyšuje, což je pro tento p íklad dost podstatné. Kdybych tento p íkaz vynechal, hodnota prom nné by se nem nila a podmínka by platila vždy a nikdy by nedošlo k ukon ení cyklu! Program by tzv. „zamrzl“. Tento p íklad p íliš neprezentuje výhodu tohoto cyklu. Zatím jsme si jen ukázali, jak bychom jej mohli použít z hlediska zápisu. Podívejme se nyní na jiný p íklad, kdy budeme chtít vždy s ítat dvojici stejných ísel a to tak dlouho, než bude sou et v tší než 10. ekn me, že použijeme prom nnou i, kterou budeme od 1 zvyšovat, dokud sou et i+i nebo sou in 2 * i nebude v tší než deset. Samoz ejm si m žeme p edem spo ítat, kolik opakování program provede, ale berme úlohu také z pohledu uživatele, který by si mohl limitní výsledek sou tu (u nás 10) libovoln zvolit. Tuto úlohu bychom mohli zapsat t eba takto: program CyklusApp; {$APPTYPE CONSOLE} uses SysUtils; Var i: integer; Function MySUM(x: integer ): integer; begin MySUM:= x+x; end;
4
DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
BEGIN i:= 1; while MySUM(i) <= 10 do begin write('Cislo: '); writeln(i); write('Soucet je: '); writeln(MySUM(i)); i:= i+1; end; readln; END.
P estože uplatn ní tohoto p íkladu je tém nulové, názornost použití jednak cyklu, jednak funkce je z ejmá: Použil jsem funkci, která k uvedenému íslu p i te totéž íslo, tak jak bylo požadováno v zadání. Funkci jsem použil v podmínce, která udává, za jakých okolností se blok cyklu má provád t, totiž do té doby, dokud bude výsledný sou et menší nebo práv roven deseti. Pro názornost v bloku cyklu vypisuji, jaké íslo je vstupním parametrem funkce a jaký je výsledek sou tu. Samoz ejm nesmím zapomenout prom nnou i vždy v bloku cyklu zvýšit, abych zajistil kone né ešení, tedy výsledek, který již podmínce nebude vyhovovat:
Obr. 0-4 Výsledek použití WHILE cyklu
Když si p edstavíme hodnotu i = 6, potom je z ejmé, že dvojnásobek této hodnoty už bude v tší než deset, cyklus se dále provád t nebude a program bude pokra ovat dál na ádku: readln;
REPEAT cyklus Podobn jako v p edchozím p ípad m žeme tento cyklus použít i všude tam, kde p edem neznáme po et opakování, ale víme, že díky ur ité podmínce má algoritmus kone né ešení, tedy po et cykl , které se provedou, je kone ný. Na rozdíl od cyklu WHILE, kdy jsme psali 5
DELPHI Cykly – intermezzo
Ing. Jaroslav Halva
podmínku hned na za átku, tedy ješt p edtím, než jsme programu definovali blok p íkaz , které se budou cyklicky opakovat, je tomu v tomto p ípad naopak: Cyklus nejprve provede první ást bloku, než dojde k vyhodnocení podmínky. Tato vlastnost se v programování m že hodit a je to také zp sob, pro máme obecn možnost rozhodnout mezi WHILE a REPEAT cyklem. Abych rozdíl ješt více oz ejmil, navrhnu podmínku v tomto cyklu tak, abych dosáhl stejného výsledku. Porovnáním obou podmínek je také z ejmé využití jednoho nebo druhého cyklu a také možnost jejich zám ny. (Alespo v n kterých p ípadech…) program CyklusApp; {$APPTYPE CONSOLE} uses SysUtils; Var i: integer; Function MySUM(x: integer ): integer; begin MySUM:= x+x; end; BEGIN i:= 1; repeat write('Cislo: '); writeln(i); write('Soucet je: '); writeln(MySUM(i)); i:= i+1; until MySUM(i) > 10; readln; END.
Op t ponechávám definovanou funkci, kterou využívám jednak ve výpisu, jednak v podmínce. Ta musí být ovšem zapsána jako negace p edešlé podmínky, aby výsledek byl stejný. Cyklus se opakuje až do (until) podmínky, kdy výsledek už je v tší než deset. Pak se cyklus ukon í. Záv rem bych ekl jen jedno: Záleží na okolnostech, pro který z popisovaných cykl se rozhodnete. Obecn platí, že cyklus FOR je zastupitelný ob ma z dále uvedených a navíc i tyto se mezi sebou dají zam nit. Existují ovšem p ípady, kdy je vhodné rozhodnout se konkrétn pro ten i onen cyklus. Ale na to už musíte p ijít sami. Chce to jenom programovat, programovat a zase programovat…
6