05. TANANYAG · C# ALAPOK

Feltételválasztás.

if, else if, else – háromszög és előjel

A lépésről lépésre animáció egy kockája: Visual Studio és magyarázó tábla

ANIMÁCIÓ · NARRÁLT

Lépésről lépésre

Tanári bemutató: a program üres fájlból, sorról sorra épül fel, közben a tábla mutatja a memóriát, a kiértékelést és a konzolt. A futások valódi .NET-futtatásból származnak.

14,7 perc · 15 fejezet · hang és felirat · fejezetválasztó

Lejátszás
Az áttekintő animáció egy kockája

ANIMÁCIÓ · FELIRATOS

Áttekintés

Rövid, hang nélküli összefoglaló a kód elemeiről, felirattal. Ismétléshez vagy a téma gyors felidézéséhez.

4,7 perc · felirat · saját lejátszósáv

Megnyitás
05_Feltetelvalasztas_kommentelt.csTeljes nézet →Letöltés
namespace Feltetelvalasztas // A namespace (névtér) összefogja és elkülöníti az ide tartozó kódelemeket; ennek a névtérnek a neve Feltetelvalasztas.
{ // A nyitó kapcsos zárójel jelzi, hogy itt kezdődik a Feltetelvalasztas névtérhez tartozó kódblokk.
    internal class Program // Az internal azt jelenti, hogy ez az osztály ezen az assemblyn belül érhető el; a class egy Program nevű osztályt definiál.
    { // Itt kezdődik a Program osztály törzse.
        static void Main(string[] args) // A Main a program belépési pontja; static: példány nélkül futtatható, void: nem ad vissza értéket, string[] args: parancssori argumentumok tömbje.
        { // Itt kezdődik a Main metódus törzse.
            // 1. PÉLDA – ELÁGAZÁS: ELDÖNTJÜK, HOGY A MEGADOTT HÁROM OLDALBÓL SZERKESZTHETŐ-E HÁROMSZÖG.

            Console.Write("A háromszög a oldala: "); // Kiírjuk a bekérő szöveget; a Write nem kezd új sort, ezért a felhasználó ugyanebben a sorban írhatja be az értéket.
            // string aOldalSzöveg = Console.ReadLine(); // A ReadLine() a beírt adatot szövegként, vagyis stringként olvassa be; ez a kétlépéses megoldás első lépése lenne.
            // int a = Convert.ToInt32(aOldalSzöveg); // A Convert.ToInt32() a szöveget egész számmá alakítaná; ez a kétlépéses megoldás második lépése lenne.

            // int aOldal = Convert.ToInt32(Console.ReadLine()); // A beolvasás és az int típusra alakítás egyetlen sorban is elvégezhető.
            double aOldal = Convert.ToDouble(Console.ReadLine()); // A ReadLine() által visszaadott szöveget a Convert.ToDouble() double típusú számmá alakítja, majd eltároljuk az aOldal változóban.

            Console.Write("A háromszög b oldala: "); // Bekérjük a háromszög második oldalának hosszát.
            // int bOldal = int.Parse(Console.ReadLine()); // A Parse is szöveget alakít számmá; ez a változat egész számot, vagyis int értéket várna.
            double bOldal = double.Parse(Console.ReadLine()); // A double.Parse() a beolvasott stringet double típusú számmá alakítja, majd az eredményt a bOldal változó tárolja.

            Console.Write("A háromszög c oldala: "); // Bekérjük a háromszög harmadik oldalának hosszát.
            // int cOldal = int.Parse(Console.ReadLine()); // Ugyanez int típussal: a szövegből egész számot készítenénk.
            double cOldal = double.Parse(Console.ReadLine()); // A double.Parse() a harmadik beolvasott oldalt is double típusú számmá alakítja.

            // LOGIKAI OPERÁTOROK – több feltételt kapcsolhatunk össze velük.
            // && – ÉS: az összekapcsolt feltételeknek egyszerre kell igaznak lenniük.
            // || – VAGY: elég, ha az összekapcsolt feltételek közül legalább az egyik igaz.
            // !  – NEM: megfordítja egy logikai kifejezés értékét; true-ból false, false-ból true lesz.

            if (aOldal + bOldal > cOldal && aOldal + cOldal > bOldal && bOldal + cOldal > aOldal) // Az if feltétele azt vizsgálja, hogy mindhárom háromszög-egyenlőtlenség teljesül-e; az && miatt mindhárom részfeltételnek igaznak kell lennie.
            { // Ez a kódblokk csak akkor fut le, ha az if feltétele true, vagyis a három oldalból szerkeszthető háromszög.
                double kerület = aOldal + bOldal + cOldal; // Összeadjuk a három oldal hosszát, és az eredményt a kerület nevű double változóban tároljuk.
                Console.WriteLine($"A háromszög kerülete: {kerület}"); // String interpolációval kiírjuk a kerület változó aktuális értékét.
                double s = kerület / 2; // Kiszámítjuk a félkerületet; a Heron-képletben ezt szokás s betűvel jelölni.
                double terület = Math.Sqrt(s * (s - aOldal) * (s - bOldal) * (s - cOldal)); // A Heron-képlettel kiszámítjuk a területet; a Math.Sqrt() a zárójelben lévő érték négyzetgyökét adja vissza.
                // terület = Math.Round(terület, 2); // A Math.Round() két tizedesjegyre kerekítené a területet, és a kerekített értéket visszaírnánk ugyanabba a változóba.
                // Console.WriteLine($"A háromszög területe: {Math.Round(terület, 2)}"); // A kerekítés közvetlenül a kiíráskor is elvégezhető, külön értékadás nélkül.
                Console.WriteLine($"A háromszög területe: {terület:F2}"); // Az F2 formátum két tizedesjeggyel jeleníti meg az értéket; ez a kiírást formázza, magát a terület változóban tárolt számot nem módosítja.
            } // Itt ér véget az if igaz ágának kódblokkja.
            else // Az else ág akkor következik, ha az if feltétele hamis, vagyis legalább egy háromszög-egyenlőtlenség nem teljesül.
            { // Itt kezdődik az else kódblokkja.
                Console.WriteLine("A megadott adatokból nem szerkeszthető háromszög."); // Tájékoztatjuk a felhasználót arról, hogy a megadott három oldal nem alkothat háromszöget.
            } // Itt ér véget az else kódblokkja.

            // 2. PÉLDA – if / else if / else ÉS Parse HASZNÁLATA.
            // Ebben a példában egy egész számot kérünk be, majd három különböző eset közül választunk.

            Console.Write("Adj meg egy egész számot: "); // Kiírjuk a bekérő üzenetet; a felhasználó ugyanebben a sorban adhatja meg a számot.
            int szám = int.Parse(Console.ReadLine()); // A ReadLine() szöveget ad vissza, az int.Parse() pedig ezt a szöveget int típusú egész számmá alakítja.

            if (szám > 0) // Az első feltétel azt vizsgálja, hogy a szám nagyobb-e nullánál; a kifejezés eredménye true vagy false lehet.
            { // Ez az ág akkor fut le, ha a szám pozitív.
                Console.WriteLine("A megadott szám pozitív."); // Kiírjuk, hogy a felhasználó pozitív számot adott meg.
            } // Itt ér véget az első if ág.
            else if (szám < 0) // Ez a feltétel csak akkor kerül vizsgálatra, ha az előző if hamis volt; azt ellenőrzi, hogy a szám kisebb-e nullánál.
            { // Ez az ág akkor fut le, ha a szám negatív.
                Console.WriteLine("A megadott szám negatív."); // Kiírjuk, hogy a felhasználó negatív számot adott meg.
            } // Itt ér véget az else if ág.
            else // Ide csak akkor jutunk, ha a szám nem nagyobb és nem is kisebb nullánál, tehát csak nulla lehet.
            { // Itt kezdődik a végső else ág.
                Console.WriteLine("A megadott szám nulla."); // Kiírjuk, hogy a felhasználó nullát adott meg.
            } // Itt ér véget az else ág.
        } // Ez a záró kapcsos zárójel lezárja a Main metódus törzsét.
    } // Ez a záró kapcsos zárójel lezárja a Program osztályt.
} // Ez az utolsó záró kapcsos zárójel lezárja a Feltetelvalasztas névteret.


