Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Informatikai rendszerek [gyakorlat]

Hasonló előadás


Az előadások a következő témára: "Informatikai rendszerek [gyakorlat]"— Előadás másolata:

1 Informatikai rendszerek [gyakorlat]
Powered by Major Péter

2 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.

3 Kiinduló pont Indítsuk el a VisualStudio-t! FILE / New / Project…
Válasszuk a Console Apllication típust! Adjuk meg a projektnevet és helyet! Kattintsunk az OK gombra!

4 Minimális program, kiindulópont
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace console1 { class Program static void Main(string[] args) } Névterek, amelyek tartalma a gyökérből elérhető, pl.: System.Text.Decoder helyett elég csak azt írni, hogy Decoder 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!

5 Változók fogalma int a;
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;

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

7 Változó típusok Fixpontos számok: 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)

8 Adattípusok összefoglaló táblázata
Típusnév másképpen (egyenértékű) Helyigény (bit) Példa (literális) Logikai változó bool Boolean 8 (!) true, false Egész szám (*: előjel nélküli) sbyte, byte* SByte, Byte 8 - short, ushort* Int16, UInt16 16 int, uint* Int32, UInt32 32 12, 12u long, ulong* Int64, UInt64 64 12l, 12ul Lebegőpontos szám float Single 6.5f double Double 6.5, 6.5e10 Fixpontos decimal Decimal 128 12m Karakter char Char ’c’ Szöveg string String változó ”szöveg”

9 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)

10 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.

11 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 sbyte sByteValtozo = -10; byte byteValtozo = 10; short int16Valtozo = -10; ushort uInt16Valtozo = 10; int int32Valtozo = -10; uint uInt32Valtozo = 10u; long int64Valtozo = -10L; ulong uInt64Valtozo = 10ul; float singleValtozo1 = 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! char charValtozo = 'c'; string stringValtozo = "szöveg";

12 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).

13 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)

14 Operátorok típusai Logikai operátorok: Többit lásd később
é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.

15 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;

16 É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.

17 Implicit konverzió ˇHova short ushort int uint long float ulong
< Honnan ˇHova short ushort int uint long float ulong decimal double sbyte x byte char

18 Egyszerű program using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Gyakorlat1 { class Program static void 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!

19 Kiírás a képernyőre A Console osztály WriteLine (kiír + új sorba lép) vagy Write fü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? string szoveg = Console.ReadLine(); Az osztály fogalmával majd, később ismerkedünk meg!

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

21 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)

22 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(double value) Round(double value, int digits) Round(double value, MidpointRounding mode) Round(double value, int digits, MidpointRounding mode) 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)

23 Egyéb Egyéb: Ezek a függvények, illetve konstansok így használhatóak:
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!

24 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)

25 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!"); double osztando = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Add meg az osztót!"); double oszto = 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();

26 Elágazások - if Szerkezete: if([feltétel]) {
Az else elhagyható. Ha csak egy utasításból állna az igaz vagy hamis ág, akkor nem kell blokkot használni. if([feltétel]) { [...kód, ha a feltétel igaz...] } else [...kód, ha a feltétel hamis...]

27 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]: default: }

28 Példa static void Main(string[] args) { Console.WriteLine("Kérem a pontszámot! (0..100)"); int pontszam = int.Parse(Console.ReadLine()); if (pontszam >= 0 && pontszam <= 100) int jegy = 0; if (pontszam >= 85) jegy = 5; } else if (pontszam >= 70) jegy = 4; else if (pontszam >= 55) jegy = 3; else if (pontszam >= 40) jegy = 2; else jegy = 1; string szoveg = ""; switch (jegy) { case 1: szoveg = "Elégtelen"; break; case 2: szoveg = "Elégséges"; case 3: szoveg = "Közepes"; case 4: szoveg = "Jó"; case 5: szoveg = "Jeles"; default: szoveg = "Hiba"; } 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!

29 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: string szoveg = 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)

30 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.

31 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 bool TryParse(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.

32 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)!

33 Kivételek kezelése static double OlvassBeEgySzamot() { Console.WriteLine("Kérek egy számot!"); bool sikerult = false; double szam = 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ár nem fut 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); return szam;

34 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ípusa függvénynév([ref | out] típus1 paraméter1, [ref | out] típus2 paraméter2, …) { //…kód… return eredmény; }

35 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).

