Iterace
Iteraci volíme tehdy, chceme-li jeden či několik příkazů opakovat.
Například chceme-li vypsat pozdrav pětkrát:
void main(){
for (int i=0; i<5; i++){
printf("Ahoj, světe!\n");
}
}
Pro iteraci (cyklus, smyčku) máme několik možností:
- for
- volíme nejčastěji pokud víme dopředu počet opakování
- while
- volíme spíše v případě, že není jasný počet opakování
- do-while
- volíme tehdy, chceme-li příkazy vykonat vždy alespoň jednou
Automaticky generovaný podcast o smyčkách si můžete pustit zde:
Podkladem pro podcast byla tato stránka a https://www.geeksforgeeks.org/c/c-loops/
Smyčka for
Smyčka for se skládá ze tří částí oddělených znakem středník ;
- inicializace (zvolíme si proměnnou, se kterou ve smyčce budeme pracovat a nastavíme jí iniciální hodnotu) „od kolika“
- podmínka, která musí platit, aby se smyčka opakovala „do kolika“
- inkrement (příkaz, který se provede při každém průchodu smyčkou) „po kolika“
Například ve smyčce:

for (int i = 1; i <= 5; i++){
printf("%d. průchod\n", i);
}
máme jednotlivé části:
- inicializace: int i = 1; (budeme pracovat s proměnnou i a nastavili jsme jí iniciální hodnotu 1)
- podmínka: smyčka se bude opakovat tak dlouho, dokud i bude menší nebo rovno 5
- inkrement: při každém průchodu smyčkou přičteme k aktuální hodnotě proměnné i jedničku
Smyčka tedy způsobí výpis:
1. průchod
2. průchod
3. průchod
4. průchod
5. průchod
Smyčka while
Smyčka while má jednotlivé části oddělené, tj. ještě před smyčkou je nutné deklarovat a inicializovat proměnnou, kterou budeme ve smyčce používat. Za slovem while je pouze podmínka, která musí platit, aby se smyčka opakovala. Nesmíme zapomenout na příkaz, kterým budeme měnit hodnotu proměnné někde uvnitř smyčky.
Například:

int i = 0;
while (i < 5){
i++;
printf("%d. průchod\n");
}
Na prvním řádku vidíme deklaraci proměnné i (použili jsme datový typ celé číslo, int). Proměnnou jsme si rovnou inicializovali, tj. přiřadili do ní hodnotu 0.
Následuje slovo while a v kulaté závorce vlastní podmínka, která musí platit, aby se smyčka opakovala. V tomto případě se smyčka bude opakovat tak dlouho, dokud i bude menší než 5.
Následuje blok příkazů ve složených závorkách, kdy nejprve zvýšíme aktuální hodnotu proměnné i o jedničku a v následujícím příkazu provedeme výpis.
I zde smyčka způsobí výpis:
1. průchod
2. průchod
3. průchod
4. průchod
5. průchod
Smyčka do-while
Smyčka do-while je velice podobná smyčce while jen s tím rozdílem, že musí proběhnout vždy alespoň jednou.
Například:

int x;
do {
printf("Zadej hodnotu větší než 5: ");
scanf("%d", &x);
} while (x <= 5);
Zde si nejprve deklarujeme proměnnou x (zvolili jsme datový typ celé číslo, tj. int).
Následuje vlastní smyčka, která se skládá z výpisu „Zadej hodnotu větší než 5: “ a vlastního načtení čísla z klávesnice na adresu proměnné x.
Smyčka se bude opakovat tak dlouho, dokud hodnota x bude menší nebo rovna 5, tj. do té doby, než uživatel zadá to, co po něm chceme (číslo větší než 5).
Příklady
Příklady na iterace si můžete zobrazit zde.
Příklady z webu w3resource si můžete zobrazit zde – for, while, do-while.
Vnořené smyčky
Jedna smyčka je super – ale v životě si s pouhou jednou smyčkou často nevystačíme. Jestliže potřebujeme opakovat nějakou činnost uvnitř jiné opakované činnosti, používáme tzv. vnořené smyčky. Jinými slovy: jedna smyčka běží „ve velkém“ a každé její jedno opakování spustí smyčku další, menší. Tento princip je velmi běžný v reálném životě – například když učitel rozdává testy ve třídě: vnější smyčka prochází jednotlivé řady lavic, vnitřní smyčka rozděluje papíry studentům v konkrétní řadě. Podobně funguje třeba procházení kalendáře po dnech a zároveň vypsání hodinového rozvrhu pro každý den, nebo generování tabulek, kde každý řádek obsahuje několik sloupců.
Vnořené smyčky nám umožňují řešit úlohy, které mají strukturu mřížky, tabulky, řad a sloupců, kombinací, permutací nebo opakovaných skupin kroků. Typický příklad v programování je například výpis jednoduché tabulky. Vnější smyčka bude řídit řádky, vnitřní smyčka pak sloupce.
for (int r = 0; r <= 5; r++){
for (int s = 0; s <= 9; s++){
printf("%i:%i ", r,s);
}
printf("\n"); //odřádkování provedeme až po výpisu všech sloupců
}
Tento kód vypíše:
0:0 0:1 0:2 0:3 0:4 0:5 0:6 0:7 0:8 0:9
1:0 1:1 1:2 1:3 1:4 1:5 1:6 1:7 1:8 1:9
2:0 2:1 2:2 2:3 2:4 2:5 2:6 2:7 2:8 2:9
3:0 3:1 3:2 3:3 3:4 3:5 3:6 3:7 3:8 3:9
4:0 4:1 4:2 4:3 4:4 4:5 4:6 4:7 4:8 4:9
5:0 5:1 5:2 5:3 5:4 5:5 5:6 5:7 5:8 5:9
Drill – základní iterace
// 1. Doplňte klíčové slovo pro cyklus, který vypíše čísla od 1 do 10.
(int i = 1; i <= 10; i++) {
printf("%d\n", i);
}
// 2. Doplňte podmínku cyklu tak, aby program vypsal čísla od 1 do 10 včetně.
for (int i = 1; ; i++) {
printf("%d\n", i);
}
// 3. Doplňte inkrementaci cyklu tak, aby se hodnota proměnné j zvyšovala po každém kroku o 1.
for (int j = 1; j <= 10; ) {
printf("%d\n", j);
}
// 4. Napište celou hlavičku cyklu for (včetně proměnné k), který vypíše čísla od 10 do 1.
// (inicializace proměnné k už proběhla dříve, v cyklu ji znovu nedeklarujte)
{
printf("%d\n", k);
}
// 5. Doplňte chybějící operátor v aktualizaci proměnné x, aby cyklus správně klesal od 10 do 1.
for (int x = 10; x >= 1; x) {
printf("%d\n", x);
}
// 6. Doplňte chybějící hodnotu do inicializace cyklu, který má vypsat sudá čísla od 2 do 20.
for (int i = ; i <= 20; i += 2) {
printf("%d\n", i);
}
// 7. Doplňte operaci pro zvýšení proměnné o 2 v každém kroku cyklu, který vypisuje sudá čísla.
for (int sudé = 2; sudé <= 20; ) {
printf("%d\n", sudé);
}
// 8. Doplňte chybějící relační operátor v podmínce cyklu, který vypisuje lichá čísla od 1 do 19.
for (int l = 1; l 20; l += 2) {
printf("%d\n", l);
}
// 9. Napište celou hlavičku cyklu for pro výpis lichých čísel od 1 do 19 (použijte novou proměnnou m).
{
printf("%d\n", m);
}
// 10. Doplňte výraz tak, aby cyklus s proměnnou c vypisoval čísla od 0 do 100 po desítkách.
for (int c = 0; c <= 100; ) {
printf("%d\n", c);
}
// 11. Doplňte chybějící podmínku do cyklu while, který má vykonat přesně 5 opakování pro výpis textu "Ahoj".
int pocitadlo = 0;
while () {
printf("Ahoj\n");
pocitadlo++;
}
// 12. Doplňte inkrementaci řídicí proměnné p uvnitř cyklu while, aby nevznikl nekonečný cyklus.
int p = 0;
while (p < 5) {
printf("Ahoj\n");
;
}
// 13. Doplňte klíčové slovo pro cyklus s podmínkou na konci (do-while), který má 10x vypsat znak '*'.
int hvezdy = 0;
{
printf("*");
hvezdy++;
} while (hvezdy < 10);
// 14. Doplňte podmínku na konci cyklu do-while tak, aby se znak '*' vypsal přesně 10krát.
int z = 0;
do {
printf("*");
z++;
} while ();
// 15. Máme pole: int znamky[10]; Doplňte podmínku cyklu pro průchod všemi 10 prvky (indexy 0 až 9).
for (int index = 0; ; index++) {
printf("%d\n", znamky[index]);
}
// 16. Máme pole: int body[10]; Napište celou hlavičku cyklu for s řídicí proměnnou i pro výpis celého pole.
{
printf("%d\n", body[i]);
}
// 17. Doplňte index do hranatých závorek pro správný výpis aktuálního prvku pole znamky v cyklu.
for (int idx = 0; idx < 10; idx++) {
printf("%d\n", znamky);
}
// 18. Procházíme řetězec: char jmeno[] = "Jan"; Doplňte podmínku cyklu, který běží, dokud nenarazí na ukončovací znak '\0'.
for (int i = 0; ; i++) {
printf("%c\n", jmeno[i]);
}
// 19. Napište celou hlavičku cyklu for s proměnnou i pro průchod řetězcem str až do jeho konce '\0'.
{
printf("%c", str[i]);
}
// 20. Cyklus prochází pole znaků text. Doplňte podmínku do větvení if tak, aby se vypsaly pouze tečky (znak '.').
for (int i = 0; text[i] != '\0'; i++) {
if () {
printf("%c", text[i]);
}
}
// 21. Doplňte podmínku cyklu while, který má běžet tak dlouho, dokud uživatel nezadá číslo 0.
int volba = 1;
while () {
scanf("%d", &volba);
}
// 22. Doplňte inicializaci cyklu for tak, aby odpočítával sekundy od 60 dolů k 0 (včetně).
for (int sekundy = ; sekundy >= 0; sekundy--) {
printf("%d ", sekundy);
}
// 23. Doplňte podmínku do cyklu for, který hledá číslo a projde pole o velikosti 50 prvků (indexy 0 až 49).
for (int k = 0; ; k++) {
if (pole[k] == 7) printf("Nalezeno");
}
// 24. Doplňte operátor pro vytvoření nekonečného cyklu pomocí konstrukce while.
while () {
printf("Tento cyklus běží stále.");
break; // vyskočení z cyklu
}
// 25. Doplňte klíčové slovo, které okamžitě ukončí jakýkoliv cyklus (např. při nalezení hodnoty).
for (int i = 0; i < 100; i++) {
if (pole[i] == -1) {
;
}
}
Drill – základní iterace
// --- PRÁCE S POLEM CELÝCH ČÍSEL --- // Pro následující úlohy předpokládejte pole: int cisla[10]; // V cyklech používejte řídicí proměnnou i. // Vypište všechny prvky pole cisla. // Do všech prvků pole cisla uložte hodnotu 0. // Do všech prvků pole cisla uložte jejich index. // Do všech prvků pole cisla uložte dvojnásobek jejich indexu. // Zvyšte hodnotu všech prvků pole cisla o 1. // Spočítejte součet všech prvků pole cisla. (Předpokládejte připravenou proměnnou: int soucet = 0;) // Nastavte všechny záporné hodnoty prvků pole cisla na nulu. // Vypište pouze sudé prvky (tj. prvky na sudých indexech 0, 2, 4...) pole cisla. // Vypište pouze sudé hodnoty (nikoliv pouze sudé indexy) pole cisla. // Spočítejte počet kladných prvků pole cisla. (Předpokládejte připravenou proměnnou: int pocet = 0;) // Spočítejte součet všech kladných prvků pole cisla. (Předpokládejte připravenou proměnnou: int soucet = 0;) // Zjistěte, zda-li pole obsahuje prvek s hodnotou 6. Jestli ano, vypište "ANO" – jestli ne, vypište "NE". // (Předpokládejte připravenou proměnnou: int nalez = 0;) // Vypište první prvek, jehož hodnota přesahuje 100. (Nezapomeňte cyklus po nalezení ukončit). // Najděte a vypište prvek pole s nejnižší hodnotou (min). (Předpokládejte: int min = cisla[0];) // Najděte a vypište prvek pole s nejvyšší hodnotou (max). (Předpokládejte: int max = cisla[0];) // --- PRÁCE S ŘETĚZCI --- // Pro následující úlohy předpokládejte řetězec deklarovaný jako pole znaků: char jmeno[16]; // Vypište znaky řetězce tak, aby jednotlivé znaky mezi sebou měly mezeru. (Cyklus končí na '\0') // Vypište pouze liché znaky řetězce (znaky na lichých indexech 1, 3, 5...). // Spočítejte počet hvězdiček v řetězci. (Předpokládejte připravenou proměnnou: int pocet = 0;) // Nastavte každý sudý znak v řetězci (indexy 0, 2, 4...) na hvězdičku. // Vypište z řetězce pouze malá písmena. (Pomocí rozmezí znaků v ASCII tabulce).
Procvičování
Zkuste si realizovat následujících 10 jednoduchých cvičení. Cílem je vždy výpis znaků, samozřejmě nikoliv výpis kompletního textu, ale za použití iterací.
- Vypište přesně v tomto formátu:
1 2 3 4 5 6 7 8 9 - Vypište přesně v tomto formátu:
1 3 5 7 9 11 13 15 - Vypište přesně v tomto formátu:
100 90 80 70 60 50 40 30 20 10 - Vypište přesně v tomto formátu:
50 45 40 35 30 25 20 15 10 5 - Vypište přesně v tomto formátu:
*****
*****
***** - Vypište přesně v tomto formátu:
* * * *
* * * *
* * * *
* * * * - Vypište přesně v tomto formátu:
*
**
***
****
***** - Vypište přesně v tomto formátu:
1
12
123
1234
12345 - Vypište přesně v tomto formátu:
1 2 * 3 4 * 5 6 *
1 2 * 3 4 * 5 6 *
1 2 * 3 4 * 5 6 * - Vypište přesně v tomto formátu:
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
Break a continue
Někdy potřebujeme v rámci běhu smyčky udělat takový fine-tuning, tj. nastane-li nějaká situace, můžeme smyčku okamžitě opustit (příkaz break), resp. můžeme ihned pokračovat s další iterací (příkaz continue).

Validace vstupu
Někdy se může stát, že budeme po uživateli chtít nějaká vstupní data. Například v jednoduchém programu budeme chtít zjistit, jakým číslem bude chtít dělit. Jak jistě víme, dělit se dá jakýmkoliv číslem kromě nuly. Musíme tedy zajistit, aby se vstup nerovnal nula. To můžeme udělat buďto jednoduchou selekcí:
printf("Zadejte dělitele: ");
scanf("%f", &fd);
if (fd == 0){
printf("Nulou nelze dělit!");
}
else{
... //výpočet
}
Tato selekce bude bez problému fungovat, ale co když uživatel udělal prostě jenom chybu a rád by v programu pokračoval? To bohužel nejde, protože selekce mu nový vstup neumožní.
K tomuto účelu se více hodí smyčka do-while, která se bude opakovat tak dlouho, dokud uživatel nezadá správné číslo (tedy číslo jiné než nula). Zde pozor na správnou formulaci podmínky – smyčku chceme opakovat pouze v případě, že vstup je nesprávný.
do{
printf("Zadejte dělitele: ");
scanf("%f", &fd);
} while (fd == 0);
... //výpočet
Do sekce za smyčkou do-while se nedostaneme, pokud vstup bude nesprávný.