Pascal – #5 Cykly se známým počtem opakování

Dnes se naučíme psát cykly v jazyku pascal. Na úvod si řekněme, co to ty cykly jsou. Cyklus nám umožní opakovat určitou část kódu libovolně dlouho. Dnes si řekneme o tzv. cyklech, u kterých známe počet opakování.

Cykly: Obecná synataxe

FOR i:=zacatek TO konec DO
 BEGIN
 Příkaz, který se bude opakovat;
 Příkaz, který se bude opakovat;; 
END;

Teď si to pojďme rozebrat. For je klíčové slovo, které říká, že se jedná o cyklus. Proměnná ‚i‘ tady má roli počítadla. A na začátku cyklu, je nastavena na hodnotu, která se bude při jednotlivých průchodech cyklu navyšovat až do té doby, než nabyde hodnotu uloženou v proměnné konec. Z tohoto kódu je tedy možné okamžitě vyčíst, kolikrát se bude opakovat, protože v prvním řádku v podstatě vidíme interval. Většinou se udává od 1.

Příklad

Aby nám to bylo jasnější, pojďme si to ukázat na jednoduchém příkladu, který nám ukáže, jak funguje počítadlo a co se vlastně v průběhu toho cyklu stane.

program cykly;
uses crt;
var i:integer;
 
begin
 clrscr;
  for i:=1 to 10 do
   begin
      writeln(i);
   end
 repeat until keypressed;
end.

Rozebrání kódu

Jak je již hned zřejmé ze zadání můžeme vidět, že daný cyklus se bude opakovat 10krát jelikož jsme zadali interval od 1 do 10. V příkazové části dá-li se to tak nazvat poté provádíme příkaz Writeln(i), tedy vypisujeme počítadlo. Tento program v podstatě nic nedělá, pouze vypisuje. Hodnota počítadla se zvedá automaticky při každém průchodu cyklu. V praxi to tedy vypadá takto.

Program narazí na slovo For a tím zjistí, že se jedná o cyklus do proměnné i (počítadla) si uloží spodní hodnotu intervalu, a postupuje na další řádek, kde vykoná příslušné příkazy v našem případě, vypíše proměnnou i. Jakmile dojde na konec, vrátí se zase zpět a proměnná i se navýší o hodnotu jedna, porovná ji s koncovou hodnotou intervalu a pokud se nerovná koncové hodnotě, jde znova na příkazovou část cyklu. Toto se opakuje tak dlouho, dokud se hodnota počítadla nerovná koncové hodnotě v té chvíli program opouští cyklus a věnuje se ostatnímu kódu, v našem případě repeat until keypressed; tedy čeká na vstup z klávesnice.

V dalším příkladu si uživatel sám zadá počet opakování. Jedna se tedy pouze o modifikaci předchozího příkladu.

Příklad 2

program cykly2;
uses crt;
var i : integer;
var pocatek : integer;
var konec : integer;
begin
  clrscr;
  write('Zadej cislo pocatek: ');
  readln(pocatek);
  write('Zadej cislo konec: ');
  readln(konec);
    for i:=pocatek to konec do 
    begin
      writeln(i);
    end;
repeat until keypressed;    
end.

V tomto příkladu vidíte, že počet opakování není zadán konstantami ale proměnnými počátek a konec, do kterých uživatel sám zadá čísla a rozhodne si tak počet opakování.

Další možnosti zápisů

Pojďme si ještě ukázat další možnosti zápisu. Například poslední příklad by šel zapsat takto:

for i:=1 to 10 do writeln(i);

Vidíme tedy, že zde chybí struktura begin – end;  sami si zvolte, co pro vás bude lepší. Ale doporučuji používat více řádkovou strukturu z jednoho prostého důvodu ve chvíli, kdy přijdou složitější cykly a bude potřeba napsat více příkazu, bude to mnohem přehlednější. Tento jedno řádkový zápis tedy slouží pro jednoduché příklady.

Kontrolní otázky

Po této lekci by jste měli být schopni zcela s přehledem odpovědět na tyto otázky.

  1. Co je to cyklus a k čemu slouží.
  2. Co je to počítadlo a k čemu slouží.
  3. Jak vypadá obecná syntaxe.

Kontrolní příklad

Napište příklad, který se uživatele zeptá na číslo (počet opakování) a na zprávu. Danou zprávu vypíše píše tolikrát kolik zadal uživatel opakování př. uživatel zadá číslo 4 zpráva se vypíše 4krát..

Závěr

To je z dnešní lekce vše příště se podíváme na podmínky. Pokud Vám není něco jasné ptejte se přímo zde v komentářích.

#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.