Cykly, neboli smyčky

6. díl - Cykly, neboli smyčky

Petr Sklenička       26. 10. 2010       C++/C       9503 zobrazení

Po pauze větší, než je obvyklé, opět přichází další díl seriálu C++ krok za krokem. Všem čtenářům tohoto seriálu se za pauzu omlouvám, byla způsobena mými zdravotními problémy. V dnešním díle nás čeká úvod do smyček, neboli do cyklů. Představíme si cyklus for, vysvětlíme si co dělá a samozřejmě nebude chybět krátký příklad praktického užití. Jako bonus přikládám tři otázky, podle kterých si můžeme ověřit, jestli cyklům for rozumíte. V další díle si pak řekneme o druhém typu cyklů, konkrétně while.

Co je to cyklus


Jak již samotný název napovídá, jedná se o něco, co se bude opakovat. V programování tedy cykly používáme, chceme-li nějakou sekvenci příkazů několikrát zopakovat. Můžeme mít tedy nějaký příkaz, u kterého budeme chtít, aby se provedl desetkrát, tudíž použijeme cyklus. Existují dvě možnosti, jak říct, kolikrát se příkaz zopakuje. První možostí je, že přesně víme, kolikrát chceme něco opakovat, čili např. desetkrát. Druhá možnost je taková, že chceme, aby se sekvence příkazů opakovala tak dlouho, dokud platí nějaká podmínka (popř. dokud neplatí nějaká podmínka). Proto si cykly v programování můžeme rozdělit do dvou skupin - cyklus for a cyklus while.

Cyklus for


U tohoto cyklu známe předem počet opakování. Jinak řečeno víme, že daný příkaz chceme zopakovat právě n-krát. Uvedeme si krátký, v praxi zcela zbytečný příklad. Chceme desetkrát za sebou vypsat na obrazovku text "Umim pouzivat cyklus". Pokud byste cykly neznali, asi byste napsali desetkrát příkaz cout. Jednodušší řešení je však toto:

for (int i = 0; i < 10; i++)
{
    cout << "Umim pouzivat cyklus\n";
} 

Tento kód Vám na obrazovku skutečně vypíše text desetkrát. Otázkou zůstává, jak to celé funguje. Není v tom skryta žádná složitost. Klíčovým slovem for uvozujeme, že se jedná o cyklus. V kulatých závorkách máme proměnnou i typu int, kterou inicializujeme na nulu. Této proměnné se říká iterační. Za nastavením proměnné na hodnotu 0 následuje středník a podmínka, že cyklus se bude opakovat tak dlouho, dokud bude proměnná i menší než hodnota deset. V poslední části se v závorkách nachází inkrementace proměnné i. To, co se vyskytuje ve složených závorkách jsou příkazy (v našem případě jeden příkaz), které se budou opakovat. Na obrazovku se tedy vypíše text "Umim pouzivat cyklus" a hodnota proměnné i se zvýši o jedna. Zkontroluje se, jestli hodnota i je menší než deset a poté se celý příkaz provede znovu. Tak se to celé bude opakovat do doby, než hodnota i bude rovna deseti. Pak cyklus skončí. S iterační proměnnou (proměnná i) je možné pracovat i v těle cyklu, jako s každou jinou proměnnou. Zkuste uhádnout, co na obrazovku vypíše následující fragment kódu:

for (int i = 0; i < 5; i++)
{
    cout << i + 1 << "\n";
}

Pokud si myslíte, že se na výstupu objeví čísla od jedné do pěti, máte pravdu. Proměnná i se každým průchodem zvyšuje o jedničku, její původní hodnota je nula a vypisuje se vždy hodnota o jedničku vyšší, než i (i + 1). V prvním průchodu je tedy hodnota proměnné i rovna 0, vypisujeme ale 0 + 1, tedy jedna. V dalším průchodu už hodnota i je jedna, vypíše se tedy 1 + 1, čili dva. Celé to pokračuje do doby, než bude mít i hodnotu 5 - v tu chvíli cyklus končí.

