Podmienený príkaz

Úvod

Predstavme si program, ktorý od používateľa vypýta číslo n a zobrazí hodnotu 1.0/n. Vieme ale, že pre n=0 nemá výraz 1/0 zmysel. Preto by mal byť program natoľko inteligentný, aby používateľa pre n=0 varoval:

n=StrToInt(Edit1->Text)
ak n==0 zobraz_chybu;
inak vypočítaj 1.0/n;

Program sa podľa podmienky n==0 rozhodne, ktorý príkaz vykoná - či vypíše chybovú správu alebo sa zobrazí správny výsledok. Program obsahuje dva alternatívne postupy - dve vervy:

* príkaz prvej vetvy sa vykoná, keď je podmienka splnená
* príkaz z druhej vetvy sa vykoná keď podmienka splnená nie je

Príkaz, ktorý umožňuje takéto podmienené vetvenie programu, sa nazýva podmienený príkaz.


Podmienený príkaz if ... else

Predchádzajúci algoritmus zapísaný pomocou príkazu if ... else:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int n;
n=StrToInt(Edit1->Text);
if (n==0) g->TextOut(0, 0, "chyba");
else g->TextOut(0, 0, 1.0/n);
}

Syntax príkazu if ... else:

if (podmienka) príkaz1
else príkaz2

pričom:

* príkaz1, príkaz2 je jednoduchý príkaz ukončený ; alebo skupina príkazov uzavretá v zložených zátvorkách (podobne, ako v príkazoch cyklu)
* podmienka
* je logický výraz (analogická, ako v príkazoch cyklu) príkaz funguje takto: ak je podmienka splnená vykoná sa príkaz1 inak sa vykoná príkaz2.

Príklad: Matematická definícia absolútnej hodnoty reálneho čísla A:

pre A<0 je |A| = -A
inak |A| = A

Výpočet absolútnej hodnoty zapísaný v jazyku C++:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int A, AbsA;
A=StrToInt(Edit1->Text);
if (A<0) AbsA=-A;
else AbsA=A;
g->TextOut(0, 0, AbsA);
}


Príklady s podmieneným príkazom

Úloha: Máme program:

if (X<20) {
g->Font->Color=clGreen;
g->TextOut(0, 0, "A");
} else {
g->Font->Color=clBlue;
g->TextOut(0, 0, "B");
}
g->TextOut(0, 20, "Koniec");

Aký text (a akou farbou) vypíše pre X==-10, X==40 a pre X==20?

Ukážka: Kombinácia príkazu cyklu a podmieneného príkazu:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int x;
for (x=0; x<10; x++) {
if (x%2==0) g->Font->Color=clRed;
else g->Font->Color=clBlue;
g->TextOut(x*10, 0, '*');
}
}

Znak % (percento) je operátor modulo - zvyšok po delení. Hodnota výrazu a%b je zvyšok, ktorý vznikne po delení čísla a číslom b.

Hodnota výrazu x%2 bude:

* pre párne x rovný nule
* pre nepárne a kladné x rovný 1
* pre nepárne a záporné x rovný -1

Ukážka: Vnáranie podmienených príkazov. Program zobrazí správu o tom, či používateľ zadal kladné číslo, záporné číslo alebo číslo rovné 0:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int N;
N=StrToInt(Edit1->Text);
if (N<0) g->TextOut(0, 0, "Záporné číslo");
else
if (N>0) g->TextOut(0, 0, "Kladné číslo"); // vnorený príkaz if
else g->TextOut(0, 0, "Číslo je rovné 0");
}


Logické výrazy, typ bool

Hodnota logického výrazu je typu bool a môže mať:

* buď hodnotu false (logická nepravda)
* alebo hodnotu true (logická pravda)

Príklad použitia premennej typu bool:

bool test;
test=1<2;
if (test) g->TextOut(0, 0, "Premenná test má hodnotu true");
else g->TextOut(0, 0, "Premenná test má hodnotu false");

Logické výrazy môžeme v C++ vytvárať:

