Pascal – #6 Podmínky

V této lekci se naučíme podmínkám. Podmínky se v programu používají k rozhodování a větvení programu. Například pokud uživatel zadá číslo, udělej něco, pokud uživatel zadá písmeno, udělej něco, pokud zadá znak, udělej něco jiného atd. Podmínky jsou nedílnou součástí každého programovacího jazyku. Je to jedna z nejdůležitějších věcí. V podstatě nejde napsat žádný větší program bez užití podmínek. Proto je velmi důležité je pochopit. Nemějte však, strach v zásadě se nejedná o nic složitého. Tolik tedy na úvod. Teď si pojďme ukázat, jak to bude vypadat v praxi.

Boolenovský výraz

Řekněme si co to je boolenovský výraz, stručně řečeno, je to takový výraz, na který se dá odpovědět ANO – NE respektive PRAVDA – NEPRAVDA. Příklad takového boolenovského výrazu je například následující  10>6 v tomto případě se jedná o ANO nebo také PRAVDU. Další možný příklad by byl 5=7 tady se však jedná o NEPRAVDU. Místo čísel však můžeme užít také proměnné, které uživatel naplní daty až za chodu programu např. a<b zde nelze na první pohled rozhodnout jedná se však také o boolenovský výraz stejně tak jako například zde x=‘A‘ tady se pro změnu ptáme, zda je v proměnné x načtený znak „A“.

Obecná syntaxe podmínky:

If (boolenovský vyraz) then
Begin

 Vykonávané příkazy;
 Vykonávané příkazy;

End;

Pojďme si to teď popsat slovy. Na začátek si řekneme, že tomuto celému se rozhodovací blok nebo taky podmínkový blok. Teď již na překlad. IF v překladu znamená ‚pokud‘ nebo taky ‚když‘. První řádek by se tedy dal přečíst takto. Pokud boolenovský výraz je pravda potom. Následující řádky jsou již blok příkazů, tak jak jsme již zvyklí například z lekce o cyklech. Pokud boolenovský výraz na začátku není pravda program skočí až na řádek s End;. Toto byla jen velice jednoduchá ukázka pojďme si ukázat něco trochu složitějšího. A tím jsou složené podmínky.

Obecná syntaxe Složené podmínky:

If (boolenovský vyraz) then
Begin

  Vykonávané příkazy;
  Vykonávané příkazy;

End

Else if (boolenovský vyraz) then
Begin

  Vykonávané příkazy;
  Vykonávané příkazy;

End;

Zde dochází k tomu, že program testuje první boolenovský výraz a pokud neplati, tak neskočí hned na konec celého bloku podmínek, ale řeší boolenovský výraz následující za slovem Else If pokud je pravda vykoná jeho příkazový blok, pokud ani ten neplatí tak hledá další boolenovský výraz za Else IF pokud žádný takový nenajde skočí na konec a pokračuje v dalším chodu programu.

Zde si ještě řekneme, že pokud by byl první boolenovský výraz platil tak by se již druhý výraz ani nekontroloval a vykonaly by se pouze příkazy následující po prvním boolenovském výrazu. Dále je důležité vědět, že Počet Else if v podmínce není omezen a můžeme ho tedy využít, kolikrát chceme. Zde si povšimneme ještě jedné zvláštnosti pascalu, že před end, za kterým následuje else se nepíše ‚;‘. Pokud bychom znak napsali, compilator by hlásil chybu.  Aby toho nebylo málo, čeká nás ještě třetí typ struktury. Ten vypadá opět podobně

Obecná syntaxe Podmínka S ELSE na konci:

If (boolenovský vyraz) then
Begin

  Vykonávané příkazy;
  Vykonávané příkazy;

End;

Elseif (boolenovský vyraz) then
Begin

  Vykonávané příkazy;
  Vykonávané příkazy;

End

Else
Begin

  Vykonané příkazy;

End;

