Portál AbcLinuxu, 10. června 2024 23:54

Octave - 10 (zbylé řídicí struktury)

30. 3. 2006 | Jiří Poláček
Články - Octave - 10 (zbylé řídicí struktury)  

Příkazy break a continue, řídicí struktura výběru z alternativ switch a ošetřování chybových situací.

Řízení běhu programu

Octave podobně jako programovací jazyk Pascal, jehož syntaxe je velmi podobná, obsahuje příkazy break a continue na bezprostřední ukončení aktuálně běžící smyčky cyklu. Vždy se dá program napsat bez použití těchto příkazů, mohou ovšem nastat „zapeklité“ situace, kdy je potřeba upravit složitý algoritmus plný vnořených cyklů a použití těchto příkazů může být relativně elegantním řešením.

Mějme jednoduchý cyklus od jedné do tří, který dvakrát vypíše aktuální hodnotu čítače. Mezi tyto dva výpisy vsuňme test na rovnost čítače číslu 2 a v kladném případě zavolejme příkaz continue:

--[skript preruseni.m]--
for i=1:3
  disp(i);
  if i==2 continue end
  disp(i);
end
--[konec skriptu]--

Příkaz continue předčasně ukončí aktuálně vykonávanou smyčku cyklu – řízení programu předá opět na začátek cyklu. V našem případě se proto nevykoná druhý příkaz disp pro vypsání čítače v případě, kdy nabude hodnoty 2:

>> preruseni
1
1
2
3
3

Nyní nahraďme příkaz continue příkazem break:

--[skript preruseni.m]--
for i=1:3
  disp(i);
  if i==2 break end
  disp(i);
end
--[konec skriptu]--

Příkaz break zajistí okamžité ukončení celého cyklu – žádné další příkazy v těle cyklu se již nevykonají a běh programu se přesune na další příkazy uvedené za cyklem. V našem případě již však žádné nejsou, proto se skript ukončí:

>> preruseni
1
1
2

V souvislosti s příkazem break se někdy můžeme setkat s pojmem cyklus s podmínkou uprostřed. Nejedná se o nic jiného, než o neukončený cyklus, o jehož ukončení se postará break na základě splnění podmínky testované někde v těle cyklu:

while true
  <příkazy cyklu>
  if <podmínka> break end
  <příkazy cyklu>
end

Dodejme ještě, že ve funkcích můžeme použít také příkaz return, který dělá to stejné, co break v cyklech – okamžitě ukončí běh právě vykonávané funkce a předá řízení objektu, který funkci zavolal, tedy jiné funkci či příkazovému řádku.

Výběr z alternativ – řídicí konstrukce switch

V Octave nechybí ani řídící konstrukce switch pro výběr z alternativ, i když její současná podoba je označovaná jako experimentální. Za klíčovým slovem switch následuje výraz, jehož výsledek je pak porovnáván se seznamem možných hodnot uvozovaných klíčovým slovem case. Pokud je nalezen odpovídající případ, provedou se příkazy uvedené v této sekci case. Neodpovídá-li žádný případ výsledku výrazu a je přítomna nepovinná sekce otherwise, provedou se příkazy uvedené v této sekci (analogie else u if). Celá konstrukce je ukončena klíčovým slovem end, respektive endswitch:

--[skript]--
switch nejaka_ciselna_promenna
case 1
  disp('jedna');
case 2
  disp('dva');
case 3
  disp('tři');
case 4
  disp('čtyři');
case 5
  disp('pět');
otherwise
  disp('neznám slovní vyjádření'); 
endswitch
--[konec skriptu]--

Uvedený skript je přepisem příkladu využívajícím řídicí strukturu elseif v odstavci o větvení programu. Porovnáním těchto příkladů zjistíme, že konstrukcí switch si ušetříme zejména zápis relačního operátoru „==“ – od toho ji také programovací jazyky obsahují – a na druhou stranu je snad jasné, že se konstrukce switch nehodí na zkoumání jiných relačních vlastností než je rovnost dvou výrazů.

V Octave mohou být zkoumaný výraz i jednotlivé případy jakékoliv platné výrazy jazyka a navíc lze snadno sdružovat případy, pro které se má vykonat stejný blok příkazů. Nuže mírně složitější ukázka skriptu:

--[skript mutace.m]--
B=[0 1; 0 0];
switch A=fix(rand(2)*2)
case B
  disp('A odpovídá matici B');
case B'
  disp('A odpovídá transponované matici B');
case {rot90(B,1), rot90(B,-1)}
  disp('A odpovídá otočené matici B');
case not(B)
  disp('A odpovídá negované matici B');
case [1 0; 1 0]
  disp('A odpovídá matici [1 0; 1 0]');
otherwise
  disp('matice A vyšla nějak úplně jinak');
end
--[konec skriptu]--