* porovnaním dvoch hodnôt - už poznáme operátory: ==, !=, <, >, <=, >=;
* použitím operátorov logická negácia alebo pomocou logických spojok:

zápis v C++: matematický význam: príklad: výsledok:
!V logická negácia výrazu V !(5==5) false
X && Y logické X a Y (1==2) && (0==0) false
X || Y logické X alebo Y (1==2) || (0==0) true

Vo výrazoch, v ktorých sa nachádza viacero operátorov, treba dávať pozor na priority operátorov. Priorita operátorov určuje, v akom poradí sa jednotlivé časti výrazu vyhodnotia (časť s operátorom s najvyššou prioritou sa vyhodnotí najskôr). Priority známych operátorov:

priorita: operátor: význam:
najvyššia ( ) zátvorky
! + - ++ -- negácia, unárne + a -,
operátory inkrementácie a dekrementácie
* /
+ - binárne + a -
< <= > >=
== !=
&& logické AND
najnižšia || logické OR

* priority ďalších operátorov sa dajú nájsť v pomocníkovi (Help)
* na sprehľadnenie komplikovaných výrazov sa odporúča používať zátvorky (aj keď to nie je potrebné)

Príklad vyhodnotenia komplikovaného logického výrazu:

výraz: !(5>5) && 2+3==5 || 6!=6
vyhodnocujem: !false && 2+3==5 || 6!=6
true && 2+3==5 || 6!=6
true && 5==5 || 6!=6
true && true || false
true || false
výsledok: true


Príkaz if bez vetvy else

Príklad: Výpis čísel, ktoré sú delitelné 7, ale nie sú delitelné 3:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int y=0, n=0;
while (y<Image1->Height) {
if (n%7==0 && n%3!=0) {
g->TextOut(0, y, n);
y=y+15;
} else ; // prázdny príkaz - nič nevykoná
n++;
}
}

Vidíme, že vo vetve else sa nachádza prázdny príkaz (skúste zistiť, čo sa stane, ak by za else nebola bodkočiarka!). V takomto prípade používame príkaz if bez vetvy else:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int y=0, n=0;
while (y<Image1->Height) {
if (n%7==0 && n%3!=0) {
g->TextOut(0, y, n);
y=y+15;
}
n++;
}
}

Príklad: Program podľa počtu hodín vypíše dobré ráno, dobrý deň, dobrý večer alebo dobrú noc:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int Hod;
Hod=StrToInt(Edit1->Text);
if (Hod<0 || Hod>24) g->TextOut(0, 0, "Neblázni!");
else {
if (Hod>=4 && Hod<=8) g->TextOut(0, 0, "Dobré ráno");
if (Hod>=9 && Hod<=16) g->TextOut(0, 0, "Dobrý deň");
if (Hod>=17 && Hod<=21) g->TextOut(0, 0, "Dobrý večer");
if (Hod<=3 || Hod>=22) g->TextOut(0, 0, "Dobrú noc");
}
}


Používanie farieb

Geometrickým útvarom môžeme nastaviť farbu:

* pero - určuje farbu úsečiek, obrys elíps a obdĺžnikov: g->Pen->Color=clBlack;
* výplň - vnútorná farba obdĺžnikov, elíps ale aj pozadie za textom: g->Brush->Color=clWhite;
* písmo: g->Font->Color=clBlack;

Príklad. Nakreslíme obdĺžnik so žltým vnútrajškom a červeným obrysom:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
g->Pen->Color=clRed;
g->Brush->Color=clYellow;
g->Rectangle(10, 10, 200, 100);
}

Príklad. Nakreslíme prekrývajúce sa farebné obdĺžniky (podobný príklad sme riešili na predchádzajúcich cvičeniach):
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCanvas *g=Image1->Canvas;
int n, sx, sy;
sx=Image1->Width/2;
sy=Image1->Height/2;
for (n=20; n>=1; n--) {
if (n%3==0) g->Brush->Color=clRed;
if (n%3==1) g->Brush->Color=clBlue;
if (n%3==2) g->Brush->Color=clYellow;
g->Rectangle(sx-n*20, sy-n*10, sx+n*20, sy+n*10);
}
}