Zde nám ke konci přibylo slovo Else, zde si opět povšimneme, že na řádku před else není za end znak ‚;‘. Druhá zvláštnost je, že se neuvádí žádný boolenovský výraz z logiky věci tedy platí, že všechny příkazy napsané za else se vykonají vždy. Else je však volitelné nemusí být v podmínce vůbec obsaženo. Většinou se jedná o koncové řešení, které pouze vypíše zprávu na obrazovku. Else by se dalo přeložit jako, pokud nastane cokoliv jiného než výše uvedené boolenovské vyrazy pak dělej následující příkazy.

Příklad 1

Tak dost bylo teorie, pojďme si ukázat, jak to funguje v praxi. Tím to pochopíte stejně nejlépe. Jako první si ukážeme zcela jednoduchý rozhodovací blok. V nadcházejícím příkladu program rozhodne zda uživatel zadal číslo větší menší než nula a nebo samotnou nulu.

Program IF1;
Uses crt;

Var a : integer;

Begin
Clrscr;
 Readln(a);

 If a > 0 then
 Begin
   Writeln('číslo vetší jak nula');
 End

 Else if a < 0 then
 Begin
   Writeln('číslo mensi jak nula') ;
 End

Else Writeln('zadané číslo je nula');

Repeat until keypressed;

End.

Logické operátory:

V druhé části lekce si ještě řekněme něco o logických operátorech, které můžeme v podmínkách využít.

OR: jedná se o logické nebo.

AND: by se dalo přeložit jako ‚a současně‘

Použití těchto operátoru v podmínkách je pak následující:

If( (boolenovský výraz) OR( boolenovský výraz)) then

taková to podmínka se provede, pokud alespoň jeden boolenovský příkaz bude pravda.

If( (boolenovský výraz) AND ( boolenovský výraz)) then

taková to podmínka se provede jen a pouze pokud budou oba boolenovské výrazy pravda

Komplexní Příklad

Vše si ukážeme hned na dalších dvou příkladech, které budou demonstrovat vše co jsme se dnes naučili. Tentokrát se bude jednat o program, kterému zadáme tři rozměry reprezentující hrany trojúhelníku, a program rozhodne, zda je vůbec možné tento trojúhelník sestavit a poté vypíše, zda se jedná o rovnoramenný rovnostranný nebo obecný trojúhelník. Při rozhodování, zda je možné sestrojit, použijeme pravidla, že součet kterýchkoliv stran musí být větší než strana třetí

Program trojuhelnik;

   uses crt;

   var a : integer;
       b : integer;
       c : integer;

 begin
     clrscr;
     Writeln('načti 3 strany trojúhelníku');
     readln(a,b,c);

              if ((a+b<c) or (b+c<a) or (c+a<b)) then
              begin
                  Writeln('Trojuhelnik nelze sestrojit');
              end
              else if  (a=b) or (b=c) or (c=a) then
              begin
                  Writeln('Rovnoramený');
              end
              else if (a=b) and (a=c) then
              begin
                  Writeln('Rovnostranný');
              end
              else Writeln('Obecný');

           repeat until keypressed;

        end.

Příklad 3

Další program neukazuje nic nového spíše procvičuje použití podmínek a logického operátoru AND.

program IF2;
 uses crt;
 var x : integer;

Begin
 clrscr;
  Writeln('Zadej cislo x od 0 do 100');
  Readln(x);
  If (x>=0) and (x<=50) then
  begin
    writeln('Zadane cislo je v intervalu od 0 do 50 včetně') ;
  end
  else if (x>=51) and (x<=100)then
  begin
    writeln('Zadane cislo je v intervalu 51 a 100');
  end
  else writeln('nezadali jste číslo v rozsahu od 0 do 100 zkuste znova');

  repeat until keypressed;

  end.

Závěr

Z dnešní lekce je to již vše. Měli byste tedy chápat obecnou strukturu podmínek if vědět kdy použít složitější podmínky s else if a else. Dále byste měli vědět, co je to boolenovský výraz. Měli byste chápat spojení boolenovských výrazů pomocí logických operátorů AND a OR. Případně si sami můžete zkusit vymyslet nějaký prográmek či pouze nějakou jinou variantu na to co jsme si dnes ukázali.

V příští lekci se podíváme na opět na cykly, které budou tentokrát ukončovány podmínkou.

#4 Řídící Struktury

