C kezdőknek – 4. rész

 

Ebben a részben a ciklusokkal fogunk foglalkozni. Mi is az a ciklus? Sokszor találkozhatunk olyan algoritmussal, hogy egy tevékenységet vagy tevékenység csoportot többször végre szeretnénk hajtani. Elvileg háromféle ciklust (iterációt) különböztetünk meg:

·        a léptető ciklust, amelyet akkor alkalmazunk, ha tudjuk, hogy hányszor akarjuk végrehajtani az iterációt - pl. egy adatbázis rekordjainak kiíratása, vagy tömbökön végzett műveletek, ennek szintaktikai megvalósításra szolgál a for ciklus;

·        az elöltesztelő ciklust, amikor valamely feltétel teljesüléséig hajtjuk végre az ismételt műveleteket, ennek tipikus alkalmazása a beolvasás végjelig algoritmusa, szintaktikai megvalósítása pedig a while ciklus; és

·        a hátultesztelő ciklust, amikor egyszer mindenképpen végre akarjuk hajtani a ciklusmagban található utasításokat és egy bentmaradási feltételt fogalmazunk meg, azaz addig végezzük az ismételt tevékenységeket, amíg a feltétel igaz nem lesz. Ennek szintaktikai megvalósítása pedig a do-while ciklus.

 

Nos, nézzünk ezekre példákat is! Mindegyik példa esetében a kód szintaktikai "kerete" a következő:

 

#include <stdio.h>

 

void main() {

  // ide jön a példa kódja

}

 

A for ciklus szintaktikája és használata:

Képzeljük el, hogy van egy tömbünk, amelyet fel akarunk tölteni a megfelelő elemekkel, vagy éppen ki akarjuk olvasni az elemeket. Ilyen tömb a karaktertömb is, amelyben a C-nyelv keretei között szövegeket tárolunk. Feladatunk például a karakterek, azok indexének és ASCII kódjainak kiírása adott szövegben.

 

char szoveg[6] = "almafa";

for (int j=0; j<6; j++)

  printf("\nA tömb %d. eleme: %c ", j, szoveg[j]);

 

Akkor is for ciklusra esik a választásunk, amikor szükségünk van egy lépésenként növekvő vagy csökkenő változóra, például ki akarjuk írni a négyzetszámokat ezerig.

 

for (int i=0; i*i<1000; i++)

  printf("%d ", i*i);

Elemezzük a kódokat! A for ciklus fejének első utasításában előkészítjük a ciklust, kezdőértéket adunk a ciklusváltozónak. A második paraméter adja meg, hogy meddig fusson a ciklus - ez a feltétel kifejezés is lehet. Ha a feltétel nem igaz, a ciklus leáll. Az utolsó pedig a léptetési utasítás, „i++” a ciklusváltozó értékét eggyel növeli. Persze nagyobb lépésköz is megadható, például: i = i + 2, de elegánsabban: i += 2. Figyeljük meg azt is, hogy a printf() függvény egy ún. format sztringet kap paraméternek, ezzel tudunk formázott érték kiíratásokat végezni.

 

Az iterációk között olyan is előfordulhat, hogy nem tudjuk előre, meddig ismétlődjön egy utasítás(blokk), hanem feltételhez szeretnénk kötni az ismételt végrehajtást. Ezekre mind kínál a C megoldásokat - rögtön kettőt is - a rá jellemző áttekinthetően felépített elegáns formában.

Elsőként a while ciklust tárgyaljuk, egy tipikus algoritmus keretében, amikor számokat kérünk be végjelig (-1) ezeket összegezzük és kiszámítjuk, majd kiírjuk a bevitt számok átlagát:

 

float szam=0, atlag=0;

int ct=0;

//úgynevezett előolvasást végzünk

printf("\nKérek egy számot, kilépés (-1): ");

scanf("%f", &szam);

while (szam != -1) { // kezdődik a ciklus

  ct++; //segédváltozó, számolja a bevitt számokat

  atlag += szam;

//beolvasás a ciklus belsejében, a következő iterációhoz

  printf("Kérek egy számot, kilépés (-1): ");

  scanf("%f", &szam);

} // ciklus vége

//kiszámítjuk és kiírjuk az átlagot, ha volt értékbevitel!

if (ct != 0) {

  atlag /= ct;

  printf("A beolvasott számok átlaga: %f", atlag);

}

A kommentek magukért beszélnek, a változók is ún. "beszédes" azonosítók, tehát látható rajtuk, mit tárolnak. Érdekes megfigyelni még a beolvasást is, amikor a scanf() függvény a formázó karakternek megfelelően (%f, azaz float) olvassa be a billentyűzetről, a standard inputról az adatot és ezt a (&) címképző operátorral a változó címére írja a memóriában.

 

Mi van azonban akkor, ha a ciklusnak egyszer mindenképpen le kell futnia - mint például egy menü megjelenítésekor? Ennek szintaxisa a do-while ciklus, amit most egy egyszerű menü elkészítésén keresztül mutatunk be:

 

int s ;

do {

  printf("\nEgyszerű menü:");

// a menüpontok kiíratás

  printf("\n1. menüpont (1) \n2. menüpont (2) \n3. menüpont (3) \n   kilépés (0)\n"); a

  scanf("%d", &s); // a pontválasztó szám beolvasása

// az esetszétválasztást a már ismert switch szerkezet végzi:

  switch(s) {

    case 1 :

      printf("\n 1. menüpont végrehajtva");

      break;

    case 2 :

      printf("\n 2. menüpont végrehajtva");

      break;

    case 3 :

      printf("\n 3. menüpont végrehajtva");

    }

} while (s != 0) ;

 

Mit keres a switch szerkezetben a break utasítás? Azt, amit a neve sugall (törés), ezen a ponton a végrehajtás a blokkból kilép és az utána következő első utasításra ugrik. E nélkül - a belépési ponttól függően - a többi case utasítás is végrehajtásra kerülne. Használjuk ciklus belsejében is, ha valami bonyolult, többrészes feltétel van, ami nem kezelhető le jól a ciklus fejében - erre jó példa lehet egy játékprogram, ahol a játék többféleképpen érhet véget.

A másik utasítás, amit szintén itt illik megemlíteni, a continue. Ezt akkor használjuk, ha valamiért szeretnénk kilépni a ciklus aktuális futásából és a következő iterációval kívánjuk folytatni a program végrehajtását - mondjuk, valami oda nem való érték került be a ciklusba vagy az adott értéknél nincs értelme az aktuális iteráció végrehajtásának.

Persze a continue hatására a ciklus tovább pörög, a következő körrel folytatjuk, amíg a ciklus belépési vagy bentmaradási feltétele igaz nem lesz.

 

Akkor hát stílszerűen kiadjuk magunknak is a continue utasítást, ennyit erre a hónapra, remélem a következő hónapban is megtisztelnek érdeklődésükkel.

 

Szelei Tamás - d4mi3n@mail.com