Vezérlőpult
C3. Szelekciók egymásba ágyazása · Vezérlési szerkezetek

C blokk · Vezérlési szerkezetek · 3. tananyag

Szelekciók egymásba ágyazása

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.

1 tanórabeágyazás és lapításőrfeltétel

Tanulási célok

1Döntés a döntésben

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.");
}

2Meddig mélyíts? A lapítás három eszköze

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?

HelyzetEszkö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ákhozbeágyazás
egy érték sávokba sorolásaelse 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:

Beágyazva — külön üzenetek
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.");
}
Összevonva — egy közös üzenet
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.

Melyik szerkezetet választanád?

A kérdés mindig ugyanaz: kell-e külön válasz az egyes feltételekhez?

1 / 8Pontszám: 0
…

3Az else melyik if-hez tartozik?

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ú!

💡 EZÉRT ÍRUNK MINDIG BLOKKOT

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.

4If a switch-ben: az okos menü

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.

5Kidolgozott példa: a mozipénztár

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.");
}
ℹ️ ŐRFELTÉTEL AKCIÓBAN

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!

6Gyakori hibák

TünetMi történt?Mit tegyél?
a program „rossz” else-ágba futblokk nélküli beágyazásnál az else a belső if-é lettmindig { } — a blokk nem hagy kérdést
a behúzás mást sugall, mint ami futkézzel elrontott behúzás — a fordítót nem érdekliCtrl+K, Ctrl+D (teljes újraformázás) és blokkok
4-5 szint mély if-piramismindent beágyazással oldottál meglapíts: &&, else if lánc, őrfeltétel (2. szakasz)
a belső if újra ellenőrzi, amit a külső már tudfeltétel-duplázása belső ágban a külső feltétel már biztosan igaz — töröld
CS0165 a belső ágban használt változóraa változó csak egy másik ágban kapott értéketdeklaráld kezdőértékkel a szerkezet előtt
a switch-ág beágyazott if-je után hiányzik a breaka sok blokk közt elveszett az ág végea break mindig az ág legvégén, a case szintjén áll

7Gyakorlat — a menü megokosodik

  1. Nyisd meg a C2-es KonzolMenu projektet.
  2. A dobókocka menüpontba építsd be a 4. szakasz kétszintű ellenőrzését (szám-e → tartományban van-e), saját hibaüzenetekkel.
  3. A számolós menüpontodba is kerüljön TryParse-os érvényesség-vizsgálat — döntsd el (és kommentben indokold!), hol ágyazol és hol vonsz össze &&-sel.
  4. Tesztelj minden kódútvonalat menüpontonként.
  5. Commit: Beagyazott dontesek a menuben.
✅ ELLENŐRZŐ PONT

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.

8Feladatok

Gyakorló feladatok

⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás

C3.1⭐

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.

C3.2⭐⭐

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.

C3.3⭐⭐

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.

C3.4⭐⭐⭐

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!

C3.5⭐⭐⭐

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.

9Önellenőrző kvíz

Ellenőrizd magad!

Minden kérdésnél egy válasz helyes. A végén pontszámot kapsz.

10Fogalomtár

FogalomJelentés
beágyazott szelekcióif/switch egy másik if/switch ágának belsejében
beágyazási szinthány döntésen belül vagyunk — minden szint egy behúzásnyival beljebb
lapítása mélység csökkentése: &&/||, else if lánc, őrfeltétel
őrfeltétela hibás/képtelen esetek kiszűrése legelöl — utána a fő ág „tisztán” fut
csüngő elseblokk nélkül az else a legközelebbi if-hez tapad — a behúzás hiába sugall mást
feltétel-duplázása belső ág újra ellenőrzi, amit a külső már garantál — felesleges
kódútvonal-robbanása szintekkel szorzódik az utak száma — és mindet tesztelni kell

11Összegzés

  1. A döntések egymásba épülhetnek: a belső ág már tudja, hogy a külső feltétel igaz.
  2. Mélyíteni akkor érdemes, ha szintenként külön válasz jár — különben lapíts: &&, else if lánc, őrfeltétel.
  3. Az else a legközelebbi if-é — de mivel mi mindig blokkokat írunk, ez nálunk kérdés sem lehet.
  4. If a switch ágában: így lesznek a menüpontok okosak — a break az ág legvégén marad.
  5. Minden szint szorozza a kódútvonalakat — a tesztelés a fejezet legfontosabb szokása.