04. Vezérlési szerkezetek

A szekvencia - utasítások sorozata

A C#-ben ugyanúgy, mint más programozási nyelvekben a forrásszöveg utasításainak végrehajtása alapvetően fentről lefelé zajlik. Ilyen módon csak szekvenciális programokat lehet írni, azonban rövid tanulás után szükségessé válik elágazásokat és ciklusokat tartalmazó programok írása is. A vezérlési szerkezetek, mint mindig itt is a C-hez hasonlóak.

A program a különböző irányokba való továbbhaladását általában egy kifejezés határozza meg. Ennek a kifejezésnek az értéke logikai alapvetően, azonban a C# nem különböztet meg külön logikai értékeket, hanem a 0 és a nem 0 értékek jelentik azt. Ilyen módon, ha egy numerikus kifejezés 0, akkor hamis, és ha nem 0, akkor igaznak tekinthető. Ha egy string kifejezés üres, akkor hamis, ha van értéke, akkor igaz. Az olyan változók, amelyeket még azelőtt értékelünk ki, hogy értéket kaptak volna (ez nem helyes), a NULL értékkel bírnak.

Elágazás - szelekció

Az első fontos lehetőség a feltételhez kötött végrehajtás. Ha bármelyik ágon több utasítást akarunk végrehajtatni (kódblokk!), akkor szintén a C szintaktika szerint { ...} jelpárost kell használnunk

if( utasítás) ...
if(kifejezés) utasítás; 

if(kifejezés) {
    utasítás1;
    utasitas2;
    .....
}

If .... else.... 

Ha a kifejezés igaz, akkor az utasítás1 különben az utsítás2 hajtódik végre.

if( kifejezés )     utasítás1;
else                utasítás2;
Ha a kifejezés igaz, akkor az utasítás1  ág hajtódik végre, különben a másik
if( kifejezés ) {
    utasítás1;
    utasitas2;
    .....
}else{
    utasítás3;
    utasitas4;
    .....
}

Ha kettőnél több elégazást szeretnénk, akkor az alábbi szintaktikával tudjuk a kérdést megoldani:

if( kifejezés1 )    utasítás1;
elseif(kifejezés2)  utasítás2;
else                utasítás3;

vagy

if( kifejezés1 ) {
    utasítás1;
    utasitas2;
    .....
}elseif( kifejezés2 ){
    utasítás3;
    utasitas4;
    .....
}else {
    utasítás5;
    utasítás6;
    ......
}

Switch(kifejezés)

A fenti esetben az if és az elseif utasításnál lévő kifejezések tetszőlegesek lehetnek, és az így felírt vezérlési szerkezettel meglehetősen bonyolult elágazásokat lehet létrehozni. Ezzel szemben általánosabb eset, amikor egy változ értékétől függően akarunk több féle műveletet is végrehajtani. Erre a célra alkalmas a C-ből jól ismert switch() függvény, amely több irányú elágazást hajt végre. Az ágak meghatározásakor csak konstansokat használhatunk, és az ágra akkor adódik át a vezérlés, ha a switch függvényben lévő változó értéke pontosan a konstans értékével egyezik meg. Amennyiben egy ágra ráadtuk vezérlést, majd végrehajtottuk az ott definiált utasításokat, a switch szerkezet végére kell ugranunk a break utasítás segítségével, mivel különben rácsorognánk a következő case feltételvizsgálatokra.

Nézzük a szintaktikáját:

switch ($i) {
    case 0:
        print "i most 0";
        break;

    case 1:
        print "i most 1";
        break;

    case 2:
        print "i most 2";
        break;

    default:
        print "i se nem 0, se nem 1, se nem 2";
}

A fenti példában az $i változó értékétől függően léptünk valamelyik irányba. Ha a változó értéke nem vette fel sem a 0, 1 vagy 2 értékeket, akkor a default utáni parancs hajtódik végre.

Gyakori eset, hogy amikor több különböző eseményt egyetlen változó különböző értékei alapján akarsz végrehajtatni, akkor használod a switch utasítást. Előfordulhat, hogy ugyanazt az eseményt több érték is jelölheti, illetve több különböző esemény van. Az alábbi példában a $jelző változó 0, 1, 2 értéke esetén az fv1() függvény fut le, a 3-as értékre az fv2() függvény, egyéb esetekben az fv3().