/*
 * FELTÉTELVÁLASZTÁS: if ÉS else
 * -----------------------------
 *
 * A programoknak gyakran döntést kell hozniuk.
 * Például:
 *
 *     - szerkeszthető-e háromszög a megadott oldalakból;
 *     - pozitív, negatív vagy nulla-e egy szám;
 *     - elérte-e valaki a szükséges pontszámot;
 *     - helyes-e egy megadott jelszó.
 *
 * Erre használjuk többek között az if utasítást.
 *
 * Alapformája:
 *
 *     if (feltétel)
 *     {
 *         // Ez a rész akkor fut le, ha a feltétel igaz.
 *     }
 *     else
 *     {
 *         // Ez a rész akkor fut le, ha a feltétel hamis.
 *     }
 *
 * Az if után zárójelben egy logikai kifejezés áll.
 * Ennek eredménye mindig bool érték:
 *
 *     true  -> igaz
 *     false -> hamis
 *
 * Például:
 *
 *     int életkor = 20;
 *
 *     if (életkor >= 18)
 *     {
 *         Console.WriteLine("Nagykorú.");
 *     }
 *     else
 *     {
 *         Console.WriteLine("Kiskorú.");
 *     }
 */


/*
 * ÖSSZEHASONLÍTÓ OPERÁTOROK
 * -------------------------
 *
 * Feltételekben nagyon gyakran két értéket hasonlítunk össze.
 *
 *     >   nagyobb mint
 *     <   kisebb mint
 *     >=  nagyobb vagy egyenlő
 *     <=  kisebb vagy egyenlő
 *     ==  egyenlő-e
 *     !=  nem egyenlő-e
 *
 * Például:
 *
 *     szám > 0
 *
 * igaz, ha a szám pozitív.
 *
 *     szám == 0
 *
 * igaz, ha a szám pontosan nulla.
 *
 * Fontos különbség:
 *
 *     =   -> értékadás
 *     ==  -> összehasonlítás
 *
 * Például:
 *
 *     int szám = 5;   // A szám változó értéke 5 lesz.
 *     szám == 5       // Ez egy kérdés: a szám értéke egyenlő 5-tel?
 */


