Stránky neboli dlhú dobu aktualizované. Môžu obsahovať nepresné alebo neaktuálne informácie.
Hľadanie
Rozšírené vyhľadávanie
TOP 7 - stránky
Napaľovacie programy - 108 202x
Free Pascal - Úvod - 65 907x
Lazarus - Kreslenie - 47 466x
Free Pascal - Začiatky - 44 754x
Free Pascal - Podmienky - 37 110x
Free Pascal - Cykly - 36 357x
Internetové prehliadače - 36 217x
Nové v diskusii
Free Pascal - Cykly - štvrtok 31.3.
Lazarus - Začíname - piatok 25.3.
Anketa - streda 2.3.
Navigácia: Programovanie > Free Pascal - Chyby a výnimky

Free Pascal - Chyby a výnimky

Dnes si ukážeme, ako zápasiť s chybami v našich programoch - veď takmer žiaden program nie je bezchybný. Taktiež sa zoznámime s mechanizmom výnimiek vo Free Pascale.

Syntaktické chyby

V prvom rade si musíme vysvetliť, aké typy chýb poznáme.

Syntaktické chyby sú spôsobené napísaním zdrojového kódu, ktorý nie je možné skompilovať (vytvoriť z neho program). Tu je jednoduchý príklad:

program synt;
begin
 writenl; // preklep
end.

Free Pascal nám v spodnej časti okna vypíše:

synt.pas(3,9) Error: Identifier not found "writenl"

Riešenie býva jednoduché - opravíme preklep, pridáme potrebnú jednotku (unit), skontrolujeme zabudnuté i prebytočné bodkočiarky,...

Logické chyby

Chyby, ktoré nastanú až počas behu programu, sa opravujú o čosi ťažšie. Dajme tomu, že chceme x-krát vypísať slovo získané od užívateľa (upozorňujem, že tento kód je chybný):

program logch;

procedure vypis;
var
 slovo: string;
 i: integer;
begin
 writeln('Napiste slovo.');
 readln(slovo);
 writeln('Zadajte pocet opakovani.');
 readln(i);
 while i >= 0 do begin
  write(slovo, ' ');
  dec(i);
 end;
end;

begin
 vypis;
 readln;
end.

Ak aplikáciu spustíme, zistíme, že dané slovo sa vypíše vždy o 1-krát viac. V takomto jednoduchom programe nájdeme chybu za pár sekúnd, ale predstavte si, že váš program obsahuje mnoho procedúr a každá je niekoľkokrát dlhšia a zložitejšia ako táto. Vtedy prichádza na rad tzv. debugovanie - hľadanie chýb špecializovanými metódami pomocou programu nazvaného debugger.

Debugging

Jednou z týchto metód je krokovanie (nazývané aj trasovanie) - prechádzame kódom spustenej aplikácie príkaz po príkaze a pritom sledujeme, čo sa deje.

Stlačením F8 (alebo Run / Step over) spustíme program v debug-režime. Ďalším stlačením F8 preskočíme riadok so slovom begin. Farebný prúžok ukazuje, že sa ideme vykonať procedúru vypis. Teraz stlačíme F7 (resp. Run / Trace into), pretože sa chceme vnoriť do vnútra tejto procedúry a sledovať jej priebeh. Ďalším stláčaním F8 prechádzame kódom a vykonávame príkazy. Ak chceme vidieť aktuálny výstup programu, môžeme kedykoľvek použiť známu skratku Alt+F5.

Ak nám to nestačí, môžeme pritom sledovať obsah premenných. Dáme kurzor na názov premennej, ktorú chceme sledovať (v našom prípade i) a zvolíme menu Debug / Add Watch (Ctrl+F7). V okne Watches sa bude zobrazovať aktuálna hodnota vždy, keď je program zastavený a daná premenná je dostupná. Sledovanie môžeme zrušiť pomocou kontextového menu.

Free Pascal - Debugging

Pokiaľ je prechádzanie programom príkaz po príkaze zdĺhavé, máme možnosť vytvoriť body zastavenia - tzv. breakpointy. Breakpoint na aktuálny riadok nastavíme (alebo odstránime) cez menu Debug / Breakpoint (Ctrl+F8). Aplikáciu spustíme ako zvyčajne (Ctrl+F9). Keď vykonávanie programu dôjde na dané miesto, zastaví sa a my môžeme napr. sledovať premenné. Keď chceme, aby program pokračoval ďalej až po najbližší breakpoint, stlačíme Ctrl+F9. Ak chceme program trasovať, použijeme skratky F7 a F8 ako zvyčajne.

