C blokk · Vezérlési szerkezetek · 3. tananyag
A valódi döntések ritkán állnak meg egy kérdésnél: „Van jegyed? — És ha van, elmúltál 18?” A C1–C2 eszközei egymásba épülnek: if az if-ben, if a switch ágában. Ma megtanuljuk ezt jól csinálni — és azt is, mikor ne: a mélyre ágazott kód olvashatatlan, pedig majdnem mindig van laposabb megoldás.
else —
és miért véd meg a blokk.Koncertbeléptetés: először a jegy, aztán a kor — és mindkét kérdésre saját válasz jár:
if (vanJegy) { if (eletkor >= 18) { Konzol.Siker("Beléphetsz a koncertre."); } else { Konzol.Hiba("Ez a koncert 18+ — a jegyet visszaváltjuk."); } } else { Konzol.Hiba("Előbb jegyet kell venned."); }
A beágyazás hatalom, de gyorsan átláthatatlan: három szintnél mélyebbre már csak nagyon jó okkal menj. Mielőtt mélyítesz, kérdezd meg: kell-e külön válasz minden szinthez?
| Helyzet | Eszköz |
|---|---|
| a feltételek együtt kellenek, és egyetlen közös válasz jár | && / || — egy if (C1) |
| külön üzenet/teendő jár az egyes hibákhoz | beágyazás |
| egy érték sávokba sorolása | else if lánc — az nem mélyít, hanem sorol |
| először a rossz eseteket akarod kiszűrni | őrfeltétel: hibaág előre, utána a „tiszta” fő ág |
Ugyanaz kétféleképpen:
if (int.TryParse(szoveg, out int tipp)) { if (tipp >= 1 && tipp <= 6) { Konzol.Siker($"Tipped: {tipp}"); } else { Konzol.Hiba("1 és 6 közé tippelj!"); } } else { Konzol.Hiba("Ez nem szám."); }
if (int.TryParse(szoveg, out int tipp) && tipp >= 1 && tipp <= 6) { Konzol.Siker($"Tipped: {tipp}"); } else { Konzol.Hiba("1 és 6 közti szám kell!"); }
Egyik sem „a helyes”: ha a felhasználónak segít a kétféle hibaüzenet, megéri a beágyazás; ha nem, az összevont rövidebb és laposabb. Te döntesz — de tudd, miért.
A kérdés mindig ugyanaz: kell-e külön válasz az egyes feltételekhez?
Blokkok nélkül a behúzás hazudhat:
// VIGYÁZAT — a behúzás félrevezet: if (vanJegy) if (eletkor >= 18) Console.WriteLine("Beléphetsz."); else Console.WriteLine("Nincs jegyed."); // valójában a BELSŐ if else-e!
Az else mindig a legközelebbi,
még pár nélküli if-hez tartozik — a fordítót a behúzás nem érdekli. A
fenti kód tehát akkor írja ki, hogy „Nincs jegyed”, amikor
van jegy, csak a néző kiskorú!
A C1-es
szabályunk („a blokk egysorosan is jár”) itt fizet ki igazán: a
{ } egyértelművé teszi, mi mihez tartozik —
a csüngő else csapdája elő sem fordulhat.
A C2-es menü ágai eddig csak kiírtak. Az igazi menüpontok kérdeznek is — az ágba beágyazott döntéssel:
switch (billentyu.KeyChar) { case '2': Console.Write("Tipp (1–6): "); if (int.TryParse(Console.ReadLine(), out int tipp)) { if (tipp >= 1 && tipp <= 6) { Console.WriteLine($"A tipped: {tipp}. A dobás: 4."); } else { Konzol.Hiba("A dobókockán 1 és 6 között vannak számok!"); } } else { Konzol.Hiba("Ez nem szám."); } break; // … többi menüpont … }
A break továbbra is az ág
legvégén áll — a beágyazott if-ek a case belsejében élnek.
Fordítva is működik: if ágba is írhatsz switch-et.
Két szint: kívül az érvényesség (szám-e), belül a kategóriák — a sávokat nem mélyítjük, hanem soroljuk (else if lánc):
Konzol.Cim("MOZIPÉNZTÁR"); Console.Write("Hány éves vagy? "); if (int.TryParse(Console.ReadLine(), out int eletkor)) { if (eletkor < 0 || eletkor > 120) { Konzol.Hiba("Ilyen életkor nincs — a pénztáros gyanakszik."); } else if (eletkor < 6) { Konzol.Siker("A belépés ingyenes!"); } else if (eletkor < 18) { Console.WriteLine("Diákjegy: 1 490 Ft."); } else if (eletkor < 65) { Console.WriteLine("Teljes árú jegy: 2 490 Ft."); } else { Console.WriteLine("Nyugdíjas jegy: 1 690 Ft."); } } else { Konzol.Hiba("Ez nem szám — kezdjük újra a pénztárnál."); }
A lánc első ága a képtelen értékeket szűri ki (negatív kor, 120 fölött) — utána a többi ág már nyugodtan dolgozhat. Összesen 6 kódútvonal: mind a hatot teszteld!
| Tünet | Mi történt? | Mit tegyél? |
|---|---|---|
| a program „rossz” else-ágba fut | blokk nélküli beágyazásnál az else a belső if-é lett | mindig { } — a blokk nem hagy kérdést |
| a behúzás mást sugall, mint ami fut | kézzel elrontott behúzás — a fordítót nem érdekli | Ctrl+K, Ctrl+D (teljes újraformázás) és blokkok |
| 4-5 szint mély if-piramis | mindent beágyazással oldottál meg | lapíts: &&, else if lánc, őrfeltétel (2. szakasz) |
| a belső if újra ellenőrzi, amit a külső már tud | feltétel-duplázás | a belső ágban a külső feltétel már biztosan igaz — töröld |
CS0165 a belső ágban használt változóra | a változó csak egy másik ágban kapott értéket | deklaráld kezdőértékkel a szerkezet előtt |
a switch-ág beágyazott if-je után hiányzik a break | a sok blokk közt elveszett az ág vége | a break mindig az ág legvégén, a case szintjén áll |
KonzolMenu projektet.&&-sel.Beagyazott dontesek a menuben.Rossz szövegre és tartományon kívüli számra különböző, értelmes hibaüzenet jön; egyetlen útvonalon sem áll le a program.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
Belépőjegy: kérd be az életkort TryParse-szal; érvénytelen bevitelre hibaüzenet, egyébként a mozipénztár mintájára legalább három árkategória — más sávokkal és árakkal, mint a példa.
Bejelentkezés: tárolt felhasználónév és jelszó (konstansok). Először a felhasználónevet ellenőrizd; ha jó, jöhet a jelszó — a két hibára különböző üzenet jár. Siker esetén zöld üdvözlés.
Háromszög-vizsgáló: kérj be három oldalhosszt. Először döntsd el, lehet-e egyáltalán háromszög (bármely két oldal összege nagyobb a harmadiknál) — ha igen, azon belül sorold be: egyenlő oldalú, egyenlő szárú vagy általános.
Szökőév: egy év szökőév, ha osztható 4-gyel — kivéve, ha osztható
100-zal — hacsak nem osztható 400-zal is. Írd meg kétszer:
egyszer beágyazott if-ekkel, egyszer egyetlen feltétellel
(&&/||/zárójelek) —
és ellenőrizd, hogy 1900-ra, 2000-re és 2024-re ugyanazt adják!
Kő–papír–olló: kérd be két játékos jelét (k/p/o egy-egy karakterrel). Külső switch az első játékos jelére; az ágakon belül döntsd el a másodikhoz képest az eredményt (győztes vagy döntetlen) — ismeretlen jelre hibaüzenet.
Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.
| Fogalom | Jelentés |
|---|---|
| beágyazott szelekció | if/switch egy másik if/switch ágának belsejében |
| beágyazási szint | hány döntésen belül vagyunk — minden szint egy behúzásnyival beljebb |
| lapítás | a mélység csökkentése: &&/||, else if lánc, őrfeltétel |
| őrfeltétel | a hibás/képtelen esetek kiszűrése legelöl — utána a fő ág „tisztán” fut |
| csüngő else | blokk nélkül az else a legközelebbi if-hez tapad — a behúzás hiába sugall mást |
| feltétel-duplázás | a belső ág újra ellenőrzi, amit a külső már garantál — felesleges |
| kódútvonal-robbanás | a szintekkel szorzódik az utak száma — és mindet tesztelni kell |
&&,
else if lánc, őrfeltétel.else a legközelebbi
if-é — de mivel mi mindig blokkokat írunk, ez nálunk kérdés sem
lehet.break az ág legvégén
marad.