Kétágú elágazás (if-else)

|
Kétágú elágazás (if-else)
|
bet | 8/51 | Sana | 07.04.2017 | Hajmi | 1,08 Mb. | | #3295 |
3.6.2. Kétágú elágazás (if-else)
A hibalehetőségek csökkentése a programozók elemi érdeke, ezért találták ki régesrég az if-else szerkezetet, amely lehetővé teszi, hogy a programunk tegyen valamit a feltétel fennállása esetén (igaz ág), illetve tegyen másvalamit akkor, ha a feltétel nem teljesül (hamis ág), így nem kell két feltételt karbantartani, s a program is rövidebb lesz:
view plaincopy to clipboardprint?
-
int pénz = 100;
-
int sörÁra = 120;
-
if (pénz >= sörÁra)
-
{
-
System.out.println("Vegyünk egy sört...");
-
System.out.println("...és igyuk meg!");
-
} else
-
{
-
System.out.println("Sajnos nincs pénzünk sörre...");
-
}
Mint láthatjuk, a módosítás mindössze annyi, hogy a második if és a feltétel helyére egy else került.
3.6.3. Többágú elágazások
Sok esetben szükség van többágú elágazásra, mivel a való életben is gyakran kell egy bekövetkezett tényre több lehetőség közül választani, gondoljunk csak arra az esetre, amikor sört akarunk venni a sarki kisboltban, de nincs mindig tele a pénztálcánk. Ekkor az éppen aktuális anyagi lehetőségeink határozzák meg, hogy milyen sört tudunk megvásárolni.
3.6.3.1. Egymásba ágyazott if-else
Egymásba ágyazott kétágú elágazásokból tudunk építeni többágú elágazást, ekkor a hamis ágba újabb elágazást tudunk tenni, amely sok ág esetén kellően átláthatatanná teheti a programunkat:
view plaincopy to clipboardprint?
-
int pénz = 100;
-
if (pénz >= 500)
-
{
-
System.out.println("Igyunk egy Guinness sört!");
-
} else
-
{
-
if (pénz >= 300)
-
{
-
System.out.println("Igyunk egy Leffe sört!");
-
} else
-
{
-
if (pénz >= 100)
-
{
-
System.out.println("Igyunk egy Soproni sört!");
-
} else
-
{
-
System.out.println("Sajnos nincs pénzünk sörre... :(");
-
}
-
}
-
}
-
System.out.println("Menjünk haza...");
A program tartalmaz több - egymásba ágyazott - if-else szerkezetet, amelyeknél látnunk kell egy döntési sorozatot. Ha a fenti feltételek szerint 100 forintból akarunk sört inni, akkor a kiértékeljük a pénz >= 500 feltételt, amely nyilvánvalóan hamis lesz, ezért nem tudunk Guinness sört inni, kénytelenek vagyunk a hamis ágon továbblépni. Az első hamis ágban egy újabb feltételt kell kiértékelni: pénz >= 300, amely szintén hamis lesz, ezért Leffe sört sem tudunk inni. Továbbmegyünk a második hamis ágon, ahol meglátjuk az utolsó feltételt, amelynek már megfelel a pénzmagunk, így tudunk inni egy Sopronit. Észre kell vennünk, hogy bármelyik feltétel teljesülése esetén - a hamis ág kihagyása miatt - a program végrehajtása az első hamis ág után folytatódik (menjünk haza...).
3.6.3.2. Egymásba ágyazott if-else-if
Az egymásba ágyazott if-else szerkezetek mindig átírhatóak egy if-else-if szerkezetre, amely sokkal áttekinthetőbb, mivel látszólag mellőzi az egymásba ágyazást:
view plaincopy to clipboardprint?
-
int pénz = 100;
-
if (pénz >= 500)
-
{
-
System.out.println("Igyunk egy Guinness sört!");
-
} else if (pénz >= 300)
-
{
-
System.out.println("Igyunk egy Leffe sört!");
-
} else if (pénz >= 100)
-
{
-
System.out.println("Igyunk egy Soproni sört!");
-
} else
-
{
-
System.out.println("Sajnos nincs pénzünk sörre... :(");
-
}
-
System.out.println("Menjünk haza...");
Észre kell vennünk, hogy az else utasítások után lespóroltunk egy blokk utasítást, mivel a blokkban csak egy if utasítás volt. Ezzel az apró módosítással átláthatóbbá tettük a program működését, hiszen fentről lefelé olvashatjuk a feltételeket és a feltételekhez tartozó utasításokat, illetve az utolsó else után azt az utasítást, amely akkor hajtódik végre, ha egyik feltétel se teljesült. Ez az utolsó else ág egyébként elhagyható, ha nincs rá szükségünk.
3.6.3.3. Kapcsoló (switch-case-default)
Ha primitív típus meghatározott értéke alapján szeretnénk különféle dolgokat végezni, akkor egy hosszabb if-else-if szerkezet helyett használjuk inkább a switch utasítást:
view plaincopy to clipboardprint?
-
int pénz = 300;
-
int sörÁra = 120;
-
int sörökSzáma = pénz / sörÁra;
-
switch (sörökSzáma)
-
{
-
case 0:
-
System.out.println("Nincs sör, nincs mit inni.");
-
break;
-
case 1:
-
System.out.println("Egy sör nem sör.");
-
break;
-
case 2:
-
System.out.println("Két sör fél egészség.");
-
break;
-
case 3:
-
System.out.println("Három sör jó kezdés.");
-
break;
-
case 4:
-
System.out.println("Négy sör jó, két sör rossz.");
-
break;
-
default:
-
System.out.println("Sok sör soha nem árt.");
-
}
Ahogy a példában látjuk, döntés a sörökSzáma változó értékétől függ, ha a változó értéke megegyezik valamelyik case ág értékével, akkor az az ág végrehajtásra kerül. A várt működés szerint a program az alábbit írja ki:
view plaincopy to clipboardprint?
-
Két sör fél egészség.
Ha egyik ág se hajtódna végre, akkor a default ágra kerül a vezérlés, ha nincs default ág, akkor a program végrehajtása a switchutasítás végétől folytatódik. A switch működési sajátossága, hogy az első egyezőségtől kezdve az összes utasítást végrehajtja a blokk végéig, ezért minden ágat egy break utasítás zár, amely hatására a program végrehajtása a switch utasítás után folytatódik. Gyakori programozói hiba a break elhagyása, amely okán másképp működik a programunk, próbáljuk ki a fenti programot brake utasítások nélkül:
view plaincopy to clipboardprint?
-
Két sör fél egészség.
-
Három sör jó kezdés.
-
Négy sör jó, két sör rossz.
-
Sok sör soha nem árt.
Mivel két sörre volt pénzünk, a két sört tartalmazó ágtól kezdve az összes utasítás végrehajtódik.
3.6.4. Előltesztelő ciklus (while)
Sok esetben szükséges egy-egy programrészletet megismételni, gondoljunk csak arra, ha bemegyünk egy kocsmába egy ezressel és addig szeretnénk sörözni, amíg el nem fogy a pénzünk:
view plaincopy to clipboardprint?
-
int pénz = 1000;
-
int sörÁra = 400;
-
while (pénz > sörÁra)
-
{
-
System.out.println("Kérjünk egy korsó sört, majd igyuk meg.");
-
pénz -= sörÁra; // Vonjuk le a sör árát a pénzünkből
-
}
A végrehajtás során a belépési feltételünk kiértékelésre kerül, csak akkor hajtódik végre a ciklus magja, ha a feltétel igaz - vagyis van pénzünk legalább egy sörre. A ciklusmag végrehajtása után a feltétel újra és újra kiértékelődik, és a ciklus magja újra és újra végrehajtódik.
Gyakori programozási hiba, hogy a ciklusmagban nem változtatjuk a feltételben szereplő változók értékét: ekkor végtelen ciklust kapunk, amely - ha ideje engedné - a ciklusmagot végtelen esetben hajtaná végre.
3.6.5. Hátultesztelő ciklus (do-while)
A hátultesztlő ciklus működése hasonlít az előltesztelő ciklus működésére, egyedüli különbség, hogy a feltétel kiértékelése az első ciklusmag lefutása után történik meg, tehát a hátultesztelő ciklus egyszer mindenképpen végrehajtja a ciklusmagot:
view plaincopy to clipboardprint?
-
int pénz = 1000;
-
int sörÁra = 400;
-
do
-
{
-
System.out.println("Kérjünk egy korsó sört, majd igyuk meg.");
-
pénz -= sörÁra; // Vonjuk le a sör árát a pénzünkből
-
}
-
while (pénz > sörÁra);
A hátultesztelő ciklus tipikus felhasználási területe a beolvasott érték alapján történő döntés, a beolvasást a ciklus addig ismétli, amíg a várt értéket sikerül beolvasni.
3.6.6. Számláló Ciklus (for)
Számláló ciklust olyan esetben használjuk, amikor konkértan tudjuk (avagy sejtjük), hogy hányszor fog ismétlődni egy feladat. Ha például tisztában vagyunk azzal, hogy a sör ára: 200 forint és 600 forint van nálunk, akkor 3 db sört vehetünk. Kifizetjük a kocsmárosnak és mivel hidegen jó, egyesével szervírozva fogyasztjuk el.
view plaincopy to clipboardprint?
-
view plaincopy to clipboardprint?
-
// 3 db sör kifizetése
-
for (int sor=1; sor <= 3; sor++)
-
{
-
System.out.println('Újabb sör szervírozása');
-
System.out.println('Sör elfogyasztása);
-
}
Bizonyos esetkben mindössze sejtjük, hogy mennyi lesz az iteráció száma, de bizonyos ok mellett idő előtt befejezzük a keresést. Ilyen esetben a Break utasítás használható. Kissé erőltetetten a sörös példánkra visszatérve 3 db sört rendelünk, de már a hamradikat nem kérjük ki valami oknál fogva.
// 3 db sör kifizetése
view plaincopy to clipboardprint?
-
for (int sor=1; sor <= 3; sor++)
-
{
-
if (sor>2)
-
break; // kettő sörnél több kell
view plaincopy to clipboardprint?
-
System.out.println('Újabb sör szervírozása');
-
System.out.println('Sör elfogyasztása);
view plaincopy to clipboardprint?
-
}
view plaincopy to clipboardprint?
-
// 1 db sör árának a visszakérése.
Olyan helyzet is lehetséges, hogy tudjuk az összes iteráció, azaz ismétlés számát, azonban egyes esetkeben nem akarunk, vagy csak részben akarjuk az iterációban lévő műveleteket végrehajtani. A ciklus következő iterációval való folytatására a continue parancsot tudjuk használni. Kedvenc sörös példánknál maradva 5 ügyfele van a kocsmárosunknak, azonban csak 4 szeretne sört. Íme a megvalósítás:
for (int vendeg=1; vendeg<6; vendeg++)
{
if (vendeg == 4) continue; // a 4. helyen ülő vendég nem kér a sörből
System.out.println('Sör kiadása a vendégnek.');
}
Amennyiben több ciklust is egymásba ágyazunk, és egyszerre több ciklusból is szeretnénk kiugrani, akkor a label, azaz cimkét kell meghatározni..
3.6.7. Léptető ciklus (for each)
Abban az esetben, ha egy konkrét halmazunk van, azaz konkrét dolgaink, és megfelelő módon vannak szervezve, akkor egyesével végighaladhatunk rajtuk.
A sörös példánknál maradva 4 megrendelést kap a kocsmáros. A megrendelések száma tudjuk, hogy 4, azonban mindig más mennyiséget kérnek egyszerre a nedüből.
A megvalósításnál tömböket, azaz egy speciális típust fogunk használni.
A tömb fogalmát külön ki kellene fejteni, azonban egy kicsit könnyelműen, de legalábbis egyszerűen egy linken megnézheted (angolul).
download.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
view plaincopy to clipboardprint?
-
int[] rendelesek={1, 2, 1, 3};
-
-
-
for(int rendeles: rendelesek){
-
-
class="Apple-tab-span" style="white-space:pre"> System.out.print("sör kiadása: ");
-
-
class="Apple-tab-span" style="white-space:pre"> System.out.print(rendeles);
-
-
class="Apple-tab-span" style="white-space:pre"> System.out.println(". db.");
-
-
}
A System.out.print parancs nem töri el a szöveget. Így a kód futásának a végeredménye:
sör kiadása: 1. db.
sör kiadása: 2. db.
sör kiadása: 1. db.
sör kiadása: 3. db.
Természetesen ez csak betekintés volt a for each szerkezetbe, szerves részét képezi bármely fejlett programozási nyelvnek ez a technika.
|
| |