/*
 * LOGIKAI OPERÁTOROK: &&, ||, !
 * ------------------------------
 *
 * Több feltételt logikai operátorokkal kapcsolhatunk össze.
 *
 *     &&  -> ÉS
 *     ||  -> VAGY
 *     !   -> NEM
 *
 * && – ÉS
 * --------
 *
 * Akkor lesz igaz, ha mindkét oldal igaz.
 *
 *     életkor >= 18 && életkor < 65
 *
 * Ez akkor igaz, ha az életkor legalább 18 ÉS 65-nél kisebb.
 *
 * || – VAGY
 * ---------
 *
 * Akkor lesz igaz, ha legalább az egyik oldal igaz.
 *
 *     nap == "szombat" || nap == "vasárnap"
 *
 * Ez akkor igaz, ha a nap szombat VAGY vasárnap.
 *
 * ! – NEM
 * -------
 *
 * Megfordít egy logikai értéket.
 *
 *     bool esik = true;
 *     !esik
 *
 * A !esik ebben az esetben false.
 */


/*
 * A HÁROMSZÖG FELTÉTELE
 * ---------------------
 *
 * Három pozitív oldalhossz akkor alkothat háromszöget, ha bármely két oldal
 * összege nagyobb a harmadik oldalnál.
 *
 * A programban ezért három feltételt vizsgálunk:
 *
 *     aOldal + bOldal > cOldal
 *     aOldal + cOldal > bOldal
 *     bOldal + cOldal > aOldal
 *
 * Ezeket && operátorral kapcsoljuk össze:
 *
 *     if (aOldal + bOldal > cOldal &&
 *         aOldal + cOldal > bOldal &&
 *         bOldal + cOldal > aOldal)
 *
 * Mivel && szerepel közöttük, az egész feltétel csak akkor true,
 * ha mindhárom részfeltétel true.
 *
 * Ha ez teljesül, lefut az if blokk, és kiszámoljuk a kerületet és a területet.
 * Ha nem teljesül, az else blokk fut le.
 */


