Popis problému:
V některých případech, zvláště při počáteční inicializaci nebo zápisu inicializačních hodnot je nezbytné tyto hodnoty kopírovat z kódové paměti automatu. V případech kdy je třeba kopírovat pole hodnot je vcelku výhodné použít ekvivalent příkazu FOR např. z jazyka C. Tento příkaz realizuje cyklus, který je dán počáteční hodnotou, koncovou hodnotou proměnné index a hodnotou o níž se proměnná indexu zvětšuje každým průchodem smyčky.
Jaká jsou omezení dotyčného řešení:
Omezení popisovaného řešení vycházejí z principu programování automatů Micropel. Program by měl inicializovat všechny nezbytné části v okamžiku, kdy je nastaven bit reset. To znamená, že i ekvivalent příkazu FOR musí tuto podmínku respektovat a musí považovat průchody s nastavenou proměnnou reset za inicializační. Na druhou stranu je ale možné bit reset využít k inicializaci vnitřních a pomocných proměnných pro realizaci tohoto příkazu. Druhé omezení spočívá v tom, že musíme respektovat opatrnou práci s proměnnou index, kterou nastavujeme pro spuštění cyklu a současně ji modifikuje ekvivalent příkazu FOR. S touto manipulací souvisí i to, že musíme mít pro každé použití cyklu FOR deklarovanou separátní proměnnou index.
Řešení:
pro verzi StudioWin 7.400 a vyšší
Příkaz FOR budeme realizovat jako funkci pro případ indexu typu word podle následující deklarace:
function bit for(var word index, word od, word do)
Funkce bude vracet hodnotu (1) TRUE tehdy, pokud bude cyklus spuštěn, hodnotu 0 (FALSE) pokud cyklus doběhl nebo pokud dochází k inicializaci v důsledku nastaveného bitu reset. Dále nebudeme pro jednoduchost uvažovat obecný krok modifikace proměnné index, ale budeme používat krok s jednotkovou velikostí. Tělo funkce FORbude vypadat takto:
function bit for(var word index, word od, word do) var bit bezi ; pomocný bit pro řízení stavu cyklu for při rozběhu if reset then begin bezi = 0 ; v případě že je reset, ukončí se funkce index = od ; inicializace indexu exit 0 end if index > do then begin exit 0 ; nebo index je > než do, ukončí se funkce end if index = od and bezi = 0 then begin bezi = 1 ; pokud je index = od, ; tj. inicializační hodnota exit 1 ; pak se tato hodnota nemění ; a cyklus se rozběhne end index = index + 1 bezi = 0 ; první průchod cyklem proběhl if index <= do then begin exit 1 ; cyklus běží end return 0 ; cyklus ukončen
Jak je zřejmé ze zdrojového textu, funguje funkce FOR i pro takzvané předčasné ukončení cyklu tím, že nastavíme index na hodnotu větší než je mez do. Tak ukončíme cyklus nezávisle na počtu provedených kroků.
Použití:
Použití funkce FOR v programu je pak již jednoduché. Uveďme příklad kopírování 10 wordů z kódové paměti na zásobník od pozice 1000.
code word hodnoty[10] = (0,1,2,3,4,5,6,7,8,9) var word index const od = 0 const do = 9 const stack_zacatek = 1000 if for(index,od,do) then begin pointer = stack_zacatek + index Stack(hodnoty[index]) ; index se inicializuje unvitř ; funkce for v okamžiku kdy reset = 1 exit ; cyklus neskončil a proto ukončíme vykonávání end ; hlavní smyčky ; do tohoto mista prijde program nejprve při reset = 1, ; a pak až po deseti průchodech cyklem for ; další program reset = 0 end
Jak je vidět z uvedeného zdrojového kódu, příkaz FOR je možné umístit v kódu vícekrát, aniž by to způsobilo nějaký problém. Pokud bychom chtěli vykonávat cyklus FOR jako součást programu a ne pouze jako inicializaci, je nutné po dosažení konce programu inicializovat všechny použité proměnné index. Situaci ukazuje následující kód
; index první smyčky var word index_0 const od_0 = 0 const do_0 = 18 ; index druhé smyčky var word index_1 const od_1 = 10 const do_1 = 28 ; první smyčka if for(index_0,od_0,do_0 ) then begin ; kód první smyčky for exit end ; pokračování programu ; druhá smyčka if for(index_1,od_1,do_1 ) then begin ; kód druhé smyčky for exit end ; dokončení programu index_0 = od_0 index_1 = od_1 reset = 0 end
Je zřejmé, že meze pro cyklus nemusí být pouze konstanty. Můžeme předávat samozřejmě i proměnné, nicméně musíme dávat dobrý pozor na jejich inicializaci. Jakmile totiž vynulujeme bit reset, cykly FOR začnou nemilosrdně běžet a inicializace mezí je pak problematická. V případě, že používáme pro meze proměnné, je vhodné provést jejich inicializaci hned na začátku kódu v klasické podmínce if reset then....
|