switch ($i) {
    case 0:
    case 1:
    case 2:
        fv1($jelzo);
        break;

    case 3:
        fv2($jelzo);
        break;

    default:
    fv3($jelzo);
}

A fenti példában az fv1, fv2, fv3 függvények lehetnek akármik!

Ciklus - iteráció

Mint a C-ben, itt is hasonló ciklusszerkezetek léteznek.

While (kifejezés)

Itt a kifejezés a ciklus előtt értékelődik ki, azaz a ciklus magja nem biztos, hogy végrehajtódik.

Példa:

int i = 1;
while (i <= 10) {
    Console.WriteLine( i );      // a kiírt érték "i", a kiírás után nő "i" értéke
    i++;
}

Do ..... While(kifejezés)

A kifejezés a ciklus végén értékelődik ki, azaz a ciklus magja egyszer mindenképpen lefut.

Példa:

var i = 10;
do {
   Console.WriteLine( i );
   i--;
} while ( i > 0); 

For(inicializáló kifejezés; Benntmaradás kifejezése; iteráló kifejezés)

A ciklus elején egyszer fut le az inicializáló kifejezés. Általában ez egy változónak ad egy kezdőértéket. Az ilyen változót ciklusváltozónak hívjuk.

A Benntmaradás kifejezése mindannyiszor a ciklus magjának lefutása előtt értékeli ki a rendszer. Ha a kifejezés igaz értéket ad vissza, akkor lefut a ciklus magja, ha hamis értéket, akkor a ciklus utáni első utasításon folytatódik a futás. Ha a kifejezés helyére üres értéket írunk, akkor végtelen ciklusba kerülhetünk, hacsak a ciklus belsejéből nem ugrunk ki a break utasítással.

Az Iteráló kifejezés felelős azért, hogy a ciklus valamikor befejeződjön. Általában a ciklusváltozó értékét növeljük vagy csökkentjük eggyel.

// Írassuk ki az egész számokat visszafelé 100-tól 1-ig
for (int i = 100; i >0; i-- ) {
     Console.WriteLine( i );
}

break vagy break n

A break utasítás arra szolgál, hogy segítségével egy struktúrából az adott helyen ki tudjunk ugrani. Ha utána írunk egy számot, akkor annak alapján több egymásba ágyazott struktúrából is ki tud ugrani: Példának okáért korábban a switch utasításnál mutattunk egy példát a break használatára, az opcionális módra pedig itt van egy példa:

int i = 0;

while ( i++) {
    switch ( i ) {

    case 5:
        Console.WriteLine( "5 esetén");
        break 1;  /* csak a switch-ből lép ki */

    case 10:
        Console.WriteLine( "10 esetén lép ki ");
        break 2;  /* a switch és a while befejezése */
    default:
        break;
    }
}

continue vagy continue n

Bár programozási módszertanok kerülik a ciklusokból való kiugrálást és a ciklusmagon belüli iterációt, azért minden általános nyelvben benne van a lehetőség, beleértve a Pascalt és a C-t is. Ez az utasítás akkor használható, ha a ciklus belsejében már eldőlnek a további iterációra vonatkozó feltételek és nem akarjuk, hogy a ciklus magjának többi részét feleslegesen futtassuk. Ha a continue n formát használjuk, akkor több egymásba ágyazott struktúrát tudunk folytatni.

Ebben a ciklusfajtában nincsen szükség egy tömb indexelésére. A ciklus egyesével végighalad a tömb elemein és a v valtozo egyesével felveszi a tomb elemeinek értékét.

int[] tomb = new int[] { 1, 2, 3, 17};

foreach (int v in tomb ) {
    Console.WriteLine("A tömb aktuális elemének értéke: {0}", v);
}

A fenti kis példában a tömb szintaktikáját és jelentését még nem tanultuk. Egyelőre legyen elég annyi, hogyha a tomb helyébe lyan adatokat képzeéünk, amelyeken egyesével végig lehet lépkedni és a v változó olyan típusú, amilyen a tömb elemei, akkor ezt a ciklust lehet használni.