C# – Vezérlési szerkezetek


Vezérlési szerkezetnek a program utasításainak sorrendiségét szabályozó konstrukciókat nevezzük.

Szekvencia

A legegyszerűbb vezérlési szerkezet a szekvencia. Ez tulajdonképpen egymás után megszabott sorrendben végrehajtott utasításokból áll. A szekvencia minden más vezérlési szerkezet építőköve. Nézzünk erre egy példát:

Elágazás

if () szerkezet

Gyakran előfordul, hogy meg kell vizsgálnunk egy állítást, és attól függően, hogy igaz vagy hamis, a programnak más-más utasítást kell végrehajtania. Ilyen esetekben elágazást használunk. Egy egyszerű elágazást létrehozhatunk az if() szerkezettel. A zárójelben egy logikai vizsgálatot kell megadnunk, majd a szerkezet blokk részében (kapcsos zárójelek között) azt kell megadnunk, hogy mit csináljon a program, ha a logikai feltétel igaz. Most is segít a VS! Ha elkezdjük írni azt, hogy if, és a tabulátor billentyűt megnyomjuk kétszer, akkor beírja helyettünk a függvény szerkezetét! Nézzünk egy egyszerű példát, itt eldönti a program, hogy az elsőnek beírt szám nagyobb-e, mint a másodiknak beírt szám. Csak ennyi a dolga! Ha nem igaz az állítás, akkor nem ír ki semmit.

Ha a logikai vizsgálatban azt akarjuk megállapítani, hogy két dolog egyenlő-e, akkor nem a sima egyenlőségjelet kell használnunk, hanem a dupla egyenlőségjelet (==)! Ez nagyon fontos, mert különben hibát kapunk. Az alábbi példában ezt láthatjuk. Természetesen ha a feltétel nem teljesül, akkor nem ír ki semmit.

Legtöbbször szükségünk van arra, hogy ha a feltétel nem teljesül, akkor is írjon ki valamit a program. Nos egészítsük ki az if szerkezetet egy else ággal. Ebben az ágban a kapcsos zárójelek között azt kell megadnunk, hogy mit csináljon a program, ha nem igaz a logikai vizsgálat eredménye. Most is segít a VS, írjuk be, hogy else, majd nyomjuk meg a tabulátor billentyűt kétszer. A következő képen erre láthatunk egy egyszerű példát.

else if () szerkezet

Néha az is jó lenne, hogy több feltételt vizsgáljunk. Erre is lehetőségünk van, mégpedig az else-if vezérlési szerkezettel.

Vizsgáljuk meg, mit is csinál a fenti program. Bekérünk két számot, majd ezeket vizsgáljuk. Ha a két szám egyenlő, akkor teljesül a feltétel, így a program nem vizsgálódik tovább, hanem kiírja az egyenlőséget. Ha nem teljesül a feltétel, azaz a két szám nem egyenlő, akkor megy tovább a vizsgálat, és megnézi, hogy az első szám nagyobb-e, mint a második szám. Ha igen, akkor befejezte a vizsgálatot, és kiírja, hogy nagyabb az első szám. Ha ez a feltétel sem igaz, akkor megy tovább, és végül kiírja, hogy az első szám kisebb, mint a második szám. Igaza van, ugyanis ha nem egyenlőek, és nem is nagyobb az első szám a másodiknál, akkor csak kisebb lehet nála. Természetesen több else if ágat is beiktathatunk, de if ág és else ág csak egy lehet!

Nézzünk még egy példát erre a szerkezetre. Az alábbi képen egy másodfokú egyenlet megoldására látható egy program. A programban használtam a Math osztály Sqrt() függvényét, amely egy szám négyzetgyökét adja vissza. Később migismerkedünk majd a Math osztály néhány hasznos függvényével.

switch () case szerkezet

Ezt a szerkezetet akkor használjuk, ha egy változó több lehetséges állapotát akarjuk vizsgálni. A switch szerkezeten belül a case utasítással megadhatjuk azokat az állapotokat, amelyekre reagálni szeretnénk. Az egyes esetek utasításai után meg kell adnunk, hogy mi történjen ezután. Az ágak a kijelölt feladatuk végrehajtása után a break utasítással kilépnek a szerkezetből. Természetesen nem kell minden lehetséges állapotot megvizsgálnunk, csak azokat, amelyek számunkra érdekesek. Erre a célra használhatjuk a default ágat, amely gyakorlatilag az else ágnak felel meg. Ha nincs olyan ág, amely kezelné az éppen aktuális értéket, akkor vagy a default ág kapja meg a vezérlést, vagy ha nem írtunk ilyet, akkor a switch szerkezetből kilépve folytatódik a program futása. A C++ nyelvtől eltérően a C# nem engedélyezi, hogy break utasítás hiányában egyik állapotból átcsússzunk egy másikba. Ez alól a szabály alól egyetlen kivétel van, ha az adott ág nem tartalmaz semmilyen utasítást.