36 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ó: public double Szog(double x, double y) { if (x >= 0) if (y >= 0) return Math.Atan(y / x); } else return Math.PI * 2d - Math.Atan(-y / x); return Math.PI - Math.Atan(-y / x); return Math.PI + Math.Atan(y / x); double x = Szog(0d, 1d);

37 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.

38 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ális vá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ális változók a függvényekből nézve.

39 Példafeladatok Írjon függvényt, amely egy másodfokú egyenlet együtthatóiból megadja annak valós megoldásait! 𝑎 𝑥 2 +𝑏 𝑥+𝑐=0 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!

40 Í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!

41 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

42 Ciklusok - for 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 for (int i = 0; i < 10; i++) { […ismétlődő kód…] }

43 Ciklusok - while 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 while([feltétel]) { […ismétlődő kód…] } vagy: do while([feltétel]);

44 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.

45 .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 (value types) 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ő (Garbage Collector, 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.

46 .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

47 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 (jagged array): 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.

48 Tömbök használata Random R = new Random(); //Véletlenszám generátor osztály példányának létrehozása int[] szamok = new int[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 = new int[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 = new int[10][]; //Tömb diákok jegyeinek tárolására for (int i = 0; i < jegyek.Length; i++) jegyek[i] = new int[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

49 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 = new int[10]; tomb[0] = 4; tomb[1] = 4 + tomb[0];

50 Többdimenziós tömbök 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 int GetLength( int dimension) metódussal kapható meg. int[,] tomb; tomb = new int[10,15]; tomb[0,2] = 4; tomb[1,1] = 4 + tomb[0,2];

51 Szövegek kezelése Szöveg konstansok, összefűzés, adott karakter kiolvasása: A stringek kezelésére szolgáló függvények a string osztály metódusai, tehát tetszőleges string változó után pontot téve elérhetők. Ezek a metódusok mindig új szöveg objektumot hoznak létre, ezért teljesítmény szempontjából érdemes lehet a StringBuilder osztály használata. string szoveg = "hello"; szoveg += " world"; char c = szoveg[0]; //c=='h'

52 Stringkezelő függvények
int IndexOf( string value ): szöveg első előfordulásának meghatározása int LastIndexOf( string value ): szöveg utolsó előfordulásának meghatározása string Insert( int startIndex, string value ): szöveg beszúrása adott pozícióba int Length { get; }: szöveg hossza string PadLeft( int totalWidth, char paddingChar ): kiegészítés adott szélességre adott karakterrel balról string PadRight( int totalWidth, char paddingChar ) : kiegészítés adott szélességre adott karakterrel jobbról string Remove( int startIndex, int count ): adott pozíciótól adott számú karakter eltávolítása string Replace( string oldValue, string newValue ): keresés és csere string[] Split( string[] separator, StringSplitOptions options ): szöveg szétvágása adott határoló stringel

53 Stringkezelő függvények
string[] Split( char[] separator, StringSplitOptions options ): szöveg szétvágása adott határoló karakterrel bool StartsWith( string value ): visszaadja, hogy ezzel a karakterlánccal kezdődik-e a szöveg string Substring( int startIndex, int length ): adott kezdőpozíciótól adott hosszúságú szövegrészt adja vissza string ToLower(): átalakítás kisbetűssé string ToUpper(): átalakítás nagybetűssé string Trim( params char[] trimChars ): adott karakterek levágása a szöveg elejéről és végéről string TrimEnd( params char[] trimChars ) : adott karakterek levágása a szöveg végéről string TrimStart( params char[] trimChars ) : adott karakterek levágása a szöveg elejéről bool EndsWith( string value ): visszaadja, hogy ezzel a karakterlánccal végződik-e a szöveg

54 Struktúrák, osztályok A .Net környezetben a struktúrák és osztályok együtt tárgyalhatók, így egyrészt könnyen bemutathatók egyező tulajdonságaik, de lehetőség van az eltérések bemutatására is. A struktúrák és az osztályok és azért kerültek létrehozásra, mert bennük összetartozó műveletek és adatok összekapcsolhatók, a struktúrákkal és osztályokkal új adattípusok hozhatóak létre. Számos szempontból a struktúra az osztály kistestvérének tekinthető, ugyanakkor számos esetben érdemes lehet osztály helyett struktúrát alkalmazni.

55 Struktúrák, osztályok tagjainak láthatósága
A struktúrákban és osztályokban lévő elemek ún. láthatósággal rendelkeznek, amely meghatározza, hogy a kód mely részeiből érhetőek el, a láthatóság főbb szintjei: private: csak az adott osztályon / struktúrán belül látszik protected: az adott osztályon belül látszik, és a belőle leszármaztatott osztályokon belül (struktúráknál nincs öröklődés, így ott nincs értelme) public: mindenhol látszik, az osztályon / struktúrán belül és kívül is A láthatóság szintjét a változó, függvény… stb. elé kell írni a kódban, mindig ez a legelső elem a sorban. Ha nem adjuk meg a láthatóság mértékét, akkor a rendszer az elemet private-nak tekinti!

56 Egy egyszerű osztály felépítése
public class Vasarlo { public int ID; public string Nev; public int Egyenleg; public void Vasarol(int ertek) Egyenleg -= ertek; } public void Fizet(int ertek) Egyenleg += ertek;

57 Egy egyszerű osztály használata
Az osztályt a new foglalt szóval kell létrehozni. A benne lévő tagok „.”-al érhetőek el. A függvények és változók így egyszerűen elérhetőek. Vasarlo V = new Vasarlo(); V.ID = 1; V.Nev = "Gazdag János"; V.Fizet(12000); V.Vasarol(11499); Console.WriteLine("Visszajár: " + V.Egyenleg.ToString());

58 Osztályok Az osztályok definíciójának nevezzük azt, ami a class blokkban szerepel, ez írja le, hogy hogyan néz ki egy osztály. Amikor az osztályt használjuk, akkor annak példányait használjuk, pl. az előző példában, amikor megadjuk azt, hogy a vásárló neve „Gazdag János”, akkor az csak egy példányra vonatkozik. Létrehozhatunk egy másik vásárlót is más névvel ugyanilyen módon.

59 Fogalmak Ha valami egy adott osztályon v. struktúrán belül van arra szokás az osztály tagjaként (member) hivatkozni: Ha az illető egy függvény, akkor az az adott osztály v. struktúra metódusa (method). Ha változó vagy konstans, akkor mezőnek (field) nevezzük. Illetve vannak még jellemzők (property), ezekről később. A következő oldalakon általában osztályokat említek a szövegben, de az itt leírtak igazak lesznek a struktúrákra is, ha nincs külön megjelölve.

60 Referencia típusú változók
Az osztályok referencia típusú változók, ez azt jelenti, hogy értékadásnál nem maga az érték, hanem annak hivatkozása (memóriahelye) másolódik. Ez azt jelenti egyben, hogy ha pl. A és B osztály típusú változók, és A-nak értéket adunk (new-al), majd azt írjuk, hogy B = A, akkor B és A ugyanazt fogja jelölni. Ugyanez történik értékadás esetén is. A struktúrák viszont érték típusúak, így rájuk ez nem vonatkozik!

61 Referencia típusú változók
Minden referencia típusnak, így az osztályoknak is lehet null értéke, ilyenkor az adott változó semmilyen referenciát nem hordoz. Ez természetesen azt jelenti, hogy ilyenkor a változó nem használható. A null-ság ellenőrizhető az == operátorral, pl.: if(V == null) … Ha egy referencia típusú változót deklarálunk, akkor az még nem rendelkezik hozzárendelt memóriaterülettel. Ezért meg kell hívni new függvényt, amint az előző példa is mutatta. Referencia típusúak az osztályokon kívül például még a string-ek és a tömbök is.

62 Konstruktor Az osztályok a new paranccsal hozhatóak létre, ha utána megadjuk az osztály nevét, majd a zárójelek közé a megfelelő paramétereket (ha vannak). Ilyenkor meghívódik az osztály konstruktora, amely az osztály alapértékeinek beállításáért felel és/vagy erőforrásokat foglal le. Pl.: ha az osztályon belül vannak tömbök, akkor a konstruktor lefoglalhatja a memóriát az elemek számára. Ha magunk hozunk létre osztálytípust, akkor alapesetben a rendszer egy alapértelmezett konstruktort használ, ami a változók értékeit alapértékre állítja (pl. egy int változó 0 lesz, míg egy tömb vagy egy osztály null). Ha azt szeretnénk, hogy mi adhassuk meg a kezdőértékeket, illetve más az osztály használatbavétele előtt szükséges műveleteket szeretnénk elvégezni, akkor magunknak kell konstruktort létrehozni.

63 A konstruktor A következőt az előbbi Vasarlo osztály blokkján belül kell elhelyezni: public Vasarlo(int id, string nev) { ID = id; Nev = nev; Egyenleg = 0; } A konstruktor mindig olyan nevű mint az osztály! Nincs típus megadva a visszatérési értéknél! Ezután az osztály így hozható létre: Vasarlo V = new Vasarlo(1, "Kovács Tamás"); Ha nem definiáltunk külön konstruktort, de szeretnénk több változónak is kiinduló értéket adni, akkor az megtehető így is: Vasarlo V = new Vasarlo() { ID = 1, Nev = "Gazdag János", Egyenleg = 0 };

64 Elérhetőség public class Vasarlo { public int ID; public string Nev;
private int Egyenleg; //Ezután már nem jó, ha azt írjuk, hogy V.Egyenleg = 410; public void Vasarol(int ertek) Egyenleg -= ertek; } public void Fizet(int ertek) Egyenleg += ertek; public int MennyiAzEgyenleg() return Egyenleg; Ahogy azt a láthatóságnál ismertettem, többfajta láthatósági szint létezik. Például ha a példában az Egyenleg mező elé public helyett private-t írunk, akkor az egyenleg már nem lesz módosítható kívülről. Ha nem választunk elérhetőségi szintet (nem írjuk, hogy public v. provate stb.), akkor alapértelmezetten minden public lesz.

65 Tagok láthatósága Egy osztály tagjainak láthatósága megszabja azok honnan érhetőek el, a három legelterjedtebb láthatósági szint: private: csak az adott osztály éri el a tagot public: mindenki látja az adott tagot, az osztályon kívül és belül is protected: csak az adott osztály és a belőle származtatottak (lásd később) látják az adott tagot A láthatóság mindig a deklaráció sorának első helyén szerepel, pl.: private double KiszamolValamit(double a) Ha nem jelöljük meg milyen egy tag láthatósága, akkor az automatikusan private lesz.

66 Kis kitérő - struktúrák
Mi a különbség? Nem referencia, hanem érték típusúak: azaz értékük csak másolódhat, két azonosító nem jelölheti ugyanazt a helyet a memóriában. Értékadásnál, függvényhívásnál az értékek másolódnak, visszahatáshoz függvénynél kell a ref vagy az out! Ha nincs paramétere a konstruktornak, akkor nem kötelező a new, ilyenkor azonnal használható a változó, viszont saját konsHa megadtunk konstruktort, akkor kötelező a new is! Csak paraméteres konstruktort adhatunk meg! A struktúra tömbök esetén az elemeket nem kell egyenként létrehozni használat esetén (kivéve paraméteres konstruktornál), míg osztályoknál igen. A struktúrák alapesetben kevesebb helyet foglalnak a memóriában és gyorsabban használhatók. A struktúrák is tárolhatnak függvényeket és jellemzőket, viszont nem örökölhet tőlük senki (lásd később). A class helyett a struct szót kell használni 

67 Statikus elemek Az osztályok és struktúrák tartalmazhatnak statikus elemeket, amelyek nem tartoznak az adott példányhoz, hanem magához a típus definícióhoz kötöttek. Függvények esetén ez azt jelenti a függvény az osztály / struktúra példányaitól függetlenül létezik, a statikus függvények a típus neve után pontot rakva és nevüket beírva elérhetők. A statikus függvényekben nem elérhetők a példányokra jellemző adatok (pl.: belső változók). Változók esetén ez azt jelenti, hogy a változó csak egy példányban létezik, de minden osztálypéldány látja (ugyanazt az egyet), és elérhető a típusnév után pontot rakva ugyanúgy, mint a statikus függvényeknél.

68 Statikus elemek példa A statikus konstruktor csak private lehet és nem lehet paramétere. A statikus NextID minden példányban ugyanaz. A statikus függvény így hívható: Vasarlo.IDNullaz(); A statikus függvény nem látja az egyes példányok változóit, hiszen ő közvetlenül a típushoz kapcsolódik, ezért a híváskor is az osztály neve utáni ponttal + a nevével kell hívni. A statikus publikus változók ugyanígy hívhatók. A statikus függvényeknek ezenkívül nem térnek el a többi függvénytől. static int NextID; static Vasarlo() //Statikus konstruktor { NextID = 1; } public Vasarlo(string nev) //Konstruktor Nev = nev; ID = NextID++; Egyenleg = 0; public static IDNullaz() //Statikus függvény NextID = 0;

69 Konstansok és csak olvasható „változók”
A konstansok olyanok mint a változók, de értékük nem változtatható meg, azt direkt módon (const int hat = 6;) meg kell adni. Értékük mindig előre meghatározott fix érték. Nem egy változó értékű kifejezés. A konstansok ezen kívül hasonlítanak a statikus változókra. A változó típusa és láthatósága közé írjuk, hogy const. A csak olvasható változók értéke csak a deklarációnál adható meg, azonban a konstansoktól eltérően ilyenkor egy kifejezésből (pl.: függvényből) is kaphatnak értéket. A csak olvasható változók értéke más és más lehet példányonként szemben a konstansokkal. A csak olvasható változók deklarációjában a típus elé a readonly szó kerül. Lehetnek statikusak is.

70 Jellemzők, tulajdonságok
Számos esetben előfordul, hogy olyan változót akarunk az osztályon kívülről láthatóvá tenni, amelynek értékét csak belülről szabad módosítani. Tételezzük fel például egy olyan osztályt, amely vevők egy csoportjának személyi adatait tárolja, ez az osztály lehetővé teszi a benne tárolt rekordok számának lekérdezését, de ezt kívülről nem szabad módosítani, hanem azt csak elem hozzáadása és törlése metódusokkal lehet elérni. Régen ezt a programnyelvek úgy oldották meg, hogy beállító és kiolvasó függvényeket adtak meg, és csak így lehetett/szabadott hozzáférni ezen változók tartalmához. A fejlett programnyelvek azonban ennél sokkal szebb és kevésbé hibaveszélyes módszert találtak, így születtek meg a jellemzők (property). A jellemző tulajdonságban egyfajta virtuális változó, mivel elérésekor valójában függvényeket hív meg a rendszer.

71 Jellemzők, tulajdonságok
A tipikus jellemző formája: public int Jellemzo { get […valami kód…] return [kifejezés]; } [private | protected] set [a beállítani kívánt érték elérhető itt a value változóban] A jellemzőben elhagyható a get vagy set rész (elég ha van egyik), illetve a részek láthatósága külön is állítható. Kívülről továbbra is úgy érhető el a jellemző mint a változók, pl.: ValamilyenOsztalyPeldanya.Jellemzo = 6; Ha a jellemző csak olvasható, vagy csak írható és mi ezt nem tartjuk be, hibaüzenetet kapunk.

72 Jellemzők, tulajdonságok
A tipikus csak olvasható jellemző formája: private int vevoSzam=0; public int VevoSzam { get […valami kód…] return vevoSzam; }

73 Jellemzők, tulajdonságok
Ha csak arra van szükségünk, hogy egy változó csak belülről legyen írható, akkor használható a rövidített írásmód. A gyakorlatban akkor is szokás használni a rövidített írásmódot, ha nincs szükség semmilyen extra funkcióra, de a kódot szebbé teheti. A fordító ilyen esetben ugyanazt csinálja mint egyszerű változók esetén (szóval teljesítménycsökkenés nincs). A rövid írásmód: public string RovidJellemzo { get; [private | protected…] set; } Természetesen a get és set, valamint az egész jellemző számos variációban láttatható.

74 Osztályok származtatása
A C#-ban az adattípusok egymásból vannak leszármaztatva. A származtatás azt jelenti, hogy az adott típus minden funkcióját megkapja a leszármazott is, de lehetőség van új funkciókkal való felvértezésre is. C#-ban minden típus az object-ből származik, amelynek két gyermeke a struct (struktúra) és a class (osztály), amelyek az érték és a referencia típusú változók ősei. A struktúrák ága jóval kisebb mélységű mint az osztályoké, ugyanis egy struktúrából már nem lehet tovább származtatni, minden struktúra a struct gyermeke. Ezzel szemben az osztályok tetszőleges mélységben származtathatók egymástól, sőt egy osztály több őssel is rendelkezhet (bár ezeknek csak egyike lehet osztály, a többi interfész, lásd később). A származtatás egyik előnye, hogy minden leszármazott osztály betöltheti az ősei szerepét is. Például ha csinálunk egy listát az egyetemmel kapcsolatban álló személyekkel, akkor a személy osztályból leszármaztatható a tanárok, a diákok vagy pl. a gazdaságisok osztálya, de ezek mindegyike ellátja a személy osztály feladatait, pl.: van kereszt és vezetékneve, kora stb. Ugyanakkor a tanárok tanszékekhez vannak rendelve, míg a diákok nem stb.

75 Osztályok származtatása
A gyakorlatban az osztályok származtatása igen egyszerű, csak a definíció fejlécébe kell írni egy kettőspont után a szülőket, pl.: class Hallgato : Szemely, Targyfelvevo { […] } Ezután az osztály kódjából elérhetőek az ősök változói, metódusai stb. És ha pl. egy függvény egy Szemely típusú paramétert vár, akkor oda jó egy Hallgato példánya is.

76 Metódusok felülbírálása
Előfordul, hogy egy osztály az ős metódusait nem csak mennyiségben kívánja bővíteni, hanem a meglévőkön is változtatni kíván, ennek feltétele, hogy az ős az adott metódust megjelölje a virtual szóval, pl.: public virtual double Szamol() { […kód…] } a leszármazottban a felülírás: public override double Szamol() [base.Szamol();] //ős metódus meghívása Jellemzők is lehetnek virtuálisak! Írásmódjuk hasonló a függvényekéhez, csak ott a fejlécben jellemző van.

77 Absztrakt osztályok Gyakran előfordulhat olyan is, hogy pl. egy tömbben hasonló elemeket akarunk tárolni, ezért létrehozunk egy ős osztályt, ezt adjuk meg a tömb deklarációjában, ugyanakkor a valóságban csak a leszármazottak kellenek. Ebben az esetben használhatóak az ún. absztrakt osztályok, amelyekből példány nem hozható létre, és tartalmazhatnak olyan függvényeket, melyeknek csak fejléce van megadva, de nincs törzsük.

78 Absztrakt osztályok Példa: Jellemző is lehet absztrakt!
abstract class Dolgozo { public string Nev; public int Kor; public abstract int FizetesSzamolasa(); //nincs törzs //de van helyette ; } //leszármazott: class Technikus : Dolgozo public override int FizetesSzamolasa() //a leszármazottnak minden absztrakt dolgot meg kell ténylegesen adnia, ha ő már //nem absztrakt Jellemző is lehet absztrakt!

79 Delegáltak A C# egy speciális változótípusa a delegált, amely meglepő módon igazából nem adatokat, hanem függvényeket tárol. Ehhez először meg kell adni magát a delegált típust = milyen fejlécű függvényekre hivatkozhat, pl.: delegate void Muvelet(double a, double b); Majd deklarálni kell a változót: Muvelet ElvegzendoMuvelet; Ha pl. van pár függvényünk: void Emel(double a) { […kód…] } void Tol(double x) { […kód…] } Megtehtjük ezt: ElvegzendoMuvelet+=Emel; ElvegzendoMuvelet+=Tol; ElvegzendoMuvelet(3); Ez utóbbi meghívja mindkét függvényt a hozzáadás sorrendjében. Egy művelet többször is hozzáadható, míg a -= operátor eltávolít egy példányt, ha tagja a csoportnak. Ha egy delegált nem tartalmaz egy függvényt sem, akkor hívása hibát okoz, ezért ilyenkor == null ellenőrzést kell végezni.

80 Események Na de mire is jók igazából a delegáltak?
Arra, hogy egy osztály meghívhassa egy tetszőleges másik osztály függvényét, anélkül, hogy azt előre ismernie kellene előre. Pl.: egy gomb jelezhet, hogy őt megnyomták, úgy hogy neki van egy delegáltja, amit ilyenkor meghív, mi pedig hozzáadhatjuk a gombnyomásra adott válaszfüggvényünket ehhez. Az ilyen delegáltak deklarációjakor egy speciális event szót szokás használni, így: public event EventHandler Click; Itt az EventHandler a delegált, a Click az esemény neve.

81 Névterek Mivel igen sok célra léteznek osztályok, így ezek ömlesztett kezelése nem célszerű, ezért az osztályokat rekeszekbe, ún. névterekbe rakjuk. A névterek rendszere hasonló a fájlrendszerhez, ahol fájlokat mappákba rakhatjuk, így egy hierarchikus rendszert hozva létre. A programozási rendszer által biztosított elemek névterekben vannak aszerint, hogy milyen feladatot töltenek be, pl. fájlkezelés, ablakok, kezelőfelület, hálózati kommunikáció stb. A névterekben úgy jelölünk egy elérési utat, mint a fájlrendszerben: C:\Users\Major Péter\Documents\Órarend.xls (A C meghajtó Users mappájában van egy Major Péter mappa ebben pedig egy Documents mappa, amelyben elhelyezkedik az Órarend.xls nevű fájl) System.IO.Path (A System névtérben van egy IO névtér, ebben van egy Path nevű osztály)


Letölteni ppt "Informatikai rendszerek [gyakorlat]"

Hasonló előadás


Google Hirdetések