Z ďalších možností, ktoré môžeme využívať, keď je program zastavený, spomeniem vyhodnocovanie výrazov (funkcií, matematických operácií a pod.) cez menu Debug / Evaluate (Ctrl+F4). Tu si však treba dať pozor - výrazy môžu mať vedľajšie efekty. To znamená, že ak zadáte inc(i), hodnota premennej i sa naozaj zmenší o 1.

Call Stack (Ctrl+F3) zobrazuje, v akej procedúre sa momentálne nachádzame a z ktorej procedúry sme sa tu dostali. Pre pokročilých je tu ešte disassembler (Debug / Disassemble), sledovač registrov procesora a GDB konzola.

Chybu ste iste našli - tu je opravený riadok:

while i > 0 do begin

Výnimky

Na to, aby sa program „zotavil“ z neočakávanej udalosti (väčšinou z chyby), sa používa mechanizmus výnimiek. Vezmime si jednoduchú aplikáciu, ktorá zobrazí celočíselný podiel dvoch čísel:

program vynimky;
var
 delenec, delitel, podiel: integer;
begin
 write('Delenec: ');
 readln(delenec);
 write('Delitel: ');
 readln(delitel);
 podiel := delenec div delitel;
 writeln('Celocis. podiel: ', podiel);
 readln;
end.

Poviete si: program sa bez problémov skompiluje, je aj logicky správny, takže máme po starostiach. Skúste však ako deliteľ zadať nulu. Alebo skúste miesto čísel napísať písmená. Program sa ukončí chybou a Free Pascal vypíše stavový kód. To však v bežnej aplikácii určite nechceme dosiahnuť. Preto použijeme mechanizmus výnimiek. Aby sa nasledujúci kód dal skompilovať, je nutné „Options / Compiler / Syntax / Compiler mode“ nastaviť na „Object Pascal extension on“.

program vynimky;
uses
 SysUtils;
var
 delenec, delitel, podiel: integer;
begin
 write('Delenec: ');
 try
  readln(delenec);
  write('Delitel: ');
  readln(delitel);
  podiel := delenec div delitel;
  writeln('Celocis. podiel: ', podiel);
 except
  writeln('Vyskytla sa chyba!');
 end;
 readln;
end.

Ak sa vyskytne výnimka (chyba) medzi slovami try a except, všetky nasledujúce príkazy, až po except, sa preskočia a vykoná sa kód medzi slovami except a end;. Ak sa výnimka nevyskytne, kód medzi except a end; sa nevykoná.

Pokiaľ chceme rozdielne zareagovať na rôzne typy výnimiek, použijeme syntax on Premenná: TypVýnimky do príkaz;:

...
except
 on EDivByZero do
  writeln('Nulou predsa nedelíme!');
 on E: EInOutError do begin
  write('Nesprávny vstup/výstup. ');
  writeln(E.Message);
 end;
 else
  writeln('Iná chyba.');
end;
...

Ak bola vyvolaná chyba typu EDivByZero, vypíše sa horeuvedená hláška. Keď zadáme na vstup písmená miesto čísel, vytvorí sa premenná E typu EInOutError, z ktorej potom získame chybovú správu (E.Message). Pokiaľ vyvolaná výnimka nie je ani jedného z uvedených typov, zobrazí sa hláška „Iná chyba“.

Zaručené vykonanie

Keď chceme, aby sa nejaké príkazy (napr. uvoľnenie prostriedkov) vykonali za každú cenu, či už bola alebo nebola vyvolaná výnimka, nebezpečný kód napíšeme za slovom try a príkazy, ktoré sa majú bezpodmienečne vykonať, za slovo finally - asi takto:

Rewrite(subor);
try
 write(subor, 'data');
finally
 CloseFile(subor);
end;

Ako výnimky fungujú

Výnimka je v podstate trieda, väčšinou odvodená od triedy Exception. To znamená, že pomocou dedičnosti môžeme vytvárať vlastné typy výnimiek s rozličnými vlastnosťami a metódami. Avšak táto možnosť sa v bežných aplikáciách až tak často nevyužíva.

Skúsme teda aspoň manuálne vyvolať výnimku. Poslúži nám kľúčové slovo raise.

raise EMathError.Create;

Ak nie je výnimka priamo zachytená v bloku try-except, postupuje ďalej k procedúre, z ktorej bola volaná aktuálna procedúra. Ak nie je zachytená ani tam, postup sa opakuje, až kým sa nedostane na najvyššiu úroveň (medzi begin a end s bodkou). Vtedy sa program ukončí chybou.

Hodnotenie
1 2 3 4 5 (ako v škole)
Priemerná známka: 3,26
Diskusia k tejto stránke Príspevok na túto tému zatiaľ neexistuje. Môžete pridať prvý z nich!
Prejsť do diskusie»
2005-2012, Matúš Sulír, matus.sulir (zav) gmail bodka com. Gen.: 0,0214 s. Valid XHTML, CSS.