Az alábbi példában láthatjuk az előzőekben leírtakat, azaz, hogy miként működik a switch szerkezet. Itt a beírt műveleti jelet vizsgálja a program, és annak megfelelően cselekszik.

Ciklus

Amikor egy adott utasítássorozatot egymás után többször kell végrehajtanunk, akkor ciklust használunk. A C# négyféle ciklust biztosít számunkra.

For ciklus

Ez az úgynevezett számlálós ciklusA for utáni zárójelben találjuk az ún. ciklusfeltételt, ez minden ciklus része lesz, és azt adjuk meg benne, hogy milyen feltétele van a ciklus futásának. A számlálós ciklus feltétele első ránézésre eléggé összetett, de ez ne tévesszen meg minket, valójában nem az. Mindössze három kérdésre kell választ adnunk: Honnan? Meddig? Hogyan?

Menjünk sorjában: a „Honnan?”-ra adott válaszban megmondjuk azt, hogy milyen típust használunk a számoláshoz és azt, hogy honnan kezdjük a számolást. Tulajdonképpen ebben a lépésben adjuk meg az ún. ciklusváltozót, amelyre a ciklusfeltétel épül. A ciklusváltozó neve konvenció szerint i lesz az angol iterate (ismétel) szóból. Több ciklusváltozó használatakor általában i, j, k, … sorrendet követünk. Mivel a ciklusfeltétel után blokkot nyitunk, azt hinné az ember, hogy a ciklusváltozó lokális lesz a ciklus blokkjára (a for után következő kapcsos zárójelekkel határolt részre) nézve, de ez nem fedi a valóságot. A ciklusfeltételen belül deklarált ciklusváltozó lokális lesz a ciklust tartalmazó blokkra (vagyis ebben az esetben a teljes Main() függvényre) nézve.

Következzen a „Meddig?”! Most azt kell megválaszolnunk, hogy a ciklusváltozó mely értéke tesz eleget a ciklusfeltételnek.

Utoljára a „Hogyan?” kérdésre adjuk meg a választ, vagyis azt, hogy milyen módon változtatjuk a ciklusváltozó értékét. A leggyakoribb módszer az inkrementáló (vagy dekrementáló) operátor használata, de megadhatunk összetett kifejezést is.

Az alábbi programban 10-nél kisebb páros számokat írunk a képernyőre egymás mellé egy szóközzel elválasztva. Az eredmény: 0 2 4 6 8 lesz.

While ciklus

Ez az úgynevezett elöl-tesztelős  ciklus, amely onnan kapta a nevét, hogy a ciklusmag végrehajtása előtt ellenőrzi a ciklusfeltételt, ezért előfordulhat az is, hogy a ciklustörzs egyszer sem fut le. Az alábbi példában azt láthatjuk, hogy a program megvizsgálja az “i” változó értékét. Ha ez kisebb, mint 10 (ez az előfeltétel), akkor végrehajtja a ciklusmagban lévő utasításokat. Ha nem kisebb, akkor nem fut le a ciklus egyszer sem. Például, ha i = 10, akkor nem fut le a ciklus, ha pedig i = 9, akkor egyszer lefut, és az eredmény egy szám lesz, a 9. Természetesen, ha i = 0, akkor tízszer lefut a ciklus, és az eredmény: 0 1 2 3 4 5 6 7 8 9. A ciklusmagban lévő ++i utasítás megnöveli az “i” aktuális értékét 1-el.

Do-While ciklus

Hátultesztelős ciklus, mert a ciklusmag végrehajtása után ellenőrzi a ciklus feltételt., így legalább egyszer biztosan lefut. Legyen a példánk megint az előzőleg bemutatott program, azaz, irassuk ki a 10-nél kisebb számokat. Most azt találjuk, hogy ha a kezdeti “i” értéket 10-re, vagy annál nagyobb számra állítjuk, akkor is lefut a program, de csak egyszer. Ilyenkor a kezdeti értéket írja ki. Például, ha i = 26 volt, akkor az eredmény is 26. Ha i = 0, akkor ugyanazt kapjuk eredményül, mint az előző ciklusban, vagyis az eredmény: 0 1 2 3 4 5 6 7 8 9 .

Foreach ciklus

Ezzel a ciklussal végig iterálhatunk egy tömbön vagy gyűjteményen. Az alábbi példában felveszünk egy stringet, amelyben az angol abc kisbetűi vannak. A ciklusfejben felveszünk egy char típusú változót, utána az in kulcsszó következik, amivel kijelöljük azt a „listát”, amelynek elemein végig szeretnénk menni. A példában használt ch változó nem ciklusváltozó, hanem ún. iterációs változó, amely felveszi az iterált gyűjtemény aktuális elemének értékét.