V tuto chvíli možná ještě nevidíte obrovský přínos, kterými cykly v programování jsou. Vězte ale, že postupem času to zjistíte, možná už i u příkladu, který si uvedeme na konci tohoto článku. Nevýhodou cyklů je, že si musíte dát pozor, abyste náhodou nenapsali tzv. "nekonečný cyklus", který Vám nikdy neskončí. Uvedu směšný příklad, abyste viděli co myslím.

for (int i = 0; i > -5; i++)
{
    cout << "Nekonecny cyklus";
}

Cyklus nám poběžím tak dlouho, dokud hodnota proměnné i bude větší než číslo -5. Problém je v tom, že původní hodnota proměnné i je 0 a s každým dalším průchodem se zvyšuje, čili bude pořád větší než -5. Cyklus proto nikdy neskončí a na kód, který se vyskytuje v programu pod cyklem, se nikdy nedostane. Toto byl velmi primitivní příklad nekonečného cyklu, asi si říkáte, že to se Vám nemůže nikdy stát. Pokud ale budete programovat, stane se Vám to. Nebude se ale samozřejmě jednat o takovýto banální příklad.

Co se týče iterační proměnné i, je čistě na Vás, jak si ji pojmenujete. Nikde není psáno, že musíte používat zrovna i, nicméně je to jakýmsi zvykem. Ani hodnota, na kterou proměnnou i nastavíte, nemusí být nula. A také nemusíte při každém průchodu zvyšovat hodnotu o jedničku, můžete si ji třeba násobit pětkou, exponenciálně zvětšovat, dělit, odečítat, zkrátka co Vás napadne. Vemte však v potaz, že poté je mnohem složitější poznat, k čemu onen cyklus vlastně slouží.

Vnořené cykly, anebo cykly v cyklech


Aby to celé bylo ještě trochu zajímavější, řekneme si o vnořených cyklech. V těle cyklu se vyskytuje nějaké sekvence příkazů, které se budou opakovaně provádět. Co když ale do těla cyklu umístíme další cyklus? Pokud toto uděláme, máme vnořený cyklus. Jednoduchý příklad:

for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        cout << i << "." << j << "\n";
    }
}

Tělo vnějšího cyklu (ten s iterační proměnnou i) se bude opakovat celkem dvakrát. V těle cyklu se však vyskytuje další cyklus, jehož tělo se bude opakovat také dvakrát. Příkaz cout se tedy provede celkem čtyřikrát (2 x 2 = 4), pokaždé však proměnné i a j mají jinou hodnotu. Uvědomte si, že na jeden průchod vnějšího cyklu je nutné provést všechny průchody vnitřího cyklu. Tímto způsobem do sebe můžete vnořit tereticky nekonečný počet cyklů, nicméně mít sto vnořených cyklů není zrovna "to pravé ořechové".

Program - průměr známek ve škole


V minulém díle jsme na závěr počítali průměr z pěti známek. K uložení známek jsme využili pole. V dnešním díle si celý program napíšeme znovu, nicméně trochu jinak, lépe. Umíme totiž používat cykly, proto bude program o hodně snažší. Uvědomte si, že uživatel zadává pět známek, což by Vám mělo napovědět, že příkaz, kterým uživatele vybídneme k zadání známky, se bude vyskytovat v těle cyklu. Dále dojde k uložení známky na patřičné místo v poli. Vzhledem k tomu, že v našem případě počítáme průměr z pěti známek, cyklus proběhne právě pětkrát. Nějak takto by mohl vypadat kód:

#include <iostream>
using namespace std;

int main()
{
    int soucet, znamky[5];
    double prumer;

    soucet = 0;
    

    for (int i = 0; i < 5; i++)
    {
        cout << "Zadej " << i + 1 << ". znamku: ";
        cin >> znamky[i];
        soucet += znamky[i];    
    }
    
    prumer = soucet / 5;

    cout << "Tvuj prumer je " << prumer << ".\n";
    return 0;
}

Určitě se mnou budete souhlasit, když řeknu, že tento kód je mnohem "hezčí" než ten v předchozím díle. Dále je zde výhoda v tom, že kdybychom chtěli počítat průměr třeba ze sta známek, kód by zůstal stále stejně dlouhý. Jedinné, co by se změnilo, je číslo 5, které bychom nahradili číslem 100.

