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ů:
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}");
}
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.
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).
List<int> list = new List<int>();
list.Add(10);
list.Add(20);
list.Add(30);
foreach (int item in list)
{
Console.WriteLine(item);
}
List<int> list = new List<int>();
list.Add(10);
list.Add(20);
list.Add(30);
foreach (var item in list)
{
Console.WriteLine(item);
}