Programujeme v jazyku C# - Diel 10. - Cykly I.

Michal Čižmár  /  19. 01. 2005, 00:00

Tento diel je o cykle for a trochu si povieme o syntaktických hračkách :-). Cykly v C# sú podobné ako aj v iných programovacích jazykoch, ale aby nedochádzalo k zbytočným chybám pri prechode na C#, je dobré si pozrieť v akých detailoch sa odlišujú napr. od C++.


Tento diel je o cykle for a trochu si povieme o syntaktických hračkách :-). Cykly v C# sú podobné ako aj v iných programovacích jazykoch, ale aby nedochádzalo k zbytočným chybám pri prechode na C#, je dobré si pozrieť v akých detailoch sa odlišujú napr. od C++.

Ani sme sa nenazdali a je tu už 10. jubilejný diel. Myslím si, že tí, čo poctivo čítali všetky diely a skúšali si príklady, vykonali už kus poctivej práce. Verím, že my priaznivci moderného programovacieho jazyka C# sa stretneme aj pri 20-tom dieli a do vtedy sa naše rady určite aj rozšíria.

Takže páni a dúfam, že aj dámy, držte si klobúky, zažíname ďalšiu desiatku !! :-)

>>Načo sú dobré cykly?

Jednoducho ak potrebujete, aby sa určitá časť programu vykonala viackrát, vložíte ju do cyklu. Napr. v článku o maticiach sme potrebovali vypísať každý prvok matice. Stačí teda vytvoriť cyklus (prípadne cykly) na výpis jedného prvku s tým, že sa budú postupne meniť parametre, ktoré nám určujú, ktorý z prvkom chceme vypísať.

>>Najpoužívanejší cyklus - cyklus for
S týmto cyklom sme sa už stretli veľakrát. Pre tých, čo ešte neprogramovali v inom jazyku, môže byť stále ešte trochu nejasný a preto uvádzam syntax, príklad a vysvetlenie :

Syntax cyklu for:

for( inicializácia, podmienka, krok ) { }

Príklad 10.1

using
System;
class
MainClass
{
  
public static void Main()
   {
 
int i;
 
int pocetKrokov = 3;
 
for(i = 0; i < pocetKrokov; i++) // cyklus 1.
  {
     
Console.WriteLine(" krok = {0}",i);
  }
  
Console.WriteLine(" Po skonceni cyklu i ={0}",i);


 for(int j = pocetKrokov-1; j >= 0; j--)
 {
    
Console.WriteLine(" krok = {0}",j); // cyklus 2.
 }
   //
Console.WriteLine(" Po skonceni cyklu j ={0}",j); //chyba
  
}

Na začiatku programu sme si vytvorili premennú i, ktorú používame v cykle ako počitadlo krokov. Takejto premennej sa hovorí iteračná premenná.
1. Na začiatku cyklu sme nastavili iteračnú premennú na počiatočnú hodnotu príkazom i=0. Iteračná premenná sa nastavuje len raz a v ďalšej slučke sa krok 1. už neopakuje.
2. Potom sa testuje logická podmienka. Kedže je splnená (t.j. 0<5), vchádzame do cyklu.
3. Vypíše sa, že krok=0.
4. Na konci cyklu sa zvýši hodnota iteračnej premennej o 1 príkazom i++, ktorý je v hlavičke cyklu. To je dosť dôležité si zapamätať!! Keď sa ešte raz pozriete na syntax cyklu for, tak pod časťou krok si môžete predstaviť ľubovólny príkaz, ktorý sa má vykonať po prebehnutí slučky aj keď sa v ďalšom kroku celý cyklus ukončí, pretože nebola splnená podmienka.

Toto vypíše príklad 10.1

krok = 0
krok = 1
krok = 2
Po skonceni cyklu i =3
krok = 2
krok = 1
krok = 0

>>Čo je to za príkaz i++ ?

Takémuto typu príkazov hovorím syntaktická hračka, t.j. ako napísať niečo jednoduchšie. Niektorí tomu hovoria syntaktický cukor (bezhlavo prevzali z angličtiny výraz syntax sugar), ale ja myslím aj na programátorov diabetikov :-). V našom prípade je ++ operátor inkrementovania. Ide o typ unárneho operátora, to znamená, že sa vzťahuje iba na jeden operand (premennú). Klasické + je binárny operátor ( 5 + 6 , dva operandy).

i++ je to iste ako i = i + 1 // inkrementovanie
i-- je to isté ako i = i - 1 // dekrementovanie

>>Na ktorú stranu sa môže písať operátor ++ ?

