830 likes | 993 Views
Informatikai rendszerek [gyakorlat]. Powered by Major Péter. Hogyan is néz ki a programozás?. A programok nem mások, mint bináris fájlok , amelyek (ún. gépi kódú) utasításokat tárolnak, amik a számítógép központi egységével végrehajthatók.
E N D
Informatikai rendszerek[gyakorlat] Poweredby Major Péter
Hogyan is néz ki a programozás? • A programok nem mások, mint bináris fájlok, amelyek (ún. gépi kódú) utasításokat tárolnak, amik a számítógép központi egységével végrehajthatók. • A programozók azonban nem ezt hozzák létre, hanem szöveges fájlokat írnak, amelyekben a szöveg bizonyos szabályoknak megfelelő alakú, ez a szabályrendszer maga a programnyelv. • A szöveges fájlból az adott fejlesztőrendszer egy bináris (gépi kódú) fájlt hoz létre, ez történhet a program futás kezdetekor (mint C#/.Net esetben), vagy előre. • Ahhoz, hogy a program jó legyen a szövegnek meg kell felelni a szigorú szintaktikai szabályoknak (a programkódot csak így lehet értelmezni a fordító által), továbbá logikai/matematikai stb. szinten is jónak kell lenni, azaz azt kell csinálnia a programnak amire szántuk, ha a program fut, de ez utóbbi nem teljesül, akkor szemantikai hibáról beszélünk.
Kiinduló pont • Indítsuk el a VisualStudio-t! • FILE / New / Project… • Válasszuk a ConsoleApllication típust! • Adjuk meg a projektnevet és helyet! • Kattintsunk az OK gombra!
Minimális program, kiindulópont Névterek, amelyek tartalma a gyökérből elérhető, pl.: System.Text.Decoder helyett elég csak azt írni, hogy Decoder using System; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; namespace console1 { classProgram { staticvoid Main(string[] args) { } } } A mi programunk névtere A Program nevű osztály, ez maga a program A Main függvény, a program belépési pontja Kezdetben csak ide írunk programot! Vigyázzunk rá, hogy a többi részt ne módosítsuk!
Változók fogalma • A változók gyakorlatilag nem mások, mint azonosítók, amelyek valamilyen értéket képviselnek. Mint a matematika területén az ismeretlenek. • A változók típussal rendelkeznek, amely meghatározza azt, hogy milyen műveletek végezhetők rajtuk, továbbá azt, hogy milyen módon tárolódnak a memóriában. • A változók névvel rendelkeznek, amellyel hivatkozhatunk rájuk. A nevüknek az alábbi követelményeknek kell eleget tennie (mint később minden azonosítónak): • Csak az angol ABC kis és nagybetűiből, valamint számokból és alulvonás (_) karakterből állhatnak. (Kis és nagybetű különbözik!) • Nem kezdődhetnek számmal. • Nem lehetnek azonosak bizonyos foglalt szavakkal, amelyek meghatározó szerepet játszanak a nyelvben. • Nem lehet azonos a nevük, mint a blokkban lévő többi változónak. • A változókat használat előtt deklarálni kell, azaz megjelölni típusukat és nevüket: int a;
Változó deklarációja int a, b = 5, c = 7; • A deklaráció részei: • A változó típusa • A változó neve • A változó kezdőértéke (opcionális) • Pontosvessző • Egyszerre több azonos típusú változó is deklarálható, ilyenkor vesszővel kell elválasztani őket. • A változók a program számos részén deklarálhatóak, amely befolyásolja azt, hogy honnan érhetőek el, azaz ún. hatókörüket (scope). • A változókat használat előtt deklarálni kell, és első olvasásuk előtt mindig értéket kell nekik adni!
Változó típusok • Logikai: • bool(Boolean): igaz vagy hamis • Számok: • Egész számok: • előjelesek: sbyte(SByte), short(Int16), int (Int32), long(Int64) – rendre 8, 16, 32, 64 bitesek – 0..2n-1 • előjel nélküliek: byte (Byte), ushort(UInt16), uint(UInt32), ulong(UInt64) - rendre 8, 16, 32, 64 bitesek – -2n-1..2n-1-1 • Lebegőpontos számok: • float(Single), double(Double) – rendre 32, 64 bitesek • Fixpontos számok: • decimal(Decimal) – 128 bites • Szöveges: • char– egy karakter, unicode (16bit) • string– karakterlánc (szöveg), unicode (16bit)
Változó típusok • Összetett típuscsoportok (ezekről bővebben később tanulunk): • struct, class (struktúra, osztály): olyan típusok melyek több típusú adatot fognak egybe (pl.: több szám, szöveg együtt) • tömbök: egyező típusú adatok sorozata, pl. 10db szám, amelyek indexszel vannak azonosítva (0. elem, 1. elem…) • enum (enumeráció): olyan típus, amely gyakorlatilag olyan, mint az egész szám típusok, de itt az értékeknek neve van, pl. a hét napjai: Hétfő (0), Kedd (1), Szerda (2)
Utótagok (Suffix) • A C# nyelvben a szám konstansok mögé utótagot tehetünk, ha nem teszünk, akkor: • Minden szám, amely egész (pl.: 10, -5) int-ként lesz kezelve. • Minden szám, amely tört (pl.: 6.5, 5e6) double-ként lesz kezelve. • Az utótagokkal elérhetjük, hogy a megadott számok más típusúak legyenek, az utótagok: • uint: u, U • long: l, L (kis l-t ne használjunk, mert összekeverhető egy 1-es el) • ulong: ul, UL • decimal: m, M • double: d, D • float: f, F • Ez egyrészt fontos, mert nem minden adattípus kompatibilis (nincs implicit konverzió, lásd később), másrészt ha még van is automata átalakítás, az időigényes, ezért ennek elkerülésére érdemes törekednünk, ha fontos a sebesség.
Közvetlen értékmegadás • A programkódban sok esetben adunk meg előre értékeket, amelyet így tehetünk meg: bool boolValtozo1 = true; //igaz bool boolValtozo2 = false; //hamis sbytesByteValtozo = -10; bytebyteValtozo = 10; short int16Valtozo = -10; ushort uInt16Valtozo = 10; int int32Valtozo = -10; uint uInt32Valtozo = 10u; long int64Valtozo = -10L; ulong uInt64Valtozo = 10ul; floatsingleValtozo1 = 10f; float singleValtozo2 = 10.5f; //Nem lehet f nélkül! float singleValtozo3 = 1.5e3f; //1500, Nem lehet f nélkül! double doubleValtozo1 = 10d; double doubleValtozo2 = 10.5; double doubleValtozo3 = 1.5e3; decimal decimalValtozo1 = 10m; decimal decimalValtozo2 = 10.5m; //Nem lehet m nélkül! decimal decimalValtozo3 = 1.5e3m; //Nem lehet m nélkül! charcharValtozo = 'c'; stringstringValtozo = "szöveg";
Operátorok • Az operátorok a matematikában használt műveleti jelek programozásbeli megfelelői, így használatuk és céljuk jórészt megegyezik. • Példa: • c = a + b; • d = -c; • +: operátor – a művelet • a, b: operandus – a művelet tárgya • Unáris operátor: egy operandus van (pl. negatív előjel) • Bináris operátor: két operandus van (pl. szorzás) • Az operátorok változók közötti műveleteket tesznek lehetővé. • Az operátorok nem definiáltak mindenfelé adattípusra, pl. nem oszthatunk el két szöveget, hanem jelentésük, alkalmazhatóságuk típushoz kötött. • Operátorok definiálhatóak tetszőleges típushoz (erről, majd később tanulunk).
Operátorok típusai • Aritmetikai operátorok (számtípusokon értelmezettek): • Összeadás: + • Kivonás: - • Szorzás: * • Osztás: / (figyelem, ha egészeket osztunk, akkor az eredmény egész lesz, pl.: 3 / 5 az 0!) • Osztási maradék (modulus): % • Bináris operátorok (egész számokon, bináris alakon értelmezett műveletek) • Biteltolás balra: << (azaz szorzás kettő hatványával), • Biteltolás jobbra: >> (osztás kettő hatványával) • És: & (bitenként) • Vagy: | (bitenként) • Negálás: ~ (bitenként) • Kizáró vagy (nem egyenlő): ^ (bitenként)
Operátorok típusai • Logikai operátorok: • és: && (igaz ha mindkét operandus igaz, különben hamis) • vagy: || (Alt Gr+W gombbal, igaz ha legalább egyik operandus igaz) • kisebb: < • kisebb vagy egyenlő: <= • nagyobb: > • nagyobb vagy egyenlő: >= • egyenlő: == (nem összekeverendő az értékadással, ott egy = van!) • nem egyenlő: != • negálás: ! (ellentétes érték, unáris) • Többit lásd később • Az operátorok precedenciával rendelkeznek, azaz egyes operátorokat a program előbb értékel ki, mint másokat, gyakorlatban például a *, / előbb kiértékelődik, mint +, -. A precedencia sorrend megtalálható számos helyen, gyakorlatban tudjuk a szorzás, osztást, más helyen tegyünk zárójelet.
Operátorok rövidítése • Az értékadás és a kétoperandusú operátorok kombinálhatóak: • Pl.: a = a + b; helyett a += b; • Ez minden kétoperandusú operátorral megy. • Növelés/csökkentés eggyel: • Alkalmazható önálló utasításként: a++; vagy a--; • Kifejezésen belül is: c = a++ * b; vagy c = --a * b; • Ez utóbbinál a jelek helyzete szerint beszélünk: • Preinkrementációról/ predekrementációról, ami az adott kifejezés kiértékelése előtt megy végbe. • Posztinkrementációról/ posztdekrementációról, ami az adott kifejezés kiértékelése után megy végbe. • Azaz az előbbi ekvivalens ezzel: • c = a * b; a++; • --a; c = a * b;
Értékadó utasítások • Az egyik leggyakoribb utasítás, szerkezete: • valtozoNev = kifejezes; • A kifejezés lehet: • Egy másik változó: a = b; • Operátorokkal végzett művelet eredménye: a = b + c * d; • Egy függvény eredménye: a = Math.Sin(b) + c; • Így leírhatók összetett matematikai műveletsorok. • Előfordulhat, hogy különböző típusú változók jelennek meg az értékadás két oldalán, vagy az operátorok között. • Ilyenkor nincs gond, ha van a két típus között úgynevezett implicit konverzió, pl. a = b, helyes akkor is, ha a double és b int. • Operátoroknál az alaplogika az, hogy a nagyobb értékkészletű változó típusával egyezik meg az eredmény.
Egyszerű program using System; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; namespace Gyakorlat1 { classProgram { staticvoid Main(string[] args) { //Egy sor kiiratása a képernyőre Console.WriteLine("Hello világ!"); //Program megállítása ~ várakozás egy enterre Console.WriteLine(); } } } A többi dián sokszor csak a Main függvény szerepel ezután, de a több részre is szükség van!
Kiírás a képernyőre • A Console osztály WriteLine (kiír + új sorba lép) vagy Writefüggvénényével, azaz: • int a = 5*4; • Console.WriteLine(a); • Console.Write(4); • A program megállítása, Enterre várás: • Console.ReadLine(); • Ez persze gyakorlatilag egy sor beolvasása, de mi lesz a beolvasott adattal? • stringszoveg = Console.ReadLine(); • Az osztály fogalmával majd, később ismerkedünk meg!
Kommentek • A programkódba megjegyzések, ún. kommentek fűzhetőek be, amelyek ugyan a program működésében nem vesznek részt, de segítségükkel: • A kód áttekinthetőbbé tehető, pl.: az adott műveletsorozatok fölé egy fejléc beillesztésével • Megjegyzések helyezhetőek el benne, amelyek segíthetik annak megértését mások, vagy magunk számára (mi lesz, ha elő kell venni egy év múlva?) • A kód egy része „kivonható a forgalomból”, tesztelésnél ez jól jöhet, ha egy hibát szeretnénk elkülöníteni • Fajtái: • //Egysoros komment • /* Több soros komment, a kommentben lévő szöveget a fordító nem értelmezi */ • Amennyiben programunk összetett, úgy mindig helyezzünk el kommenteket és törekedjünk sokatmondó változónevek használatára!
Beépített matematikai függvények • A System.Math osztály statikus függvényeivel: • Trigonometrikus függvények (szögek radiánban!): • Sin(x), Cos(x), Tan(x), Asin(x), Acos(x), Atan(x), Atan2(y, x) (origóból induló vektor szöge +x tengellyel, ±π/2, paraméterek: y, x - a vektor koordinátái) • Hiperbolikus függvények: • Sinh(x), Cosh(x), Tanh(x), Asinh(x), Acosh(x), Atanh(x) • Exponenciális, logaritmikus, hatványozó: • Exp(x) (természetes alapú hatvány), Pow(x, y) (tetszőleges alapú hatvány, paraméterek: x – alap; y - kitevő), Sqrt(x) (négyzetgyök), Log(d[, newBase])(természetes v. tetszőleges alapú, paraméterek: d vagy a – a szám aminek logaritmusát vennénk; newBase – a logaritmus alapja [ha nincs megadva, akkor e]), Log10(x) (10-es alapú logaritmus)
Kerekítés • Round • a kerekítés történhet adott tizedes jegy számra, illetve megadható a kerekítés módja: a 0.5-öt felfelé vagy páros szám felé (alapértelmezett!) kerekítsük • Használati módok: • Round(doublevalue) • Round(doublevalue, intdigits) • Round(doublevalue, MidpointRoundingmode) • Round(doublevalue, intdigits, MidpointRoundingmode) • Paraméterek: • value: kerekítendő szám • digits: tizedesjegyek • mode: kerekítési mód, lehet: • MidpointRounding.AwayFromZero – kerekítés felfelé • MidpointRounding.ToEven – kerekítés egész szám felé • Truncate(x)(egészrész), Ceiling(x)(a legkisebb adott értéknél nagyobb egész szám), Floor(x)(a legnagyobb adott értéknél kisebb egész szám)
Egyéb • Egyéb: • Abszolút érték: Abs(x) • Szignum függvény: Sign(x)(szignum függvény, értéke -1, ha x < 0; 0, ha x = 0 és 1, ha x > 0) • Konstansok: E, Pi • Ezek a függvények, illetve konstansok így használhatóak: • double d = 10.14; • double a = Math.Sin(c * Math.Pi) + 5; • d = Math.Sign(a); • Stb. • Gyakorlási tipp: • Írjon programot, amely megold valamilyen egyszerű matematikai problémát! A bemeneti adatokat adja meg változók kezdőértékeként! Számolja ki a részeredményeket (deklarálja a szükséges változókat is)! Írassa ki a képernyőre az eredményt!
Algoritmusok felépítése • Minden algoritmus alapvetően három alapelemből épül fel: • Szekvencia: az utasítások egymás utáni végrehajtása • Szelekció (elágazás): választás, valamely feltételtől függően más-más műveletek mennek végbe • Iteráció (ciklus): ugyanazon műveleteket többször egymás után hajtjuk végre (ez természetesen nem azt jelenti általában, hogy pont ugyanaz történik, hiszen közben program állapota változik, pl. számos ugyanolyan elemen [tömb!] elvégzünk egy műveletet)
Elágazások - if • Az elágazás ellenőriz egy logikai feltételt (hogy igaz-e?) és az alapján dönt mit is csináljunk: Console.WriteLine("Osztó program"); Console.WriteLine("Add meg az osztandót!"); doubleosztando = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Add meg az osztót!"); doubleoszto = Convert.ToDouble(Console.ReadLine()); if (oszto == 0) //Feltétel: egy logikai kifejezés { //Ez fut le, ha a feltétel igaz Console.WriteLine("Hopsz, nullával nem tudunk osztani! :("); } else { //Ez fut le, ha hamis //Ez az ág elhagyható Console.WriteLine("Az eredmény: " + (osztando / oszto).ToString()); } Console.ReadLine();
Elágazások - if if([feltétel]) { [...kód, ha a feltétel igaz...] } else { [...kód, ha a feltétel hamis...] } • Szerkezete: • Az else elhagyható. • Ha csak egy utasításból állna az igaz vagy hamis ág, akkor nem kell blokkot használni.
Elágazások - switch • Egy változó értékétől függően, más-más kódrész fut le. • A default ág akkor fut le, ha a változó értéke egyik megadott case-el sem egyezik meg. • A default ág elhagyható. switch([változó]) { case [érték1]: [...kód...] break; case [érték2]: case [érték3]: [...kód...] break; default: [...kód...] break; }
Példa staticvoid Main(string[] args) { Console.WriteLine("Kérem a pontszámot! (0..100)"); intpontszam = int.Parse(Console.ReadLine()); if (pontszam >= 0 && pontszam <= 100) { int jegy = 0; if (pontszam >= 85) { jegy = 5; } elseif (pontszam >= 70) { jegy = 4; } elseif (pontszam >= 55) { jegy = 3; } elseif (pontszam >= 40) { jegy = 2; } else { jegy = 1; } stringszoveg = ""; switch (jegy) { case1: szoveg = "Elégtelen"; break; case 2: szoveg = "Elégséges"; break; case 3: szoveg = "Közepes"; break; case 4: szoveg = "Jó"; break; case 5: szoveg = "Jeles"; break; default: szoveg = "Hiba"; break; } Console.WriteLine("Az érdemjegy: " + szoveg + "."); } else { Console.WriteLine(„A pontszám nincs 0 és 100 között!"); } Console.ReadLine(); } Ez a példa egy favágó megoldás, de kiválóan szemlélteti a két elágazás működését!
Adatok beolvasása • Adatot beolvasni csak szövegként lehet. Azonban a megfelelő formátumú karakterláncok átalakíthatóak számmá. • A szöveg beolvasása a következőképpen történik: • stringszoveg = Console.Readline(); • Ez addig olvassa be a szöveget míg be ütünk entert. • Ezután a beolvasott adat más típussá alakítható: • Az egyes számtípusok Parse(…) függvényével: • int a = int.Parse(szoveg); • Ha nem sikerül az átalakítás, akkor úgynevezett kivétel (hiba) keletkezik • Az egyes típusok TryParse(…) függvényével: • Int a; bool siker = TryParse(szoveg, out a); • A visszatérési érték megadja, hogy sikerült-e az átalakítás. • A Convert osztállyal: int a = Convert.ToInt32(szoveg); (lásd később)
Convert osztály • A Convert osztály ToByte(…), ToSByte(…), ToInt16(…), ToInt32(…), ToInt64(…), ToUInt16(…), ToUInt32(…), ToUInt64(…), ToSingle(…), ToDouble(…), ToString(…), ToChar(…), ToDecimal(…) függvényei a paraméterben megadott kifejezést a kívánt típusba (lásd a függvények neve) alakítják.
Szöveg alakítása számmá • Az szám struktúrák rendelkeznek egy Parse(string s) metódussal (pl.: int.Parse(…), double.Parse(…) stb.), ami az s paramétert átalakítja az adott típussá, ha a paraméter nem szám, akkor kivétel (lásd később) keletkezik. • Ugyancsak van egy boolTryParse(string s, out <típus>result) metódusuk is, amely visszaadja sikerült-e az átalakítás, illetve egy kimeneti paraméterben (lásd. később) az átalakított eredményt.
Kivételek • Sokszor előfordul, hogy az általunk kezdeményezett művelet valamiért nem hajtható végre, például mert: • Nem megfelelőek a megadott paraméterek • Valamilyen erőforrás (például.: fájl, hálózat, nyomtató, grafikus kártya stb.) nem elérhető, vagy nem rendelkezik a szükséges képességekkel • Ilyenkor a függvények úgynevezett kivételeket hoznak létre, amelyek hibaüzenettel megszakítják alkalmazásunk futását. Ez azonban nem jelenti, azt hogy a program rosszul működik. Csak azt, hogy ezeket a különleges eseteket kezelnünk kell. • Ez a try … catch blokkal végezhető el: • try { /*kivételt kiváltani képes kód*/ ] } catch { /*hiba kezelése*/ } • Ha a try részben kivétel keletkezik, akkor kód futása megszakad és a catch részben folytatódik • Amennyiben olyan kódot írunk, ahol kivétel keletkezhet, úgy azt mindig kezelni kell (ZH-ban is)!
Kivételek kezelése staticdoubleOlvassBeEgySzamot() { Console.WriteLine("Kérek egy számot!"); boolsikerult = false; doubleszam = 0d; do { try//A try blokkban várjuk a hibát { //A következő sor hibát okozhat, ha a megadott szöveg nem szám szam = double.Parse(Console.ReadLine()); sikerult = true; //Ez a sor márnemfut le ha hiba van } catch//Ha hiba történik, akkor lefut ez a blokk { Console.WriteLine("Ez nem szám! Próbáld újra!"); } } while(!sikerult); returnszam; }
Saját függvények definiálása • Amennyiben egy adott kódrészt szeretnénk többször használni, vagy szeretnénk programunkat átláthatóbbá tenni létrehozhatunk függvényeket. • A függvények kódjának általános felépítése: • visszatérési_érték_típusafüggvénynév([ref | out] típus1 paraméter1, [ref | out]típus2 paraméter2, …) • { • //…kód… • return eredmény; • }
Saját függvények definiálása • Ha nincs visszatérési érték, akkor a visszatérési érték típusa „void”. • Minden paraméter elé kell írni annak típusát, a paraméterek sorát vesszővel kell tagolni. • A return használható eredmény nélkül is, ha nincs visszatérési érték, ilyenkor egyszerűen befejezi a függvény futását. A return szerepelhet elágazások több ágában is. Ha visszatérési érték van, akkor mindig kell return (minden kódágba). • Ha nincs visszatérési érték, akkor a return nem kötelező, de használható, pl. adott feltétel esetén befejezzük a függvény futtatását. • A return után a függvény futása véget ér, akkor is ha utána van még utasítás! (Azok nem futnak le!) • Több függvény is lehet ugyanolyan névvel, ha a paraméterlistájuk eltérő (paraméter típus és sorrend, név nyilván nem számít, hiszen az híváskor nincs ott). Ezt nevezzük a függvények túltöltésének (overloading).
Példa – kétdimenziós vektor szöge az x+ tengelyhez képest derékszögű koordinátarendszerben A függvény így hívható: publicdoubleSzog(double x, double y) { if (x >= 0) { if (y >= 0) { returnMath.Atan(y / x); } else { returnMath.PI * 2d - Math.Atan(-y / x); } } else { if (y >= 0) { returnMath.PI - Math.Atan(-y / x); } else { returnMath.PI + Math.Atan(y / x); } } } doublex = Szog(0d, 1d);
Paraméterátadás • A függvények paraméterei mint lokális változók működnek, így értékük módosítható: • Ha érték típusú a változó, akkor a másolattal dolgozunk, nincs visszahatás az eredeti értékre. (ilyenek az egyszerű adattípusok, lásd később) • Ha referencia típusú az adott paraméter, akkor az eredeti adaton dolgozunk, tehát a függvény módosíthatja az átadott változó tartalmát. (lásd később) • Ha érték típusú paraméteren szeretnénk változtatni, úgy hogy az a hívó fél felöl látszódjon, akkor a ref ill. out szavakat kell a paraméter típusa elé írni, a következőképpen: • ref: olyan változót várunk paraméternek, amely már előre meghatározott értékkel rendelkezik, azaz szeretnénk kiolvasni tartalmát, majd visszaírni • out: olyan változót várunk paraméternek, amely értékét a függvény határozza majd meg, csak írni akarunk bele. • A ref és out szavakat a függvény hívásakor is ki kell írni a megadott változó neve elé! Ilyenkor az adott paraméter csak változó lehet (egyéb kifejezés nem)! • Ezek teszik lehetővé egynél több érték kivitelét a függvényből.
Globális és lokális változók • A függvényekben deklarált változók csak a függvény futása alatt léteznek, és a függvény futásának befejeztével törlődnek a memóriából. • Ezek a változók más függvényekben nem láthatók, és a tartalmuk a függvény minden futásakor törlődik (ugye mert amúgy nem is léteznek). • Az ilyen változókat lokálisváltozóknak nevezzük. • A függvények tartományában, tehát a függvények fejlécével egy szinten definiált változók az összes velük egy szinten lévő függvényből láthatók, ezek globálisváltozók a függvényekből nézve.
Példafeladatok • Írjon függvényt, amely egy másodfokú egyenlet együtthatóiból megadja annak valós megoldásait! • Bemeneti paraméterek: a, b, c • Kimeneti paraméterek: x1, x2 • Visszatérési érték: megoldások száma 0..2 • Írjon a függvény teszteléséhez főprogramot!
Példafeladatok • Írjon függvényt amely megadja két kétdimenziós vektor által bezárt szöget koszinusztétel segítségével! • Bemeneti paraméterek: x1, y1, x2, y2 az origóból induló vektorok végpontjai • Visszatérési érték: a szög radiánban • Írjon a függvény teszteléséhez főprogramot!
Példaprogramok • Írjon programot, amely bekéri egy időtartam hosszát, mint mérőszámot és mértékegységet (a felhasználó egy listából választhat), majd kiírja hogy az összesen hány év, hét, nap, óra, perc, másodperc pl. így: • Adja meg az időtartam hosszát! • 23,4 • Válassza ki a mértékegységet (1 - év, 2 – hét, 3 – nap, 4 – óra, 5 – perc, 6 - másodperc): 4 • Az ön által megadott időtartam összesen: 23 óra 24 perc
Ciklusok - for for (int i = 0; i < 10; i++) { […ismétlődő kód…] } • Szerkezete: • Ahol a for kulcsszó utáni zárójeles rész három része: • értékadás a ciklusváltozónak (i) – gyakorlatilag bármely utasítás, ami egyszer le fog futni az ismétlés előtt • az ismétlés feltétele, addig ismétel amíg igaz – bármely bool értékű kifejezés megfelel ide • a ciklusváltozó változtatása, ciklusonként egyszer hívódik meg ami itt van - tetszőleges utasítás lehet • az első és utolsó tag a fejlécben lehet több utasítás is, ilyenkor az egyes utasítások közé vesszőt kell rakni
Ciklusok - while while([feltétel]) { […ismétlődő kód…] } vagy: do { […ismétlődő kód…] } while([feltétel]); • Szerkezete: • Amíg a feltétel igaz, addig ismétel. A feltétel egy logikai típusú kifejezés. • Az előbbi az ún. elől tesztelő, a második a hátul tesztelő ciklus
Ciklusok – continue & break • Lehetőség van arra, hogy egy ciklus adott iterációjából a következő körre ugorjunk (ha van még), erre szolgál a continue utasítás. Ennek hívása után azonnal a következő kör következik, vagy a ciklus vége (ha a feltételek olyanok). • Ha ki szeretnénk lépni a ciklusból, azt a break utasítással tehetjük meg. Ilyenkor a ciklus hátralévő része elmarad.
.Net adattípusok csoportosítása • A .Net adattípusai két csoportba sorolhatóak. Az egyszerű adattípusok, amelyeket eddig használtunk az ún. érték típusok (valuetypes) • Ezek egy értéket tárolnak és ebből fakadóan az ilyen változóknak mindig van értékük.Ha az adatot továbbítjuk a program másik részébe, akkor lemásolódik, a másoltok pedig nincsenek hatással az eredeti változókra. • Ezzel szemben vannak úgynevezett referencia típusok. Ezek szigorú értelemben nem egy értéket, hanem annak hivatkozását tárolják – azaz azt, hogy merre található a memóriában. • Az ilyen változók nem minden esetben rendelkeznek értékkel, pontosabban értékük lehet null, ha éppen nem hivatkoznak semmire. • Ezért ahhoz, hogy az ilyen változókat használni lehessen, először memóriát kell foglalni. Ehhez a new utasítást kell használni (lásd később). • A memória felszabadítását az ún. szemétgyűjtő (GarbageCollector, GC) végzi. Ehhez időnként átnézi a programot, és megkeresi azokat a memóriában tárolt értékeket, amelyekre nincs hivatkozás = egyik referencia változó sem hivatkozik rájuk, és ezeket törli a memóriából.
.Net adattípusok csoportosítása • Érték típusok: • Mindig rendelkeznek valamilyen értékkel. • A deklaráció után azonnal használhatók. • A=B; utasítás estén: • A értéke meg fog egyezni B értékével • Paraméterátadáskor: • Lokális másolat készül a paraméterről. A változtatások a külvilágra nem hatnak. • Ilyen például: • bool, enum, byte, short, int, long, float, double, struct • Referencia típusok: • Értékük lehet null. • A használat előtt a new kulcsszóval hozzuk létre őket. • A=B; utasítás esetén: • A és B ugyanazt a változót jelöli. • Paraméterátadáskor: • Az eredeti változót közvetlenül elérjük. • Ilyen például: • string, class • tömbök
Tömbök • A tömbök arra szolgálnak, hogy több ugyanolyan típusú adatot tároljunk bennük és az elemeket sorszámmal, ún. indexszel azonosítsuk. • A tömböknek több fajtája létezik: • Egydimenziós tömbök (vektorok): az elemek n elemű tömb esetén 0..n-1 indexekkel rendelkeznek. • Többdimenziós tömbök (mátrixok): az indexekből annyi van ahány dimenziója van az adott tömbnek, minden dimenzió más méretű lehet. Pl.: 5x4x3 méretű 3 dimenziós tömb, az indexek rendre 0..4; 0..3; 0..2 tartományokban vannak. • „Recés” tömb (jaggedarray): tömbök tömbje, abban különbözik a többdimenziós tömbtől, hogy itt minden elem egy külön tömb, ezért más-más méretük lehet. • A tömbök referencia típusú változók, tehát átadáskor a referencia adódik át ezért a módosítások mindenhol látszanak. • A tömböknek használat előtt memóriát kell lefoglalni, a memóriafoglalás során meg kell adni a tömbök méretét, amely ezután nem változtatható meg.
Tömbök használata RandomR = newRandom(); //Véletlenszám generátor osztály példányának létrehozása int[] szamok = newint[20]; //20 elemű int tömb létrehozása for (int i = 0; i < szamok.Length; i++) //szamok.Length -> megadja a tömb méretét { szamok[i] = R.Next(100); //Egész szám generálás nullától 99-ig } int[,] matrix = newint[3, 3]; //3x3-as tömb létrehozása for (int i = 0; i < matrix.GetLength(0); i++) //matrix.GetLength(0) -> tömb mérete a 0. (első) dimenzióban { for (int j = 0; j < matrix.GetLength(1); j++) { matrix[i, j] = R.Next(100); //Egész szám generálás nullától 99-ig } } int[][] jegyek = newint[10][]; //Tömb diákok jegyeinek tárolására for (int i = 0; i < jegyek.Length; i++) { jegyek[i] = newint[R.Next(5)]; //Mindenkinek max 4 jegye lehet for (int j = 0; j < jegyek[i].Length; j++) { jegyek[i][j] = R.Next(5) + 1; //Jegyek 1-től 5-ig } }
Tömbök • Egyező típusú adatok sokaságának tárolására szolgál. • Használata (10 elemű tömbbel): • Használat előtt helyet kell foglalni a tömb számára, ilyenkor megadjuk a tömb méretét. • Az elemek a [] operátorral érhetőek el. • A tömb mérete a tomb.Length jellemzővel kapható meg. • Számozásuk mindig 0-tól a tomb.Length-1-ig tart. int[] tomb; tomb = newint[10]; tomb[0] = 4; tomb[1] = 4 + tomb[0];
Többdimenziós tömbök int[,] tomb; tomb = newint[10,15]; tomb[0,2] = 4; tomb[1,1] = 4 + tomb[0,2]; • Használat: • A különböző dimenziókra vonatkozó méreteket ill. pozíciókat vesszővel választjuk el. • A Length mező ilyenkor az összes elem száma. • A dimenziónkénti elemszám az intGetLength( intdimension) metódussal kapható meg.