Pro tento díl je to vše, v díle příštím budeme s cykly pokračovat, podíváme se však na cykly while.  Pokud si myslíte, že jste cykly pochopili, můžete se zkusit podívat na následující úkoly:

Máme následující fragmenty kódů:

for (int i = 5; i < 10; i += 2)
{
    cout << i + 3 << "\n";
}
int vysledek = 0;
for (int i = 0; i < 5; i++)
{
    for (int j = 5; j > 0; j++)
    {
        vysledek = i + j;
    }
}

cout << vysledek;
for (int i = 0; i < 5; i++)
{
    
    for (int j = 0; j < 5; j++)
    {
        int soucet = 0;
        soucet = soucet + i + j;        
    }    

}

cout << soucet;

Co se objeví na výstupu u jednotlivých kódů? Je v kódu něco špatně? Předpokládejte, že v programu máme řádně napsanou funkci main a další potřebné náležitosti.

Pokud by něco nebylo jasné, napište do diskuze, není problém cokoliv lépe vysvětlit.

 

hodnocení článku

4 bodů / 4 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Všechny díly tohoto seriálu

 

Mohlo by vás také zajímat

C++/CLI a interoperabilita managed a unmanaged kódu - díl 1.: Úvod do jazyka a základní konstrukce

V tomto článku je popsána nadstavba C++ pro práci s .NET prostředím zvaná C++/CLI umožňující vytvářed mixed assembly obsahující jak managed tak unmanaged kód. V prvním díle je popsána myšlenka jazyka a základní syntaktické konstrukty (základní typy, podmínky, cykly, pole, namespace a část tříd a objektů). U čtenáře je předpokládána znalost .NET frameworku a nativního programování nejlépe v C++ (alespoň syntaxi a základy).

C++/CLI a interoperabilita managed a unmanaged kódu - díl 2.: Složitější konstrukty, low-level přístup a generické programování

V tomto článku je popsána nadstavba C++ pro práci s .NET prostředím zvaná C++/CLI umožňující vytvářed mixed assembly obsahující jak managed tak unmanaged kód. V tomto díle jsou popsány pokročilejší partie jazyka týkající se hlavně objektů, low-level přístupu k managed objektům a generického programování.

Virtuální souborový systém

Článek pojednává o způsobu návrhu virtuálního souborového systému. Před čtením Vám doporučuji stáhnout si a přečíst zadání, abyste věděli o co vlastně jde. Ke stažení jsou i zdrojové kódy v jazyce C++. Aplikace asi nemá žádné velké využití, nicméně přišlo mi to jako zajímavý problém - jednalo se o semestrální projekt.

 

 

Nový příspěvek

 

f

'

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Cykly, neboli smyčky

Prosím Vás co znamená

for (int i = 5; i < 10; i += 2)

a úplně na konci to i +=2

nahlásit spamnahlásit spam 0 odpovědětodpovědět

i += 2 je úplně stejné jako i = i + 2. V každém kroku cyklu se tedy hodnota i zvýší o dvojku. Tedy 5, 7, 9.

nahlásit spamnahlásit spam 4 / 4 odpovědětodpovědět

Diskuse: Cykly, neboli smyčky

Dobrý den, chtěl bych pochválit výborný článek a možná dodat jednu maličkost. Váš příklad nekonečného cyklu není dokonalý. Jako ukázka samozřejmě postačuje, ale tento cyklus nakonec skončí, protože když se u datového typu int dostaneme na horní hranici, tak se hodnota převrátí do záporných hodnot. Se zvyšováním o jedničku to sice bude trvat dlouho, ale nastane to... Jenom taková poznámka, nechci šťourat :)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

V první řadě děkuji za pochvalu. Co se týče té poznámky, přiznávám, máte pravdu. Přiznávám i to, že jsem na to při psaní článku zapomněl, neuvědomil jsem si to, i když to samozřejmě vím. Ono to je patrně tím, že člověk vědomě nekonečný cyklus asi nepíše. Tím se ale rozhodně nechci nijak ospravedlňovat, děkuji Vám za to, že jste mě a vlastně i čtenáře na tuto chybu upozornil.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Diskuse: Cykly, neboli smyčky

S cim nezbyva nez souhlasit?

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback