fel
le

A while ciklus

A C# egyik ciklusát a while kulcsszóval lehet felépíteni. Általános alakja:

1. ábra: A while ciklus általános felépítése

A while kulcsszó után az if-hez hasonlóan a logikai feltételt zárójelben kell megadni. A while-ról az előző fejezetben leírtak szerint tudnunk kell, hogy

  • pozitív vezérlésű,
  • előltesztelő

ciklus, vagyis legelső lépésben máris a vezérlő feltétel kiértékelésével kezd, majd amennyiben az igaz értékű, úgy végrehajtja a ciklusmag utasításait. Ezek utát újra a ciklus vezérlő feltételének kiértékelése következik. A két fázis egymást követve ismétlődik, amíg egyszer a vezérlő feltétel végre hamis értékű nem lesz. Ekkor a ciklus futása megáll (a program futása természetesen nem). A program futása a ciklust követő következő utasítás végrehajásával folytatódik (a szekvencia szabályban foglaltaknak megfelelően).

A while ciklus ennek megfelelően lehet hogy egyetlen alkalommal sem hajtja végre a ciklusmagját, míg a másik véglet is előfordulhat: a vezérlő értéke minden kiértékeléskor igaz értékű lesz. Ez utóbbi esetben végtelen ciklusról beszélünk.

Példa - adatbekérés

int a=0;
while (a<=0)
{
  Console.Write("Kérek egy pozitív számot:");
  a = int.Parse(Console.ReadLine());
}
Console.WriteLine("A szám kétszerese = {0}",a*2);
 

A fenti kis programrészlet addig kér be számokat billentyűzetről, amíg a kezelő az utasításnak megfelelően valóban pozitív számot nem ír be. Amennyiben csalni próbálna, és negatív számokat írna be, úgy a ciklus megismétli a futását.

A példában több apró kis trükk található. Vegyük először is észre, hogy az a változó deklarációja a cikluson kívül található, nem a ciklus belsejében, az adatbekérés sorában. Több variáció is előfordulhat a próbálkozásaink során, de mindegyiknek megvan a maga hibája:

// HIBÁS !!!
while (int a<=0)
{
  Console.Write("Kérek egy pozitív számot:");
  a = int.Parse(Console.ReadLine());
}
Console.WriteLine("A szám kétszerese = {0}",a*2);
 

Ez esetben két hiba is van:

  • az a változó deklarációja a while utasítás belsejében történik meg, így a ciklusmagban bár van hatásköre, de a ciklust követő programkódban már nincs a változó hatáskör, így a kétszeres kiírás helyén sem.
  • az a változó deklarációjához nem tartozik kezdőértékbeállítás, így a vezérlő feltétel első kiértékelése közben az a változó definiálatlannak tekinthető, nem megállapítható, hogy az aktuális értéke kisebb vagy egyenlőe mint a nulla.

// HIBÁS !!!
while (a<=0)
{
  Console.Write("Kérek egy pozitív számot:");
  int a = int.Parse(Console.ReadLine());
}
Console.WriteLine("A szám kétszerese = {0}",a*2);
 

Ez esetben is két hiba van:

  • a ciklus vezérlő feltételében még az a változó deklarálatlan, hisz deklarációja 2 sorral lejjebb történik meg.
  • a ciklusmagon kívül továbbra sincs a változó, melynek hatásköre lenne

// HIBÁS !!!
while (int a<=0)
{
  Console.Write("Kérek egy pozitív számot:");
  int a = int.Parse(Console.ReadLine());
}
Console.WriteLine("A szám kétszerese = {0}",a*2);
 

A fenti kód esetén fennáll a korábban leírt hiba, mely szerint az a változó kezdőértékének hiányában az első lefutáskor nem kiértékelhető a ciklus vezérlő feltétel. Ugyanakkor a ciklusmagban újra deklaráljuk az a változót - holott annak a ciklusmagban van hatásköre. Változók esetén hatáskörön belüli újradeklarálás hibának minősül.

// NEM HIBÁS, DE NEM IS JÓ !!
int a=1;
while (a<=0)
{
  Console.Write("Kérek egy pozitív számot:");
  a = int.Parse(Console.ReadLine());
}
Console.WriteLine("A szám kétszerese = {0}",a*2);
 

Nagyon ügyeljünk a változó kezdőértékének beállítására. Az a változó kezdőértékének megadása egyetlen okból fontos - hogy a vezérlő feltétel első esetben kiértékelhető legyen. Olyan kezdőérték kell, mely ráveszi a ciklust a ciklusmagjának lefuttatására. A továbbiakban a kezdőérték már nem fontos, hiszen a ciklusmagban az a értékét aktuális értékétől független módon felülírjuk, így a ciklusmag további lefutásai vagy nem lefutásai már függetlenek a kezdőértéktől.

A fenti kódban a kezdőértéké rosszul került megválasztásra. Az a=1 miatt a ciklus vezérlő feltételének első kiértékelése máris hamis értéket eredményez, így a ciklus el sem indul, hanem azonnal ugrunk a kétszeres kiírására. Ez esetben az a értéke még mindíg 1, vagyis a programunk kiírja a 2-t, mint kétszeres értéket. Sikerült kemény munkával tehát egy olyan programot létrehoznunk, mely minden lefutásakor kiírja: a szám kétszeres = 2.

Példa - 2

Gyakori eset, hogy a ciklusmag lefutásának darabszáma előre ismert. Ekkor alkalmazhatunk egy olyan számlálót, melynek értékét minden lefutáskor növeljük egyel. Eképpen ellenőrízhetjük, hogy a futások száma elérte-e már a kívánt értéket. Az alábbi program 10-szer írja ki a megadott szöveget, az a értéke azt mutatja meg, hanyadik futásnál tartunk.

int a=1;
while (a<=10)
{
  Console.Write("Jó reggelt Magyarország!");
  a = a+1;
}
 

Ugyanezt megoldhatjuk a visszafele számolással is. Ekkor az a értéke azt mutatja, hány futás van még hátra:

int a=10;
while (a>=1)
{
  Console.Write("Jó reggelt Magyarország!");
  a = a-1;
}
 
Hernyák Zoltán
2013-01-24 10:46:32