V této lekci, v pořadí 4. se podíváme na řídící struktury. Patří zde podmíněné příkazy a cykly. Zařadíme zde i přepínač (příkaz switch), jeho využití je minimální. Použití jednotlivých struktur si znázorníme na příkladech.

Podmínky

Podmínka s IF

Podmíněné výrazy se tvoří pomocí klíčového slova if. Je možné použít i else ale není to nutnost.

Obecný tvar:

if (podminka)
{
	prikazy
}
else
{
	Prikazy
}

Syntaxe dovoluje zapsat podmínku i bez složených závorek, které ohraničují příkazy jak pro splněnou tak pro nesplněnou podmínku.

int vysledek = 0;

if (5 > 6)
    vysledek += 10;
    vysledek += 15;

printf("Vysledek: %d\n", vysledek);

Jak bude vypadat výpis toho programu?

Vysledek: 15

Pokud nepoužíváme složené závorky, tak ke splněné či nesplněné podmínce přiřadí pouze první příkaz. V tomto programu se podmínka nesplní. Přiřazení +10 se neprovede a else větev neexistuje. Následná operace +15 již není součásti podmíněného příkazu a je provedena.

Na následujícím příkladu vidíme použití více větví:

    
int den = 7; //predpokladejme prirazeni v rozmezi 1 až 7

if (den == 6)
    printf("je vikend\n");
else if (den == 7)
    printf("je vikend\n");
else
    printf("je pracovni den\n");

Vidíme ale, že první 2 větve mají stejný výstup je možné je spojit do jedné za použití správného operátoru:

if (den == 6 || den == 7)
    printf("je vikend\n");
else
    printf("je pracovni den\n");

Příkaz switch

Pokud máme podmínku, která obsahuje mnoho větví, je jednoduší a přehlednější použít příkaz switch.

Obecný tvar:

switch(celociselna_promenna)
{
	case konst_vyraz_1 : prikazy_1;
	case konst_vyraz_n : prikazy_n;
	default : prikazy_vychozi;
}

Následující program vypisuje slovně den v týdnu. Každý den je charakterizovaný číslem, zadán v proměnné den. Klauzule default se provede, pokud výčet neobsahuje konkrétní hodnotu, ale tento příkaz není povinný.

int den = 5;

switch(den)
{
    case 1 : printf("pondeli\n");break;
    case 2 : printf("utery\n");break;
    case 3 : printf("streda\n");break;
    case 4 : printf("ctvrtek\n");break;
    case 5 : printf("patek\n");break;
    case 6 : printf("sobota\n");break;
    case 7 : printf("nedele\n");break;
    default : printf("neznamy den\n");break;
}

Tento příklad obsahuje stejné zadání, jako příklad u podmínky s if, abyste mohli srovnat syntaxi.

int den = 5; //opet predpokladame ze prirazeni je v rozmezi 1 až 7
switch (den)
{
    case 6 :
    case 7 :
    printf("je vikend\n"); break;
    default : printf("je pracovni den\n"); break;
}

Cykly

Cyklus musí vždy obsahovat podmínku, podle které se cyklus ukončí. V těle cyklu musí být výraz, který souvisí s ukončovací podmínkou cyklu. Na základě výpočtu tohoto výrazu, se podmínka v určitém kroku nesplní a dojde k ukončení cyklu. V jazyce C existují 2 typy cyklů. Jako u podmínek i v cyklech je možné nevyužít složené závorky, ale cyklus se bude vztahovat pouze k prvnímu příkazu (posloupnost znaků oddělená nejbližším středníkem).

1. For

Obecný tvar:

for (pocatecni_hodnota;podminka;inkrementace)
{
	prikazy
}

Zde vidíme základní použití cyklu for. Program vypisuje jednotkovou matici, za pomoci 2 cyklu.

#include <stdio.h>

int main(void)
{
    unsigned char rozmer = 6; //rozmer matice

    for (int i = 0; i < rozmer; i++)
    {
        for (int j = 0; j < rozmer; j++)
        {
            if (i == j)
                printf("1 "); //vypisuje 1 na hlavni diagonale
            else
                printf("0 ");
        }
        printf("\n");
    }

    return 0;
}

