16. Větvení v programu

Podmínka (condition)

je logický výraz, jehož hodnotou je pravda nebo nepravda. Říkáme, že podmínka platí nebo neplatí.

Základní relační operátory jsou <,>,=,<=,>=,<>.
Ve výrazu lze použít proměnné, konstanty i kulaté závorky. Obecně v podmínce může být výraz vlevo i vpravo, navíc se dají sestavovat složené podmínky pomocí logických spojek. Toho si ale užijete až v konkrétním programovacím jazyce.
Sémantika je následující:
Nejprve se vyhodnotí podmínka. Pokud platí, provede se příkaz (nebo více příkazů) uvedený ve větvi označené symbolem +. Pokud podmínka neplatí, provede se příkaz (nebo více příkazů) uvedený ve větvi označené symbolem -. Příkazem uvnitř může být přiřazovací příkaz, vstup nebo výstup dat i další podmíněný příkaz. V posledním případě mluvíme o složeném podmíněném příkazu nebo prostě o podmínce v podmínce. Jedna z větví v rozhodovacím bloku může být prázdná, neobsahuje žádný příkaz. Obvykle se jedná o větev označenou -. Takový podmíněný příkaz nazýváme neúplný. Úplný podmíněný příkaz má v každé větvi alespoň jeden příkaz.

Příklad několika podmínek:
a=0
b>=0
i=10
n<100
s>2*(i+j)
j<>0

Nyní se podíváme na podmínky složené – ty vznikají z jednoduchých pomocí logických spojek.
Jednodušší podmínky pak ovšem musíme závorkovat!!!!
Tabulka logických spojek (jen těch nejjednodušších):

Pro úplnost  i jejich český překlad (i když anglicky máte umět) : and = a současně, or=nebo.

Operátor Význam
  And   Pokud platí obě podmínky
  Or   Pokud platí alespoň jedna podmínka
  Xor   Pokud platí pouze jedna podmínka
  Not   Pokud podmínka neplatí

Příklad:

var cislo: integer;
begin
cislo := 5;
if (cislo >= 2) and (cislo < 4) then write(‚Ahoj‘);
if not (cislo = 1) then write(‚Cislo neni jedna‘);
end.

Jak vidíme, ahoj se nevypíše, protože podmínka splněna není. Pozor! Podmínky je nutné uzavírat do závorek, jinak by to bylo bráno jako bitová operace s čísly, ale tím se teď zabývat nebudu. Operátor not znamená negaci, tzn. že zápis „not (cislo = 1)“ znamená to samé jako „cislo <> 1„. Podmínky lze utvářet i složitější a to pomocí závorek:

var cislo: integer;
begin
cislo := 5;
if ((cislo > 2) and (cislo < 7)) or (cislo = 10) then write(‚Ahoj‘);
end.

Ahoj se tedy vypíše, pokud je „cislo“ větší než 2 a menší než 7, nebo je 10. 


Postup při zpracování podmínky

Pro podmínky se v Pascalu používají klíčové příkazy IFTHEN a ELSE a CASE. Také se jim říká „příkazy větvení“. Seznámíme se s novým datovým typem a tím je boolean. Proměnné tohoto typu nabývají pouze dvou hodnot – true/false – pravda nebo nepravda. Příkaz IF taky nemusí mít else, potom se mu bude říkat „neúplný příkaz if“. Častá chyba : Před ELSE nesmí být středník.

Když program narazí na příkaz IF, vyhodnotí booleovský výraz (to, co je za if). Pokud je výsledná hodnota true, program provede veškeré příkazy, které se nachází za THEN. Jestli je výsledná hodnota false (neplatí), tak provede příkazy za ELSE.

IF a>b {to je booleovský výraz} THEN writeln(‚a je větší než b‘)
ELSE writeln(‚a není větší než b‘);

Takže po tom, co program projede tuhle rozdvojku, tak vypíše buď : „a je větší než b“ nebo „a není větší než b“. Záleží na vyhodnocení výrazu.

Příklad pro použití if

Následující program seřadí uživatelem zadaná čísla podle velikosti.

program serazeni;
var a,b,c:integer;
begin

writeln('zadej 3cisla');
readln(a,b,c);

if (a>=b) and (b>=c) then writeln(a,' ',b,' ',c);

(* Jestliže uživatel zadal "a" větší, rovno "b" a zároveň b je větší, rovno "c", tak můžu v klidu vypsat čísla v tomto pořadí a-b-c následuje dalších 5 možností : *) 
if (a>=b) and (b<=c) then writeln(a,' ',c,' ',b);
if (b>=a) and (a>=c) then writeln(b,' ',a,' ',c);
if (b>=c) and (c>=a) then writeln(b,' ',c,' ',a);
if (c>=a) and (a>=c) then writeln(c,' ',a,' ',b);
if (c>=b) and (b>=a) then writeln(c,' ',b,' ',a);

readln;
end.

Složitější podmínka

Tento způsob řeření se dá popsat jako taková podmínka v podmínce. Při splnění podmínky se provede další větvení atd. ELSE se vztahuje vždy k nejbližšímu THEN. Doporučuji, abyste si udělali tzv. Vývojový diagram, kde si graficky vyznačíte, jak program postupuje, když „prolézá“ podmínkami. Při první podmínce se program vydá jedním nebo druhým směrem, pak narazí na další rozdvojku atd. Jeden směr znamená splnění podmínky a druhý představuje ELSE.

program rychlejsi_serazeni;
var a,b,c:integer;
Begin

writeln('zadej 3 přirozená čísla');
readln(a,b,c);

if a>=b then if b>=c then writeln(a,' ',b,' ',c)
else if a>b then writeln(c,' ',a,' ',b)
else writeln(c,' ',a,' ',b)
else if c>b then writeln(c,' ',b,' ',a);
else if a>c then writeln (b,' ',a,' ',c)
else writeln(b,' ',c,' ',a);

readln;
end.

Příklady větvení programu

Příkaz IF

Následující program určí řešení kvadratické rovnice. Zároveň provede diskusi na základě hodnot koeficientů a hodnoty diskriminantu, o jakou rovnici se jedná – Kvadratická s dvěma kořeny, dvojnásobným kořenem, lineární s nekonečně mnoho řešeními, s žádným řešením nebo s dvěma komplexními kořeny. Nyní už bude zaTHEN následovat více příkazů, např. vypsat informaci o řešení a zároveň provést další operaci, proto je nutné tyto příkazy uzavřít do begin a end.

program rovnice;
var a,b,c:integer;
    reseni,diskr,reseni1,reseni2:real;
begin

writeln('zadej tri koeficienty kvadraticke rovnice');
readln(a,b,c);

{ vypis rovnice: }
writeln('rovnice vypada takto: ',a,'x^2 + ',b,'x + ',c); 

if (a=0) then
   if (b=0) then
    if (c=0) then writeln ('constantni fce - nekonecno reseni')
    {a,b,c je rovno nule}
   else writeln('konstantni fce nema reseni') {pouze c ruzne od nuly}
else begin {b,c ruzne od nuly - jedna se o linearni funkci}
  writeln('linearni fce');
  reseni:=-(c/b);
  writeln('reseni je: ',reseni);
 end
 else begin {a,b,c ruzne od nuly}
   writeln('jedna se o kvadratickou fci');
   diskr:=b*b-4*a*c; {vypocet diskriminantu}
  if diskr >=0 then begin {diskriminant vetsi jak 0 tzn. 2 koreny}
reseni1:=-b+sqrt(diskr)/2*a;
reseni2:=-b-sqrt(diskr)/2*a;
writeln('resenim je ',reseni1,' a taky ',reseni2);
end
else begin {diskriminant je zaporny - budou 2 komplexni koreny}
  writeln('je to komplexni rce');
  diskr:=-diskr;
  writeln('reseni 1 =', -b/(2*a),'+i*',sqrt(diskr)/(2*a));
  writeln('reseni 1 =', -b/(2*a),'-i*',sqrt(diskr)/(2*a));
end;
end;

readln;

end.

Příkaz CASE

Case slouží k rozvětvení programu na několik částí, přičemž program využije jen jednu a ostatní přeskočí, popřípadě provede to, co uvedeme v příkazu ELSE. Struktura CASE je vidět na příkladu.

program znamky;
var znamka:integer;
Begin

writeln('zadej cislo: ');
readln(znamka);

Case znamka of
  1 : writeln('vyborny');
  2 : writeln('chvalitebny');
  3 : writeln('dobry');
  4 : writeln('dostatecny');
  5 : writeln('nedostatecny');
else
  writeln('neni znamka');
end;

readln;
end.

Další příklad ukazuje, že konstanty, nemusejí být jen třeba jedno číslo, jako v předchozím příkladu (1,2,3..), ale také intervaly. Tento program určuje, jaký znak jste zadali.

program znaky;
var Z:char;
Begin

writeln('zadej znak: ');
readln(znamka);

Case Z of
  'A'..'Z' : writeln(Z,' je velke pismeno');
  'a'..'z' : writeln(Z,' je male pismeno');
  '0'..'9' : writeln(Z,' je cislice');
else
  writeln(Z,' je jiny znak');
end;

readln;
end.

podmíněný příkaz
umožňuje rozdělit program do 2 větví podle toho, zda je nebo není splněna podmínka
Jestliže platí podmínka p,pak proveď příkaz p1, jinak proveď příkaz p2.
if p
  then p1
  else p2;
Neúplný podmíněný příkaz
umožňuje provést příkaz jenom tehdy, když je splněna podmínka
Jestliže platí podmínka p,pak proveď příkaz p1.
if p then p1;
Vícenásobné větvení
slouží k zadání vícenásobného větvení
case Jestliže výraz je roven konstanta1, proveď příkaz1, jestliže výraz je roven konstanta2, proveď příkaz2,…, jestliže výraz je roven konstantaN, proveď příkazN, jinak proveď příkaz.
case
vyraz of
konstanta1:
 příkaz1;
konstanta2:
 příkaz2;
….
konstantaN:
 příkaz N;
else
příkaz;
end;