Příklad zkoumá náhodně vygenerovanou matici nul a jedniček oproti nějaké mutaci matice B; všimněme si zejména složených závorek u třetího případu, s jejichž pomocí se dělá výše zmiňované sdružování případů. Pokud znáte konstrukci switch z jiných programovacích jazyků (zejména C, Java), uvědomte si, že v Octave jsou případy exkluzivní, tj. při vyhodnocování se nalezne první odpovídající hodnota, provedou se příkazy příslušné pouze tomuto případu a dále se pokračuje příkazy za koncem řídicí struktury. Případné využívání příkazů break by zde patrně vedlo k neočekávaným výsledkům.

Varování nakonec – obvyklými zkoumanými případy v konstrukci switch jsou konstanty respektive konstantní výrazy. Pokud chceme být varováni u nekonstantních případů, je třeba nastavit interní proměnnou warn_variable_switch_label na nějaké nenulové číslo.

>> warn_variable_switch_label=1  
>> mutace
warning: variable switch label
A odpovídá matici [1 0; 1 0]

Ošetřování chyb

Octave také obsahuje dvě řídicí struktury pro ošetřování chybových situací – jedná se limitované formy převzaté z jazyka Lisp. Obě tyto struktury obsahují dva bloky příkazů oddělené klíčovými slovy, přičemž první z těchto bloků obsahuje v obou případech kritické místo, tj. příkazy, u kterých lze očekávat vyvolání chybové situace. Příkazy v druhém bloku u struktury try-catch se provedou v případě, že v prvním bloku nastala chyba, naopak struktura unwind_protect garantuje, že druhý blok příkazů se provede vždy, bez ohledu na to, zda v prvním bloku příkazů byla či nebyla chybová situace vyvolána. Ošetřit se tak dají dočasné změny globálních proměnných, otevírání souborů apod:

--[skript otevri.m]--
try
  load neexistujici_soubor;
catch
  disp('Daný soubor neexistuje');
end_try_catch
--[konec skriptu]--
>> otevri
Daný soubor neexistuje

Porovnejme s:

unwind_protect
  load soubor
unwind_protect_cleanup
  disp('Tento text se vypíše bez ohledu na existenci souboru');
end_unwind_protect

Namísto funkce disp lze pro vypsání chybových a varovných hlášení využít funkcí error a warning, které k textu přidají prefix „error:“ nebo „warning:“. Funkce error navíc ukončí běh programu, více viz Error Handling.

Seriál Octave (dílů: 16)

První díl: Octave - 1 (je to kalkulačka), poslední díl: Octave - 16 (a co dál?).
Předchozí díl: Octave - 9 (cykly)
Následující díl: Octave - 11 (kreslíme grafy)

Související články

Octave - 1 (je to kalkulačka)
Octave - 2 (počítání s maticemi)
Octave - 3 (přístup k jednotlivým položkám matice)
Octave - 4 (je to pravda?)
Octave - 5 (práce s řetězci)
Octave - 6 (práce se soubory)
Octave - 7 (vlastní skripty a funkce)
Octave - 8 (větvení programu)
Octave - 9 (cykly)
Octave - 11 (kreslíme grafy)
Octave - 12 (měřítko os a speciální grafy)
Octave - 13 (dokončení grafiky)
Octave - 14 (finance a statistika)
Octave - 15 (špetka matematiky)
Octave - 16 (a co dál?)
Vektorový elegán Ipe
Recenze: Kniha kódů a šifer
Awk & sed: Příručka pro dávkové zpracování textu
SETI@home
Jak se píše procesor
GnuCash - domácí účetnictví na úrovni
Použití gnuplot pro tvorbu grafů v PHP
Hra s písmenky - wxMaxima

Odkazy a zdroje

Octave

Další články z této rubriky

LLVM a Clang – více než dobrá náhrada za GCC
Ze 4 s na 0,9 s – programovací jazyk Vala v praxi
Reverzujeme ovladače pro USB HID zařízení
Linux: systémové volání splice()
Programování v jazyce Vala - základní prvky jazyka

Diskuse k tomuto článku

Jiří Poláček avatar 30.3.2006 11:31 Jiří Poláček | skóre: 47 | blog: naopak | Sivice
Rozbalit Rozbalit vše Odkazy do nápovědy Octave
Odpovědět | Sbalit | Link | Blokovat | Admin
Zdá se, že dnešního dne došlo k přesunu webových stránek Octave na adresu http://www.gnu.org/software/octave/ (nikde jsem nenašel zmínku proč), přičemž adresa do webového manuálu již není přímo v adresáři doc, nýbrž v doc/interpreter, z čehož plyne jeden nemilý fakt – přímé odkazy do nápovědy Octave z mých článků nyní prostě nefungují :-(
Sudoku omrzelo? Zkuste bobblemaze! | Statistiky jsou jak bikiny. Napoví hodně, všechno ale neukážou.
30.3.2006 11:38 Robert Krátký | skóre: 94 | blog: Robertův bloček
Rozbalit Rozbalit vše Re: Odkazy do nápovědy Octave
To se dá napravit. Během víkendu se na to podívám.

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.