Tento program vypočítává faktoriál ze zadaného čísla (proměnná cislo), je vhodné si na tomto programu vyzkoušet debugger. Pokud neumíte s debuggerem v Qt Creatoru pracovat, zde je návod k použití.

#include <stdio.h>

int main(void)
{
    unsigned int cislo = 6;
    unsigned int faktorial = 1;

    for (unsigned int i = cislo; i > 0; i--)
    {
        faktorial *= i;
    }

    printf("Vysledek: %u\n", faktorial);
    return 0;
}

Tento ukázkový příklad zobrazuje nekonečný cyklus. Ukončení běhu programu v konzoli se provede pomocí klávesové zkratky CTRL + C.

for (int i = 0; i < 1; i++)
{
    i = 0; //ridici promenna je vynulovana a podminka cyklu je s kazdou iteraci cyklu splnena
    printf("%d", i);
}

2. While

Tento cyklus může být dvojího typu, záleží jestli je podmínka cyklu na začátku nebo na konci.

Obecný tvar s podmínkou na začátku:

while (podminka)
{
	prikazy
}

Obecný tvar s podmínkou na konci:

Do
{
	Prikazy
} while (podminka);

Na tomto triviálním příkladu vidíme rozdíly mezi oběma typy cyklu while:

do
{
    printf("Cyklus while s podminkou na kocni\n");
} while(1 == 2);

while(1 == 2)
{
    printf("Cyklus while s podminkou na zacatku\n");
}

Zde můžeme srovnat syntaxe obou dvou typu cyklu (for i while)

#include <stdio.h>

int main(void)
{
    printf("Zde je vypis cyklu for\n");
    for (int i = 0; i < 3; i++) //v tomto radku vidime inicializaci pocatecni hodnoty, podminku i inkrementaci 
    {
        printf("for: %d\n", i);
    }

    printf("\nZde je vypis cyklu while\n");
    int j = 0; //zde je inicializace pocatecni hodnoty
    while (j < 3) //zde je podminka cyklu
    {
        printf("while: %d\n", j);
        j++; // zde je inkrementace
    }

    return 0;
}

Pomocné příkazy v řídících strukturách

break

S tímto příkazem jsme se již setkali u switch, kde byl použit u každého výčtu. Pokud by příkaz break nebyl pouzit ani u jednoho výčtu, příkaz switch by se nechoval jako podmíněný výraz a byl by naprosto zbytečný. Pokud upravíme příklad, který jsme si uvedli právě u příkazu switch, tak že odstraníme všechny příkazy break, můžeme pozorovat změnu ve výpisu pro všechny hodnoty 1 až 7.

Obecně příkaz break předčasně ukončuje cykly for či while. V daném programu se postoupí na příkaz, který se nachází bezprostředně za tímto cyklem. Použití si znázorníme na ukázkovém příkladu:

#include <stdio.h>

int main(void)
{
    unsigned char cislo = 250;
    for (int i = 1; i < 100; i++)
    {
        cislo++;
        printf("%d. iterace cyklu | cislo = %d\n", i, cislo);
        if (cislo == 255) //pokud dojde k preteceni datoveho typu, cyklus se zastavi
            break;
    }

    return 0;
}

continue

Tento příkaz funguje podobně jako break, s tím rozdílem, že neukončí celý cyklus, ale pouze právě prováděnou iteraci.

goto

Příkaz provede přesun na určitý řádek kódu, který je označen tzv. štítkem. Tento štítek musí mít stejný název jak pro označení řádku tak jako hodnota příkazu goto, aby příkaz fungoval správně

goto stitek
...
stitek : prikazy

Tento příkaz je možné použít i ke zkonstruování cyklu:

int i = 0;

iterace : if (i < 10)
{
    printf("%d. iterace\n",i);
    i++;
    goto iterace;
}

Všechny tyto 3 příkazy je možné nahradit, je vhodné je používat co nejméně a příkaz break používat pouze u switch.

Poznámka

Nepleťte si operátory = a == první slouží k přiřazení a druhý porovnává 2 hodnoty.

To je vše k dnešní lekci o řídících strukturách v jazyce C. Příště se podíváme na využití polí a také na ukazatele.