Aj na pravú, aj na ľavú stranu premennej. Potom je ale dôležité poradie vyhodnocovania príkazu.

POZOR!!!

i++ znamená, ža sa najprv vyhodnotí obsah premennej i a potom sa zväčší jej hodnota.
++i najpr sa zväčší hodnota premennej i a potom sa vyhodnotí jej obsah.

Príklad 10.2

using System;

class MainClass
{
       
public static void Main()
      {
          
int i = 5;
          
int j, k, m ;

          
j = i++; // potom i je 6
         
k = ++i; // teraz uz i = 7
         
m = i++ + 2; // a teraz i=8
         
Console.WriteLine("j={0} k={1} m={2}",j,k,m);
      }
}

Program vypíše toto : j=5 k=7 m=9
Konkrétne príkaz j=i++ znamená, že najprv sa vyhodnotí hodnota premennej i (=5), táto hodnota sa vloží do premennej j a na koniec sa zvýši hodnota premennej i na 6.

Dokonca by fungovalo aj tretie priradenie, keby sme napísali m=i+++2 (bez medzier), pretože prekladač analyzuje výraz zľava doprava a tak prvé dve pluská považuje za unárny operátor a tretie plusko, ako klasické +. Ale takýto zápis je neprehľadný.
POZOR!!
Niečo takéto nefunguje : int z = ++(j+k);

>>Musí sa krok iba zvyšovať/znižovať o 1 v cykle for?

Samozrejme, že nie!
Ak chcete zvyšovať krok o 2, vyzerala by hlavička for takto :

for
(i = 0; i < pocetKrokov; i = i+2) alebo
for
(i = 0; i < pocetKrokov; i += 2) .

kde i+=2 je ďalšia zo syntaktických hračiek, ktorá sa dá robiť aj z inými matematickými operátormi, napr. i *=5 je to isté ako i = i *5 .

>>Lokálne iteračné premenné


Vráťme sa ešte raz k prvému príkladu. Hlavička druhého cyklu for bola takáto :
for(int j = pocetKrokov-1; j >= 0; j--)

vidíte, že iteračnú premennú j sme deklarovali v hlavičke a môžeme ju používať ako bežnú premennú až na to, že existuje iba vo vnútri cyklu. Keby sme chceli vypísať jej hodnotu po dokončení cyklu, tak to nepôjde, pretože kompilátor vám zahlási, že taká premenná neexistuje (nie je nikde deklarovaná v danom kontexte).

POZOR!
Pre programátorov C++.
V C# nie je povolené vytvárať lokálne premenné s takým istým menom premennej, ako sa vyskytuje v nadradenom bloku.
int i;
for(int i=0; i<5; i++); nefunguje!!!!

>>Musí byť hlavička cyklu for vždy úplná?

Nemusí. Najlepšie je si pozrieť príklad :

Príklad 10.3

using System;

class MainClass
{
 
public static void Main()
  {
        
int i=0;
        
for(  ; i < 5 ; i++) 
       
Console.WriteLine("i={0}",i);
 
    
for(i=0; i< 5;   )
    {
       
Console.WriteLine("i={0}",i);
       
i++; // inkrementujeme vo vnutri cyklu
     } 
  
     
//for( ;  ; ) ;  
      // ked vynechame vsetko
      / / je to nekonecna slucka
   
}
}

Poznámka! Ak sa cyklus skladá iba z jedného príkazu, nie je potrebné uzatvárať jeho telo do zložených {} zátvoriek. Vidno to na prvom cykle for v príklad 10.3. To či to budete využívať je len na vás a záleží na tom, čo sa vám zdá prehľadnejšie.


>>Čo bude nabudúce?

Budeme pokračovať v sérií článkov o cykloch. Preberieme si ďalší typ cyklu - while a príkazy break, continue.

>>Predchádzajúce diely :
Programujeme v jazyku C# - Diel 9. - Konštanty a enumerata
Programujeme v jazyku C# - Diel 8. - Polia IV.
Programujeme v jazyku C# - Diel 7. - Polia III.
Viac na : www.inet.sk/CSharp


>>Príklady na stiahnutie :
www.inet.sk/download/user/Priklad10.1_JednoduchyCyklusFor.zip
www.inet.sk/download/user/Priklad10.2_operatorInkrementovania.zip
www.inet.sk/download/user/Priklad10.3_neuplneFor.zip

Ak máte vlastné návrhy, k čomu by som sa mal vrátiť alebo to vysvetliť podrobnejšie, napíšte mi e-mail.

Michal Čižmár

micitn@orangemail.sk

SEE YOU!







Neprehliadnite: