6. diel - Cykly v C# .NET - for a while
V predchádzajúcom cvičení, Riešené úlohy k 5. lekcii C# .NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Teraz prejdeme k cyklom. Po dnešnom C# .NET tutoriále už budeme mať takmer kompletnú výbavu základných konštrukcií a budeme schopní tvoriť rozumné aplikácie.
Cykly
Ako už slovo cyklus napovedá, niečo sa bude opakovať. Keď chceme v programe niečo urobiť 100x, určite nebudeme písať pod seba 100x ten istý kód, ale vložíme ho do cyklu. Cyklov máme niekoľko druhov, vysvetlíme si, kedy ktorý použiť. Samozrejme si ukážeme praktické príklady.
for
cyklus
Tento cyklus má stanovený pevný počet opakovaní a
hlavne obsahuje tzv. riadiacu premennú (celočíselnú), v ktorej sa postupne
pri behu cyklu menia hodnoty. Syntax (zápis) cyklu for
je
nasledovná:
for (variable; condition; command)
variable
je riadiaca premenná cyklu, ktoré nastavíme počiatočnú hodnotu (najčastejšie0
, pretože v programovaní všetko začína od nuly, nie od jednotky). Napr. tedaint i = 0
. Samozrejme si môžeme premennú vytvoriť aj niekde nad tým a už nemusíme písať slovoint
, býva ale zvykom používať práveint i
.condition
je podmienka vykonania ďalšieho kroku cyklu. Akonáhle podmienka nebude platiť, cyklus sa ukončí. Podmienka môže byť napr.(i < 10)
.command
nám hovorí, čo sa má v každom kroku s riadiacou premennou štát. Teda či sa má zvýšiť alebo znížiť. Na to využijeme špeciálnych operátorov++
a--
. Tie samozrejme môžete používať úplne bežne aj mimo cyklus, slúžia na zvýšenie alebo zníženie premennej o1
.
Poďme si uviesť jednoduchý príklad: väčšina z nás určite pozná Sheldona z The Big Bang Theory. Pre tých, ktorí nie, budeme simulovať situáciu, keď Sheldon klope na dvere svojej susedky. Vždy 3x zaklope a potom zavolá: "Penny!". Náš kód by bez cyklov vyzeral takto:
{CSHARP_CONSOLE}
Console.WriteLine("Knock");
Console.WriteLine("Knock");
Console.WriteLine("Knock");
Console.WriteLine("Penny!");
Console.ReadKey();
{/CSHARP_CONSOLE}
My už ale nemusíme nič otrocky opisovať:
{CSHARP_CONSOLE}
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Knock");
}
Console.WriteLine("Penny!");
Console.ReadKey();
{/CSHARP_CONSOLE}
Konzolová aplikácia
Knock
Knock
Knock
Penny!
Cyklus prebehne 3x, spočiatku je v premennej i
nula, cyklus
vypíše „Knock“ a zvýši premennú i
o jedna. Potom beží
rovnako s jednotkou a dvojkou. Akonáhle je v i
trojka, už
nesúhlasí podmienka i < 3
a cyklus sa ukončí. O
vynechávaní zložených zátvoriek platí to isté čo pri podmienkach. V
tomto prípade tam nemusí byť, pretože cyklus spúšťa iba jediný príkaz.
Teraz môžeme do deklarácie cyklu namiesto trojky napísať desiatku. Príkaz
sa spustí 10x bez toho, aby sme museli písať niečo navyše. Určite vidíte,
že cykly sú mocným nástrojom.
Keď niekam potrebujeme napísať for
cyklus,
môžeme využiť snippet
vo Visual Studiu. Napíšeme len for
a dvakrát stlačíme
Tabuľátor. Zvyšok kódu sa sám doplní. Skúste si to.
Skúsme teraz využiť to, že sa nám premenná inkrementuje. Vypíšme si
čísla od jednej do desať. Pretože nebudeme chcieť, aby sa nám v konzole
text vždy odriadkoval, použijeme namiesto WriteLine()
iba
Write()
:
{CSHARP_CONSOLE}
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i);
Console.ReadKey();
{/CSHARP_CONSOLE}
Vidíme, že riadiaca premenná má naozaj v každej iterácii (priebehu)
inú hodnotu. Všimnite si, že v cykle tentoraz nezačíname na nule, ale
môžeme nastaviť počiatočnú hodnotu 1
a koncovú
10
. V programovaní je však zvykom začínať od nuly, neskôr
zistíme prečo.
Teraz si vypíšeme malú násobilku (násobky čísel 1 až 10, vždy do
desiatich). Stačí nám urobiť cyklus od 1
do 10
a
premennú vždy násobiť daným číslom. Mohlo by to vyzerať asi takto:
{CSHARP_CONSOLE}
Console.WriteLine("Here's a simple multiplication table using loops:");
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 2);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 3);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 4);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 5);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 6);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 7);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 8);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 9);
Console.WriteLine();
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * 10);
Console.ReadKey();
{/CSHARP_CONSOLE}
Výsledok:
Konzolová aplikácia
Here's a simple multiplication table using loops:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Program funguje pekne, ale stále sme toho dosť napísali. Pokiaľ vás napadlo, že v podstate robíme 10x to isté a iba zvyšujeme číslo, ktorým násobíme, máte pravdu. Nič nám nebráni, aby sme vložili 2 cykly do seba:
{CSHARP_CONSOLE}
Console.WriteLine("Here's a simple multiplication table using loops:");
for (int j = 1; j <= 10; j++)
{
for (int i = 1; i <= 10; i++)
Console.Write("{0} ", i * j);
Console.WriteLine();
}
Console.ReadKey();
{/CSHARP_CONSOLE}
Pomerne zásadný rozdiel, že? Pochopiteľne nemôžeme použiť pri oboch
cykloch i
, pretože sú vložené do seba. Premenná j
nadobúda vo vonkajšom cykle hodnôt 1
až 10
. V
každej iterácii (rozumajte priebehu) cyklu je potom spustený ďalší cyklus
s premennou i
. Ten je nám už známy, vypíše násobky, v tomto
prípade násobíme premennú j
. Po každom behu vnútorného cyklu
je potrebné odriadkovať, to vykoná Console.WriteLine()
. Môžete
si skúsiť vypísané riadky upraviť pomocou metódy PadLeft()
tak, aby boli čísla pekne v stĺpcoch.
Urobme si ešte jeden program, na ktorom si ukážeme prácu s vonkajšou premennou. Aplikácia bude vedieť spočítať ľubovoľnú mocninu ľubovoľného čísla:
{CSHARP_CONSOLE}
Console.WriteLine("Exponent calculator");
Console.WriteLine("===================");
Console.WriteLine("Enter the base: ");
int a = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the exponent: ");
int n = int.Parse(Console.ReadLine());
int result = a;
for (int i = 0; i < (n - 1); i++)
result = result * a;
Console.WriteLine("Result: {0}", result);
Console.WriteLine("Thank you for using our exponent calculator");
Console.ReadKey();
{/CSHARP_CONSOLE}
Asi všetci tušíme, ako funguje mocnina. Pre istotu pripomenieme, že
napríklad 23 = 2 * 2 * 2. Teda an spočítame tak, že
n-krát vynásobíme číslo a
číslom a
. Výsledok
si samozrejme musíme ukladať do premennej. Spočiatku bude mať hodnotu
a
a postupne sa bude v cykle prenásobovať (viac v lekcii Výpočet
ľubovoľnej mocniny). Vidíme, že naša premenná result
je v
tele cyklu normálne prístupná. Pokiaľ si však nejakú premennú založíme
v tele cyklu, po skončení cyklu zanikne a už prístupná nebude:
Konzolová aplikácia
Exponent calculator
===================
Enter the base:
2
Enter the exponent:
3
Result: 8
Thank you for using our exponent calculator
Už tušíme, na čo sa for
cyklus využíva. Zapamätajme si,
že počet opakovaní je pevne daný. Do premennej cyklu by sme
nemali nijako zasahovať ani do nej nič dosadzovať, program by sa mohol tzv.
zacykliť. Skúsme si ešte posledný, odstrašujúci príklad:
{CSHARP_CONSOLE}
// this code is wrong
for (int i = 1; i <= 10; i++)
i = 1;
Console.ReadKey();
{/CSHARP_CONSOLE}
Au, vidíme, že program sa zasekol. Cyklus stále inkrementuje premennú
i
, ale tá sa vždy zníži na 1
. Nikdy teda
nedosiahne hodnotu > 10
, cyklus nikdy neskončí. Okno programu
zatvoríme alebo použijeme tlačidlo Stop v lište Visual Studia.
while
cyklus
Cyklus while
funguje inak: jednoducho opakuje príkazy v bloku,
pokiaľ platí podmienka. Syntax cyklu je nasledovná:
while (condition) { // commands }
Pokiaľ vás napadá, že je možné cez while
cyklus urobiť aj
for
cyklus, máte pravdu Cyklus for
je vlastne špeciálny prípad
while
cyklu. Cyklus while
sa ale používa na trochu
iné veci, v jeho podmienke často máme napr. metódu vracajúcu logickú
hodnotu true
/ false
. Pôvodný príklad z
for
cyklu by sme urobili pomocou while
nasledovne:
{CSHARP_CONSOLE}
int i = 1;
while (i <= 10)
{
Console.Write("{0} ", i);
i++;
}
Console.ReadKey();
{/CSHARP_CONSOLE}
To ale nie je ideálne použitie while
cyklu. Zoberme si našu
kalkulačku z minulých lekcií a opäť ju trochu vylepšime, konkrétne o
možnosť zadať viac príkladov. Program teda hneď neskončí, ale spýta sa
používateľa, či si praje spočítať ďalší príklad. Pripomeňme si
pôvodnú verziu kódu (je to tá verzia so switch
, ale pokojne
použite aj tú bez neho, záleží na vás):
{CSHARP_CONSOLE}
Console.WriteLine("Welcome to our calculator");
Console.WriteLine("Enter the first number:");
double a = double.Parse(Console.ReadLine());
Console.WriteLine("Enter the second number:");
double b = double.Parse(Console.ReadLine());
Console.WriteLine("Choose one of the following operations:");
Console.WriteLine("1 - addition");
Console.WriteLine("2 - subtraction");
Console.WriteLine("3 - multiplication");
Console.WriteLine("4 - division");
int option = int.Parse(Console.ReadLine());
double result = 0;
switch (option)
{
case 1:
result = a + b;
break;
case 2:
result = a - b;
break;
case 3:
result = a * b;
break;
case 4:
result = a / b;
break;
}
if ((option > 0) && (option < 5))
Console.WriteLine("Result: {0}", result);
else
Console.WriteLine("Invalid option");
Console.WriteLine("Thank you for using our calculator. Press any key to end the program.");
Console.ReadKey();
{/CSHARP_CONSOLE}
Teraz vložíme takmer celý kód do while
cyklu. Našou
podmienkou bude, že používateľ zadá "yes", budeme teda kontrolovať obsah
premennej goOn
. Spočiatku bude táto premenná nastavená na
"yes", aby sa program vôbec spustil, potom do nej necháme načítať voľbu
užívateľa:
Console.WriteLine("Welcome to our calculator"); string goOn = "yes"; while (goOn == "yes") { Console.WriteLine("Enter the first number:"); double a = double.Parse(Console.ReadLine()); Console.WriteLine("Enter the second number:"); double b = double.Parse(Console.ReadLine()); Console.WriteLine("Choose one of the following operations:"); Console.WriteLine("1 - addition"); Console.WriteLine("2 - subtraction"); Console.WriteLine("3 - multiplication"); Console.WriteLine("4 - division"); int option = int.Parse(Console.ReadLine()); double result = 0; switch (option) { case 1: result = a + b; break; case 2: result = a - b; break; case 3: result = a * b; break; case 4: result = a / b; break; } if ((option > 0) && (option < 5)) Console.WriteLine("Result: {0}", result); else Console.WriteLine("Invalid option"); Console.WriteLine("Would you like to make another calculation? [yes/no]"); goOn = Console.ReadLine(); } Console.WriteLine("Thank you for using our calculator. Press any key to end the program."); Console.ReadKey();
Konzolová aplikácia
Welcome to our calculator
Enter the first number:
12
Enter the second number:
128
Choose one of the following operations:
1 - addition
2 - subtraction
3 - multiplication
4 - division
1
Result: 140
Would you like to make another calculation? [yes/no]
yes
Enter the first number:
-10,5
Enter the second number:
Našu aplikáciu je možné teraz používať viackrát a je takmer hotová. Už toho vieme celkom dosť, začína to byť zábava, však?
Operátor ++
Na záver si ešte spomenieme niečo viac o operátorovi ++
. Už
vieme, že zvýši hodnotu ľubovoľnej číselnej premennej o 1
.
Môžeme ho teda používať aj mimo for
cyklus, teda v bežnom
kóde, napr.:
{CSHARP_CONSOLE}
int points = 0;
Console.WriteLine("Is the Sun a ball of hot gases?");
string correctAnswer = "yes";
string answer = Console.ReadLine();
if (answer.ToLower() == correctAnswer.ToLower()) {
points++;
Console.WriteLine("Correct, you have a total of {0} points", points);
}
{/CSHARP_CONSOLE}
Pokiaľ zadáme správnu odpoveď, kód vyššie vypíše:
Konzolová aplikácia
Is the Sun a ball of hot gases?
yes
Correct, you have a total of 1 points
Pokiaľ patríte k ľuďom, ktorí si naozaj radi skracujú svoj kód,
môžete využiť to, že operátory ++
a --
hodnotu
čísla aj vracajú. Možno ich teda použiť priamo
ako hodnotu, aj keď je kód potom menej čitateľný, pretože na
jednom riadku prebiehajú 2 veci:
- Hodnota sa zvýši alebo zníži o
1
. - Hodnota sa vráti napríklad k výpisu, ktorý môže byť na tom istom riadku.
Operátory takto môžeme použiť dokonca dvoma spôsobmi a vrátiť si tak buď novú hodnotu, alebo tú pred zvýšením/znížením:
variable++
alebovariable--
– Vráti súčasnú hodnotu a až potom zvýši/zníži hodnotuvariable
o1
.++variable
alebo--variable
– Zvýši/zníži hodnotuvariable
o1
a vráti novú hodnotu.
Túto znalosť teraz využime pri príklade kvízu vyššie:
{CSHARP_CONSOLE}
int points = 0;
Console.WriteLine("Is the Sun a ball of hot gases?");
string correctAnswer = "yes";
string answer = Console.ReadLine();
if (answer.ToLower() == correctAnswer.ToLower())
Console.WriteLine("Correct, previously you had {0} points and now you have 1 more!", points++);
{/CSHARP_CONSOLE}
Výsledok je teraz nasledujúci:
Konzolová aplikácia
Is the Sun a ball of hot gases?
yes
Correct, previously you had 0 points and now you have 1 more!
Hodnota premennej points
je teraz naozaj 1
, hoci vo
výpise máme 0
. Operátor ++
hodnotu premennej na
danom riadku totiž najprv vrátil a až potom zvýšil. Nám sa však skôr
hodí napísať operátor ++
pred premennou, aby sme
dosiahli ten istý výpis ako predtým:
{CSHARP_CONSOLE}
int points = 0;
Console.WriteLine("Is the Sun a ball of hot gases?");
string correctAnswer = "yes";
string answer = Console.ReadLine();
if (answer.ToLower() == correctAnswer.ToLower())
Console.WriteLine("Correct, you have a total of {0} points", ++points);
{/CSHARP_CONSOLE}
Teraz je výsledok rovnaký ako pôvodne:
Konzolová aplikácia
Is the Sun a ball of hot gases?
yes
Correct, you have a total of 1 points
Kód funguje úplne rovnako ako ten vyššie, najskôr zvýši hodnotu
premennej points
a potom sa táto hodnota odovzdá k výpisu.
Z hľadiska prehľadnosti odporúčame túto praktiku skôr nepoužívať. Že je premenná modifikovaná, a nie len vypisovaná sa dá totiž veľmi ľahko prehliadnuť, najmä keď je text dlhší a koniec riadku tak nie je vidieť. Avšak na podobné kódy môžete naraziť v cudzích projektoch, a preto je dobre, že sme si tu túto praktiku ukázali.
V nasledujúcom cvičení, Riešené úlohy k 6. lekcii C# .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 8x (198.97 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#