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); }