Cyklus

Řídicí struktury

SSŠVT


Cyklus

Opakování části kódu

Pokud se nějaká akce (část kódu) má v programu provést nula-krát, jeden-krát, dva-krát, tři-krát atd., přičemž to, kolikrát se provede, závisí na nějaké podmínce, hodnotě apod., použijeme třetí nejběžnější řídicí strukturu – totiž cyklus.

V C# máme tyto příkazy pro různé typy cyklů:


Opakování části kódu s předem známým počtem opakování (iterací)

Pokud předem víme, že se má část kódu provést např. desetkrát, můžeme použít cyklus for. Syntaxe:

for (inicializace; podmínka; iterace)
    příkaz
        

Ve for-cyklu většinou používáme tzv. řídicí proměnnou, např. i. Při inicializaci uložíme do řídicí proměnné nějakou výchozí hodnotu, např. i = 1

V části podmínka je nějaká podmínka, která říká:

Pokud pro cyklus používáme řídicí proměnnou, měla by tato proměnná v podmínce figurovat. V našem případě bude podmínka např. i <= 10

Po provedení příkazu (tzv. těla cyklu) se provede ještě část iterace, kam většinou dáme příkaz, který nějak aktualizuje hodnotu uloženou v řídicí proměnné. Například: i++

Tělo cyklu (příkaz) má být jediný příkaz. Ale můžeme použít blok (složené závorky) a do něj dát příkazů více. Blok se chová jako jediný příkaz, byť je složený z několika podpříkazů.

Příklad for cyklu, který na konzoli vypíše čísla od 1 do 10 a jejich druhé mocniny.

for (int i = 1; i <= 10; i++)
{
    Console.WriteLine($"i = {i}");
    Console.WriteLine($"i^2 = {i * i}");
}
        

Opakování části kódu do splnění/nesplnění určité podmínky

Tam, kde je podmínka "abstraktnější" a nelze předem určit počet průchodů cyklu, můžeme použít jednu z konstrukcí:

Syntaxe cyklu while:

while (podmínka)
    příkaz
        

Cyklus while říká, že dokud je splněna podmínka, provede se příkaz. Místo jediného příkazu můžeme opět použít blok (sadu příkazů uzavřených do složených závorek).

DayOfWeek currentDay = DateTime.Now.DayOfWeek;
while (DateTime.Now.DayOfWeek == currentDay)
{
    Thread.Sleep(60000);
    Console.WriteLine(DateTime.Now);
}
        

Předchozí příklad while-cyklu vypisuje každou minutu na konzoli aktuální datum a čas. Vypisování skončí, jakmile "přejdeme" přes půlnoc, protože se změní DayOfWeek a podmínka v hlavičce cyklu už nebude splněna.

Dále máme k dispozici konstrukci do-while. Syntaxe:

do
    příkaz
while (podmínka);
        

Konstrukce do-while se chová "téměř" stejně jako příkaz while. Provede se příkaz a vyhodnotí se podmínka. Pokud je podmínka splněna (vyhodnocena jako true), opět se provede příkaz. A znovu se kontroluje podmínka. A tak dále. Jakmile je podmínka nesplněna (vyhodnocena jako false), pokračuje se prvním příkazem za koncem cyklu (za podmínkou).

Příklad do-while cyklu:

do
{
    Console.Write("Zadej kladné číslo (pro ukončení zadej nulu): ");
    string s = Console.ReadLine();
    int n = Convert.ToInt32(s);
    Console.WriteLine($"Zadal jsi: {n}");
}
while (n > 0);
        

Rozdíl mezi while a do-while je v tom, že u cyklu while se nejprve vyhodnotí podmínka, a teprve potom (je-li splněna) se provede příkaz.

U cyklu do-while se nejprve provede příkaz, a teprve pak se kontroluje, zda je splněna podmínka.

Z toho vyplývá, že je možné, že tělo cyklu while se nikdy neprovede (pokud již před prvním průchodem podmínka splněna není), zatímco v cyklu do-while se jeho tělo aspoň jednou provede vždy.


Procházení kolekcí

Pokud máme kolekci (např. pole int a[] = new int[10]; for (int i = 0; i < a.Length; i++) { a[i] = i + 1; }, nebo třeba seznam List<int> list = new List<int>(); list.Add(10); list.Add(20); list.Add(30);), tak pro zpracování takové kolekce můžeme použít cyklus foreach. Syntaxe je:

foreach (typ-prvku proměnná in kolekce)
    příkaz
        

Zápis cyklu foreach se promítne při provádění našeho programu tak, že se příkaz postupně vykoná tolikrát, kolik prvků v kolekci máme. Přitom v každé iteraci tohoto cyklu bude v proměnné hodnota toho prvku z kolekce, který odpovídá pořadí iterace (o kolikátý průchod tělem cyklu se jedná).

V hlavičce foreach cyklu musí být proměnná stejného datového typu jako prvky kolekce. Datový typu určuje typ-prvku. Pokud chceme nechat na překladači jazyka C#, aby odvodil ("infer"), jaký typ se má pro proměnnou použít, použijeme místo typu-prvku zástupné klíčové slovo var.

Následující příklady kódu s cyklem foreach a s explicitním určením typu-prvku i s klíčovým slovem var dělají stejnou věc: Vypíší na konzoli postupně prvky seznamu list, čili 10, 20 a 30 (na každý řádek jedno číslo).

Příklad s explicitním určením typu prvků kolekce
List<int> list = new List<int>();
list.Add(10);
list.Add(20);
list.Add(30);
foreach (int item in list)
{
    Console.WriteLine(item);
}
        
Příklad s klíčovým slovem var
List<int> list = new List<int>();
list.Add(10);
list.Add(20);
list.Add(30);
foreach (var item in list)
{
    Console.WriteLine(item);
}