/*
 * TÖBB ESET: if – else if – else
 * ------------------------------
 *
 * Nem mindig csak két lehetőség közül szeretnénk választani.
 * Ilyenkor egy vagy több else if ágat is használhatunk.
 *
 * Általános forma:
 *
 *     if (elsőFeltétel)
 *     {
 *         // Ha az első feltétel igaz.
 *     }
 *     else if (másodikFeltétel)
 *     {
 *         // Ha az első hamis, de a második igaz.
 *     }
 *     else
 *     {
 *         // Ha egyik korábbi feltétel sem volt igaz.
 *     }
 *
 * A vizsgálat felülről lefelé történik.
 * Amint a program talál egy igaz feltételt, végrehajtja annak a blokkját,
 * majd az egész if – else if – else szerkezet után folytatja a futást.
 *
 * A program második példája:
 *
 *     if (szám > 0)
 *     {
 *         Console.WriteLine("A megadott szám pozitív.");
 *     }
 *     else if (szám < 0)
 *     {
 *         Console.WriteLine("A megadott szám negatív.");
 *     }
 *     else
 *     {
 *         Console.WriteLine("A megadott szám nulla.");
 *     }
 *
 * Itt három, egymást kizáró esetünk van:
 *
 *     szám > 0  -> pozitív
 *     szám < 0  -> negatív
 *     egyébként -> nulla
 */


/*
 * Console.ReadLine(), Parse ÉS Convert
 * -------------------------------------
 *
 * A Console.ReadLine() a felhasználó által beírt adatot szövegként,
 * vagyis string típusú értékként adja vissza.
 *
 *     string beolvasott = Console.ReadLine();
 *
 * Ha számként szeretnénk vele dolgozni, a szöveget számmá kell alakítani.
 * Ezt többféleképpen is megtehetjük.
 *
 * 1. Parse
 * --------
 *
 * A számtípus saját Parse metódusát használjuk:
 *
 *     int szám = int.Parse("1212");
 *     double érték = double.Parse("12,5");
 *
 * Bekéréssel együtt:
 *
 *     int szám = int.Parse(Console.ReadLine());
 *
 * A végrehajtás sorrendje belülről kifelé:
 *
 *     Console.ReadLine()
 *             ↓
 *     beolvas egy stringet
 *             ↓
 *     int.Parse(...)
 *             ↓
 *     a stringből int értéket készít
 *             ↓
 *     int szám = ...
 *             ↓
 *     az eredményt eltároljuk a szám változóban
 *
 * Más típusoknak is van Parse metódusuk, például:
 *
 *     int.Parse("1212")
 *     double.Parse("12,5")
 *     bool.Parse("true")
 *     DateTime.Parse("2025.09.12")
 *
 * A tizedesjel és egyes dátumformátumok értelmezése a rendszer
 * területi beállításaitól is függhet.
 *
 * Fontos: ha a szöveg nem alakítható a kért típusra, a Parse hibát jelez.
 * Például az int.Parse("alma") nem tud egész számot készíteni az "alma" szövegből.
 * Ennek biztonságosabb kezelésére létezik a TryParse is, ezzel később érdemes foglalkozni.
 *
 * 2. Convert
 * ----------
 *
 * A Convert osztály különböző típusokra alakító metódusokat biztosít:
 *
 *     Convert.ToInt32(...)
 *     Convert.ToDouble(...)
 *     Convert.ToBoolean(...)
 *
 * Például:
 *
 *     double oldal = Convert.ToDouble(Console.ReadLine());
 *
 * A mostani programban szándékosan mindkét megoldás megjelenik:
 * az a oldalnál Convert.ToDouble(), a b és c oldalnál double.Parse(),
 * a második példában pedig int.Parse().
 */


/*
 * IMPLICIT ÉS EXPLICIT TÍPUSKONVERZIÓ
 * -----------------------------------
 *
 * Típuskonverziónak nevezzük, amikor egy értéket egy másik típusú
 * értékként szeretnénk használni.
 *
 * IMPLICIT – rejtett, automatikus konverzió
 * ------------------------------------------
 *
 * Bizonyos átalakításokat a C# automatikusan elvégez, ha azok biztonságosak.
 *
 * Például:
 *
 *     int egész = 12;
 *     double valós = egész;
 *
 * Az int értéke automatikusan átalakítható double típusra.
 *
 * Stringgel végzett összefűzésnél is történhet automatikus szöveggé alakítás:
 *
 *     int a = 1;
 *     string b = "2";
 *     Console.WriteLine(a + b);
 *
 * A kiírt eredmény:
 *
 *     12
 *
 * Itt nem matematikai összeadás történik, hanem szöveg-összefűzés.
 *
 * EXPLICIT – kifejezett konverzió
 * ------------------------------
 *
 * Ilyenkor mi adjuk meg, hogyan szeretnénk átalakítani az értéket.
 * A Parse és a Convert is ilyen, szándékosan kért átalakítást végez.
 *
 *     int szám = int.Parse("42");
 *     double oldal = Convert.ToDouble("12,5");
 */


/*
 * EGÉSZ ÉS VALÓS OSZTÁS – A KIFEJEZÉS TÍPUSA
 * -------------------------------------------
 *
 * Osztásnál különösen fontos, hogy milyen típusú értékek szerepelnek
 * a kifejezésben.
 *
 * Ha mindkét operandus egész típusú, egész osztás történik:
 *
 *     5 / 3      -> 1
 *     2 / 3      -> 0
 *
 * A tört rész ilyenkor elvész.
 *
 * Például:
 *
 *     int a = 7;
 *     int b = 3;
 *     int c = a / b;
 *
 * c értéke 2 lesz.
 *
 * Fontos: attól, hogy az eredményt double változóba tesszük, az osztás
 * még nem lesz automatikusan valós osztás:
 *
 *     double c = a / b;
 *
 * Az a / b előbb int / int műveletként kiszámolódik, vagyis 2 lesz,
 * és csak ezután kerül a 2 érték double változóba, tehát c értéke 2.0.
 *
 * Ha azt szeretnénk, hogy valós osztás történjen, legalább az egyik
 * operandus legyen valós típusú:
 *
 *     double c = a / 4.0;   -> 1.75
 *     2 / 3.0               -> 0.666666...
 *
 * A 4.0 és a 3.0 alapértelmezés szerint double literálok, ezért ezekben
 * a kifejezésekben már valós osztás történik.
 */


/*
 * A HERON-KÉPLET ÉS A KIÍRÁS FORMÁZÁSA
 * ------------------------------------
 *
 * Ha a háromszög szerkeszthető, először kiszámítjuk a kerületet:
 *
 *     double kerület = aOldal + bOldal + cOldal;
 *
 * Ezután a félkerületet:
 *
 *     double s = kerület / 2;
 *
 * Mivel a kerület double típusú, itt valós osztás történik.
 *
 * A Heron-képlet:
 *
 *     T = √(s · (s-a) · (s-b) · (s-c))
 *
 * C#-ban:
 *
 *     double terület = Math.Sqrt(
 *         s * (s - aOldal) * (s - bOldal) * (s - cOldal)
 *     );
 *
 * A Math.Sqrt() a négyzetgyököt számítja ki.
 *
 * A kiírásnál:
 *
 *     Console.WriteLine($"A háromszög területe: {terület:F2}");
 *
 * az F2 azt jelenti, hogy az értéket két tizedesjeggyel jelenítjük meg.
 * Ez csak a megjelenítést befolyásolja; a terület változóban tárolt eredeti
 * double érték nem változik meg.
 *
 * A Math.Round(terület, 2) ezzel szemben egy két tizedesjegyre kerekített
 * számértéket ad vissza.
 */