Professional Documents
Culture Documents
2
Karsa Zoltn
foglalkozzunk. A 7. sorban a main metdus, aminek minden programban lennie kell! A main minden c# kd
belpsi pontja, mikor elindul a program az itt vgzett utastsok, vagy alprogramok meghvsa esetn az
alprogramokban lv utastsok futnak le! A 9. sorban a kirats s a 10-es sorban a billentyletsre vr
fggvny. Ajnlott a {} jelek hasznlata, de nem minden esetben ktelez, a kapcsos zrjelek segtsgvel
tlthatbb lesz a programunk! Miutn begpeltk a kdot nyomjuk meg a Start gombot, s ha nem ejtettnk
szintaktikai hibt, akkor lefut a programunk s a kpen lthat eredmnyt adja. A szintaktikai hibkat piros
recs alhzssal jelzi a program s addig nem engedi futtatni a kdot. A nyelv lehetv teszi kommentek
beszrst a fjlba a // s a /**/ jelek hasznlatval, a // csak az abban a sorban lev szveget kommentezi ki,
gy a fordts utni kimenetre az itt lv szveg nincs hatssal, mg akkor se, ha megfelel kdot rtunk ide
ugyangy, mint a /**/ csak hogy ez tbb soros is lehet.
Megjegyzs: n a Visual Studio 2015 Enterprise verzit hasznlom, de megteszi rgebbi verzi is.
Szorgalmi feladat: Milyen kimenet jelenik meg, ha begpeljk az albbi kdot a mainbe?
Console.Write("Milyen");
Console.WriteLine(" lesz");
Console.WriteLine(" a kimenete");
Console.Write(" az albbi");
Console.WriteLine(" kdnak?");
Console.ReadKey();
//Console.WriteLine("Hahaa");
//ez itt egy egysoros komment
Ha nem tudjuk, prbljuk ki a visual studio-ban a programot!
Adatszerkezetek
vltozk, tpusok
Mi a vltoz? A vltoz a memriban lefoglalt bitek azonostja s tartalma. deklarls - egy vltoznvvel
elltott tpust hozunk ltre; definils - a vltoznvvel elltott tpusnak rtket is adunk. A tpusok egy-egy
algoritmusban a megadott tpus rtknek trolsra hasznlt memria tartomnynak elnevezse. Mrete
korltokhoz kttt. A nyelvben az albbi mdon definilunk s deklarlunk egy vltozt:
Dek.: tpus vltoznv; Pl.: int szam1;
Def.: tpus vltoznv = rtk; Pl.: string szo = "vr";
A c# nyelvben a szm tpusokat csak simn a vltoznv utn egy = jellel s utna egy szmmal deklarljuk, mg
a szveges (cahr, string) tpusokat char (1db karakter) esetben '' jelek kz string-nl (karakterlnc -
gyakorlatilag vgtelen karakter) "" jelek kz rjuk, s gy definiljuk.
A vltozk nvadsakor trekedjnk arra, hogy a vltoz neve tkrzze a vltoz tartalmt. A vltozk neve
betkkel vagy _ jellel kell kezddnie, ezutn az sszes karakter megengedett (a magyar kezetes betk is
hasznlhatk), hossza ltalban 32 karakter lehet.
Fontosabb adattpusok: szm tpusok: egsz (sbyte, byte, short, ushort, int, uint, long, ulong) illetve a vals-
lebegpontosszmok (float, double, decimal). Az s-signed eljeles az u-unsigned eljeltelent jelli, gy pldul a
sbyte (signed byte-eljeles byte) kpes negatv szmok trolsra is. Logikai tpus: bool (true-igaz, false-hamis)
Karakteres tpus: char-karakter, string-karakterlnc
Fontos: ez nem az sszes tpust tartalmazza, ezek az alapvet tpusok, ezeken kvl vannak osztlyok,
konstruktorok, objektumok, struktrk, listk, tmbk...!
A vltozk nem kpesek a vgtelensgig a szmok eltrolsra, az albbi tblzat tartalmazza az alapvet
tpusok rtkhalmazt, az rtkhalmazon kvl es szm nem trolhat el benne! Trekedjnk mindig a
megfelel tpust vlasztani az adott vltoznak, hogy cskkentsk az adott memria ignyt (pl.: tudjuk, hogy
egy vltoz 0 s 100 kztti rtket vesz majd csak fel, ezrt byte tpust hasznlunk).
Nv rtkhalmaz Helyfoglals (bit)
bool logikai true vagy false 1
char karakter 1db karakter 16
string - karakterlnc U 0 232 db karakter
byte, sbyte 0-255, -128-127 8
ushort, short 0 65535; -32708 - 32767 16
uint, int 0 4,2 * 109, -2,1*109 2,1 * 109 32
18 18 18
ulong, long 0 18 * 10 , -9 * 10 9 * 10 64
Lebegpontos szmok 32 - 128
3
Karsa Zoltn
Mveletek a tpusokkal: Lssuk be nem sokat r a vltoz, ha nem tudjuk mdostani. A matematikban
megszokott mveletekkel adhatunk ssze, vonhatunk ki, oszthatunk Csak azonos tpusokat adhatunk ssze
konvertls nlkl (ksbb sz lesz rla). Pldk:
int a = 7; //vltoz ltrehozsa, rtkads
int b = 3; //vltoz ltrehozsa, rtkads
//az ab vltozba lesz eltrolva a + b eredmnye
int ab = a + b;
int aszorb = a * b; //21
//a b vltozt egyenlv tesszk b + 3, teht nveljk a b rtkt 3-mal
b = b + 3; //ugyan azt az eredmnyt kapjuk, csak rvidtve
b += 3; //Pldul az albbi kplet megegyezik:
a -= 2;
a = a - 2; //<--ezzel
//stringek sszeadsa/sszefzse
string str1 = "alma";
string str2 = "fa";
string ossz = str1 + str2; //az eredmny: almafa
int a = 2, b = 4, c; //tbb vltoz ltrehozsa egy sorban
Vltozk kiratsa: rassuk ki a kpernyre a vltozk rtkt a + opertorral, stringeknl sszefzst jelent, gy
a + opertorral rathatjuk ki a vltoznkat. Plda:
int eredmeny = 2;
Console.WriteLine("Az eredmny " + eredmeny + " lett.");
Szorgalmi feladat: Gyakoroljunk: hozzunk ltre kt vltozt s adjunk nekik rtket, ezutn rassuk ki a
vltozk sszegt s klnbsgt, el ne felejtsk a Console.ReadKey()-t a vgrl!
int j, i = 5;
j = i;
j++;
Console.WriteLine(i);
4
Karsa Zoltn
Precedenciai rangsor
opertorok s mvelettpusok rangsora
A precedenciai rangsor egy olyan rangsor, amelyet a nyelv kvet s olyan sorrendben rtelmezi a mveleteket,
amilyen sorrendben le van rva ebben a tblzatban. Pldul a matematikban is a () jeles rszek utn a
szorzst, majd az egyb mveleteket vesszk figyelembe.
Mvelettpus Opertorok
1. Elsdleges (), [], x++, x--, new, typeof,
sizeof, checked, unchecked
2. Egyoperandus +, -, !, ~, ++x, --x
3. Multiplikatv *, /, %
4. Additv +, -
5. Eltolsi <<, >>
6. Relcis <, >, <=, >=,
7. Egyenlsgi ==, !=
8. AND &
9. XOR ^
10. OR |
11. Feltteles AND &&
12. Felt. OR ||
13. Feltteles mvelet ?:
14. rtkads az sszes rtkad opertor
Ne ijedjnk meg a tblzat nagysgtl, a nyelv megismerse sorn magunktl megtanuljuk ezeket, nhny
opertor mg nem is fontos az alapoknl.
5
Karsa Zoltn
Adatbekrs a konzolrl
Console.ReadLine(), konvertls
Mit kell tennnk akkor, hogy ha a felhasznltl akarjuk elkrni az adatait, megkrjk, hogy adjon meg valami
informcit? Erre szolglnak a Console.ReadLine() s a Console.ReadKey() fggvnyek, a ReadLine()
enter lenyomsra vr s az enter lenyomsa utn beolvassa a bert szveget, ezrt stringet ad vissza, viszont ha
valamilyen matematikai mveletet szeretnnk rajta elvgezni, akkor szintaktikailag hibs lesz. Ennek elkerlse
rdekben t kell alaktani szm tpuss a string-et, hogy mkd kpes legyen, kt lehetsgnk van a string
szmm val talaktsra:
string beker = Console.ReadLine();//szveg bekrse s eltrolsa a beker vltozban
int szam1 = int.Parse(beker); //vltoz = tpus.Parse(string tpus)
int szam2 = Convert.ToInt32(beker); //vltoz = Convert.To+tpus+(valamilyen tpus)
A bekeres nev string vltozba eltroljuk a bekrt szveget (mert hiszen string, hiba az rtke pldul 5),
majd a szam1 s szam2-nl lv Parse s Convert fggvny alaktja t szmm. A Parse fggvny csak string-bl
kpes valamilyen egyb vltozba konvertlni, viszont a Convert megbirkzik az sszes vltozval, gy kpes
brmelyikbl brmelyikbe konvertlni. Ha nem int-be szeretnnk konvertlni, cserljk le az int-eket a
megfelel tpusra pl.:
string beker = Console.ReadLine();
byte szam1 = byte.Parse(beker);
byte szam2 = Convert.ToByte(beker);
A konvertlst lehet egy sorba is rni az albbi alakban, ilyenkor nem trolunk el stringet:
int bekertszam1 = int.Parse(Console.ReadLine()); //vagy
int bekertszam2 = Convert.ToInt32(Console.ReadLine());
Ha nem valamilyen szmot adunk meg, akkor kifagy a programunk s kivtelt dob, ezrt figyelmeztessk a
felhasznlt, hogy csak szmot adjon meg, ksbb megtanuljuk a kivtelkezelst is. A kivtel:
System.FormatException azaz nem megfelel formtum kivtel.
Bekrsnl a Parse fggvnyt ajnlott hasznlni! A ReadKey egy darab billentyt olvas be s ConsoleKey tpust
ad vissza ennek talaktst itt nem trgyalom, egy darabig csak a programok vgn fogjuk hasznlni, hogy ne
zrdjon be az ablak.
Egy pldaprogram az eddig tanultakrl:
//nvtr, main
Console.Write("Add meg a tglalap egyik oldalt: ");
int a = byte.Parse(Console.ReadLine());
Console.Write("Add meg a tglalap msik oldalt: ");
int b = byte.Parse(Console.ReadLine());
int ker = 2 * (a + b); int ter = a * b;
Console.WriteLine("A tglalap kerlete " + ker + " cm, terlete " + ter + " cm2");
Console.ReadKey();
6
Karsa Zoltn
Konvertls, castols
ConverTo, castols
Mit kell tennnk, ha kt klnbz tpus szmot szeretnnk sszeadni, ssze adni ssze tudjuk, csak a tpus
talaktssal elveszhetnek fontos dolgok (prbljunk meg kt egymssal maradk nlkl nem oszthat int tpust
egymssal elosztani, az eredmny egsz?). Konvertlssal viszont mr a megfelel tpusv konvertlhatjuk a
szmunkat. A castols is ugyan az csak egyszerbb rsmdban. Plda:
int szam1 = 5; int szam2 = 120;
double maradeknincs = szam1 / szam2; //ha kiratjuk 0-t kapunk
double vanmaradek = (double)szam1 / szam2; //megolds: castols
double vanmaradek2 = Convert.ToDouble(szam1) / szam2; //vagy konvertlssal
Console.WriteLine("Nincs maradk:" + maradeknincs + " Van " + vanmaradek);
Console.ReadKey();
7
Karsa Zoltn
Felttelek egymsba gazsa Gyakran szksgnk van sszetettebb elgazsokra is. if (feltetel){
Ekkor az ifen vagy az elsen bell ltre kell hozni mg egy elgazst. A program fentrl //utasts1
}
lefel halad gy ha a felttel igaz akkor lp be az ifen bellre s csak utna veszi else {
if (feltetel){ figyelembe a kvetkez felttelt, ha nem teljesl az els if (feltetel){
//utasts1 szint felttel, akkor a msodik szint mr nem hajtdik //utasts2
} }
vgre, ha az if gban van! Ugyangy, ha a msodik felttelt }
else if (feltetel){
//utasts2 az else gba tesszk s az els felttel igaz lesz, akkor mr
} nem lpbe
az else Console.WriteLine("Add meg a dolgozat maximlis pontszmt: ");
int dogamaxp = int.Parse(Console.ReadLine());
gba gy nem is fogja megvizsglni a Console.WriteLine("Add meg a dolgozatban elrt pontszmot: ");
msodik elgazst. Jegyezzk meg, int dogaelertp = int.Parse(Console.ReadLine());
hogy egy if-elgazsnak csak EGY double szazalek = (double)dogaelertp / dogamaxp * 100;
if (szazalek > 90) {
kimenetele lehet, nem lehet olyan Console.WriteLine("A dolgozat jegye: 5");
hogy mindkt g, teht a hamis s a } else {
negatv gban lv utastsok is if (szazalek > 80) {
Console.WriteLine("A dolgozat jegye: 4");
lefutnak!! Ha egy sszetettebb } else if (szazalek > 70) {
felttelt szeretnnk leprogramozni Console.WriteLine("A dolgozat jegye: 3");
} else if (szazalek > 60) {
szksgnk van akr tbb if-re is, ez Console.WriteLine("A dolgozat jegye: 2");
egy kicsit bonyolultabb teszi a kd } else {
megrtst. Ha megfelelen Console.WriteLine("A dolgozat jegye: 1");
}
hasznljuk a tabultort s a kapcsos }
zrjeleket, akkor olvashatbb, Console.ReadKey();
rthetbb vlik a kd. Nzznk erre
is egy pldafeladatot: Csinljunk egy olyan programot, amely bekri egy dolgozat maximlis pontszmt, majd
az abbl elrt pontszmot s megadja a jegyet. Az egyszersg kedvrt 90%-tl 5, 80%-tl 4, 70%-tl 3, 60%-
tl 2 s 60% alatt elgtelen. Gondolkozzunk el mit kell csinlni, elszr be kell krni 2db adatot majd a
megfelel feltteleket alkalmazva ki kell ratnunk a jegyet. Ki kell szmolni a szzalkos rtkt is a
dolgozatoknak majd ez sszehasonltjuk a megadott szzalkokkal. Az els if megvizsglja, hogy a megkapott
szazalek nagyobb-e 90-nl, ha nagyobb a dolgozat ts s nem vizsglja tovbb a feltteleket (hiszen az else
gban van). Ha nem akkor tovbb vizsgl Az else if () egy rvidtett vltozat, gyakorlatilag azt rvidti le, hogy
ha az elz if az else gba lp s jra kvetn egy if felttel pl:
8
Karsa Zoltn
a zrjelen kvl van egy or, ebbl pedig az kvetkezik, hogy vagy az a < 3 nak
kell igaznak lennie, vagy a zrjeles rsznek, vagy mindkettnek.
Szorgalmi feladat: Gyakoroljuk az if szerkezetet! Csinljunk egy olyan
programot, amely bekr egy magassgot (cm) s kirja a kpernyre a
kvetkezket:Ha 140cm kisebb akkor rja ki, hogy alacsony, ha 140-170
tlagos s 170cm nagyobb, akkor rja ki, hogy magas. Segtsg: a feladatot 2
if-else szerkezettel kell megoldani!
Szelekcik elgazsok: switch
kapcsol
A switch egy olyan elgazs, amelyben szinte vgtelen elgazs lehetsges. A
folyamatbrja megtekinthet a jobb oldalon, mondatszer lersban sok
felttelekkel kell lerni, ahol a felttel egy rsze megegyezik a tbbi rsszel.
Nzzk meg a c#-os formjt: Ha megnzzk kzelebbrl, akkor minden egyes
felttelnl az egyenlsgt vizsgljuk (pl.:bekeres == "aut"), ha az rtk
hamis, akkor tugrik a kvetkez 'sszehasonltsra' s gy tovbb, ha nem
tallt egyetlen egy egyezt sem, akkor a default gnl lv utasts fog
lejtszdni. Fontos hogy csak s kizrlag == lehet vizsglni ms opertorokat
(<,>, != ) nem lehet hasznlni. A case ggal j sszehasonltst hvunk s
mg rjuk az sszehasonltst, majd egy kettsponttal nyitjuk, nem ;-vel,
utna kapcsos zrjel s mg az utols zrjel eltt egy break; utasts, ami ksbb a ciklusbl val kilpsre
fog szolglni. A default egy vgs megolds, akkor fog lefutni a default
gban lv utasts, ha semelyik case g nem volt megfelel. Mint az
iffet is, a switchet is egymsba lehet tenni. Switchet akkor hasznljunk,
ha az rtkek ktttek. Pldul egy dobkocknl, ahol 6 lehetsg van,
ezrt knnyen lehet alkalmazni.
Nzznk egy egyszer programot a switch szemlltetsre: A
felhasznl megadja, hogy hnyast dobott a dobkockval, s a
programunk rja ki a dobott szmot betvel Megjegyzs: van
egyszerbb md is erre, lsd: tmbk, de a bemutats miatt switchel
oldom meg! Elszr nzzk meg hogy, hogy is nzne ki ifekkel:
int dobottszam = int.Parse(Console.ReadLine());
if (dobottszam == 1) {
Console.Write("Egy");
} else if (dobottszam == 2) {
Console.Write("Kett");
} else if (dobottszam == 3) {
Console.Write("Hrom"); int dobottszam = int.Parse(Console.ReadLine());
} //gy tovbb, nagyon fraszt gy vizsglni switch (dobottszam)
{
Nzzk meg ugyanezt switchel: case 1:
Console.Write("Egy"); break;
Fontos hogy csak a == felttelek helyettestsre case 2:
hasznlhat! Mondatszer lersban sok felttellel Console.Write("Kett"); break;
lehet lerni a switch szerkezett. case 3:
Console.Write("Hrom"); break;
Szorgalmi feladat: csinljuk meg a fenti kdot
//...
folyamatbrban s stuktogramban! }
9
Karsa Zoltn
Itercik ciklusok: elltesztel ciklus (while)
while, pros szmok kiratsa, vgtelenciklus, break, continue
Az elltesztel ciklus "elszr vizsgl, s utlag vgez", teht mieltt belpnk a ciklusmagba, a ciklus
megvizsglja a felttelt s utna vgzi el az utastsokat, majd jra vizsgl s vgez, jra, jra s jra, ameddig a
felttel hamis nem lesz. Szlssges esetben 0-szor hajtdik vgre. ltalban ltre szoktunk hozni mg egy
vltozt, amit majd vizsglhatunk ez esetben a parosszam az s a ciklus addig fut (addig ismtli a ciklusmagot)
10
Karsa Zoltn
Console.WriteLine("Add meg a jelszt!"); Folyamatbrban az a klnbsg az elltesztel ciklussal
string passw; szemben, hogy elszr a csompontba rkezik be, utna
do { kvetkezik a bekrs s azutn a vizsglat, a <> Pascal nyelven
passw = Console.ReadLine();
} while (passw != "123"); a nem egyenlt jelenti, c#-ban ez a !=. A stuktogramban
Console.WriteLine("Sikeres belps!"); elszr szerepel a ciklusmag s utna a felttel. Megjegyzs:
Console.ReadKey(); Pascalban a htultesztel ciklusnl, akkor kezdi el jra a
ciklusmag futtatst, ha a vizsglat hamis eredmnyt adott,
de az itt lthat brkban nem foglalkoztam vele s a tovbbiakban sem hasznlom ezt a szemlletet!
A szmllvezrelt ciklus (for-ciklus) teljesen gy mkdik, mint egy while azzal a klnbsggel, hogy itt
ltrehoztunk egy szmllt (i) s ennek vltoztatsval tudjuk a felttelt folyton vizsglni. az els rsze int i = 0;
ltrehozzuk a segdvltozt a msodik rsze a felttel, s vgl az i++ az i rtkt nveli 1-el. For-nl mindig az
i++ formt hasznljuk!
rdekessg: A for-ciklusnak van egy "testvre" a foreach ciklus, ezt majd a tmbk krbejrsra fogjuk
hasznlni, egyelre nem lnyeges. Mondatszer lersban a for-ciklus ltalnos formja: Ciklus, i := 1-tl,
felttel (pl.: N-ig), x lpssel (pl.: i := i + 1 lpssel) ciklusmag Ciklus vge. Struktogramoknl s
folyamatbrknl kln utastsokkal kell nvelnnk a ciklus vltozt s ltrehozni is kell! Pldafeladatknt
szmtsuk ki 10!-t (faktorilis: egy n nem negatv egsz szm faktorilisnak az n-tl 1-ig terjed sorozat
elemeinek szorzata, pl.: 3! = 3*2*1 = 6) egy for-ciklussal! Mivel a szorzs tnyezi felcserlhetk, ezrt
kezdhetjk az i segdvltozt 10-tl 1-ig vagy 1-tl nvelhetjk 10-ig. Ennek megfelelen az i++ vagy az i
alakot kell hasznlni. A felttel nvels esetn i <= 10 vagy i < 11 ennek megfelelen cskkents esetn i >= 1
vagy i > 0. Ltre kell hozni egy fakt vltozt, amibe eltroljuk majd a szorzatok eredmnyt.
// a fakt vltozt 1-rl indtsuk, mivel ez nem foglya befolysolni a megoldst
int fakt = 1; // elg lenne az i-t 2-vel indtani mivel az eggyel val szorzsnak nincs jelentsge
for (int i = 1; i <= 10; i++) {
//fakt = fakt * i; rvidtett alakja;
fakt *= i;
}
Console.WriteLine(fakt);
Console.ReadKey();
Prmszmok kiratsa 1000-ig, avagy ciklusok egymsba gyazsa
Egyszer minden programoz szembe tkzik azzal a gonddal, hogy rassuk ki a prmszmokat (azok a
termszetes szmok, amelyeknek csak kett osztjuk van: 1 s nmaga): Haladjunk kvlrl befel, az els for
arra szolgl, hogy lptesse neknk azokat a szmokat, ami ksbb az osztand szerept fogja betlteni. Utna
ltrehoztam egy bool(logikai) tpust ami arra szolgl, hogy ha az rtke true marad akkor ki lehet rni az aktulis
i szmot, ami prmszm. A kvetkez for arra szolgl, hogy lptesse neknk az osztt. Nem lehet ezen bell mg
egy i ciklusvltoz, mert mr van egy. Fontos, hogy j nem lehet egyenl nullval, mert nullval val oszts nincs
s ne legyen 1-se, mert az 1 minden egsz szm osztja, ezrt indtjuk a j-t 2-rl. A for-ciklus felttele j addig
menjen amg nem ri el az i-t (hiszen flsleges tovbb vizsglnia), szintn a j < i felttel nem lehet j <= i, mert
akkor a szm nmagval oszthatsgt is megvizsgljuk (mert ugye minden szm nmagval osztva 1 ad, s
nem ad maradkot) s ott van egy && is mivel ha mr talltunk egy olyan szmot ami oszthat az adott
szmmal, teht a szm mr biztosan nem lesz prmszm, emiatt mr nem kell tovbb vizsglnunk. Az if arra kell,
hogy megnzze, hogy oszthat-e a szm maradk nlkl, a % opertor visszaadja kt szm maradkt. Ha a
maradk 0 (teht oszthat maradk nlkl) akkor tlltjuk a primszam logikai tpust falsera, mert talltunk neki
osztt, ergo nem lehet prmszm. A kvetkez ifben, ha a primszam logikai tpus igaz, azaz az aktulis i
prmszm kirja, ha hamis akkor nem.
for (int i = 2; i < 1000; i++) {
bool primszam = true;
for (int j = 2; j < i && primszam; j++) {
if (i % j == 0) primszam = false;
}
if (primszam) Console.WriteLine(i);}
11
Karsa Zoltn
Tipp: Ha Visual Studioban F11-el elindtjuk ezt a programot, ott lpsrl lpsre lehet haladni a programban, s
kzben mutatja a vltozk rtkeit s taln gy knnyebben is megrthet.
Console.BackgroundColor
A Console.BackgroundColor a konzolon kirt betk httrsznt lltja t egy belltott sznre. Hasznlata a
ConsoleColor.szn -nel
Console.BackgroundColor = ConsoleColor.Blue;
Console.WriteLine("Ez kk htter szveg");
Console.ForegroundColor
A Console.ForegroundColor a konzolon kirt betk sznt lltja t egy belltott sznre.
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Ez zld szn szveg");
Console.ResetColor()
A Console.ResetColor() visszalltja alaprtelmezett rtkre a httr s a szveg sznt.
Console.ForegroundColor = ConsoleColor.Green;
Console.BackgroundColor =
ConsoleColor.DarkBlue;
Console.WriteLine("Sznes");
Console.ResetColor();
Console.WriteLine("Alaprtelmezett");
Console.Clear();
A Console.Clear() trli az ablak tartalmt, vagy ha kzvetlenl a httrszn belltsa utn hasznljuk,
akkor az egsz htteret az adott sznre lltja be.
Console.BackgroundColor = ConsoleColor.DarkBlue;
Console.Clear();
Console.Beep();
A Console.Beep(frekvencia, id tartalom ms-ban) spolst eredmnyez.
Console.Beep(400, 1000);
Console.Title
A Console.Title a konzol ablak cmnek elnevezsre szolgl, ha nem lltjuk be ezt az rtket, akkor az
adott program elrsi tja lesz az ablak neve. A Console.Title-nek egy string tpust kell adnunk = jellel, plda:
Console.Title = "ablak";
Console.WindowHeight s WindowWidth
A Console.WindowHeight s WindowWidth az ablak aktulis magassgt s szlessgt mondja meg,
melyet el is trolhatunk egy vltozban. int m = Console.WindowHeight, sz = Console.WindowWidth;
Console.WriteLine(m + "*" + sz);
Console.SetWindowSize(,)
A Console.SetWindowSize(int szlessg, int magassg) metdus a konzol ablak mretnek
belltsra szolgl, ha nem lltjuk be
Console.SetWindowSize(50, 40);
alaprtelmezetten 80 szlessg s 25
karakterterlet magassg. Plda:
12
Karsa Zoltn
Console.SetCursorPosition(,)
A Console.SetCursorPosition(int oszlop ,int sor) a kurzor helynek belltsra szolgl. Kpzeljk el a konzol
ablakot egy koordinta rendszerknt melyben az x tengely balrl jobbra 0-tl az ablak szlessgig tart,
valamint az y tengely, ami fentrl lefel, 0-tl az ablak magassgig tart. Az ablak bal fels sarka a 0, 0
koordinta s jobb als sarka 79, 24 koordinta (80 szlessg s 25 magassg ablak esetn). Ha az ablakon
kvlre es koordintt adunk meg, amit a program nem kpes elrni, akkor a
System.ArgumentOutOfRangeException kivtel addik, ami a kvetkez hibt jelenti: Az rtknek nullval
egyenlnek vagy annl nagyobbnak s a konzol puffermretnl kisebbnek kell lennie az adott dimenziban. A
plda programban a konzol ablak kzepre fog kerlni a kurzor:
int m = Console.WindowHeight;
int sz = Console.WindowWidth;
Console.SetCursorPosition(sz / 2, m / 2);
Math.Abs(double) Mint mr fent emltettem, ez az abszolt rtkt fogja visszaadni egy double tpus
vltoznak.
double x = -20.5;
x = Math.Abs(x); //Megolds: 20.5
Math.Ceiling(double) Azt a legkisebb egsz szmot adja vissza, ami nem kisebb a megadott szmnl.
double x = 12.6;
x = Math.Ceiling(x); //Megolds: 13
Math.Floor(double) Azt a legnagyobb egsz szmot adja vissza, ami nem nagyobb a megadott
szmnl.
double x = 15.3;
x = Math.Floor(x); //Megolds: 15
Math.Max(byte_1, byte_2) A kt megadott byte tpus vltozk kzl vissza adja a legnagyobb
rtkt.
byte sz0 = 10, sz1 = 15;
byte max = Math.Max(sz0, sz1); //Megolds: 15
13
Karsa Zoltn
Math.Min(byte_1, byte_2) A kt megadott byte tpus vltozk kzl vissza adja a legkisebb rtkt.
byte sz0 = 10, sz1 = 15;
byte min = Math.Min(sz0, sz1); //Megolds: 10
Matematikai llandk:
Math.PI a pi konstanst adja vissza Console.WriteLine("A PI rtke: " + Math.PI);
Math.E az e konstanst adja vissza
Randomols
Random r, new, Next()
Sokszor elfordul, hogy egy rtket randomoljunk, magyarul vletlenszeren generljunk egy szmot. Hogy
randomolni tudjunk a System.Random osztlyt kell hasznlnunk s ltre kell hoznunk egy Random objektumot
(mg nem lnyeges, hogy szmunkra mi is ez, csak hasznljuk) nvvel elltva: Random nv = new
Random(); A new opertor egy objektum ltrehozsra szolgl. Ezutn a megadott objektumnv segtsgvel
tudunk majd olyan fggvnyekre hivatkozni, amelyek segtenek neknk a vletlen szm generlsban. Ahogy a
tpusoknl is, itt is az egsz illetve a lebegpontos szmokra bontjuk a hasznland fggvnyeket: Egsz szmok
generlsakor a nv.Next() fggvnyt kell hasznlni (int nagysg), melyet, ha resen hagyunk, akkor egy
tetszleges int szm fog generldni. Ha a zrjelen bell adunk egy intervallumot pldul nv.Next(0, 11),
akkor az els szm mondja meg a minimlis mg generlhat rtket, az utols pedig a mr nem generlhat
rtket, ez esetben 0-t mg generlhat a gp, de 11-et nem, csak maximum 10-et. Hogy megmaradjon ez a
generlt szm troljuk el egy vltozban! A kvetkez plda egy dobkockt fog szemlltetni:
//Random objektum ltrehozsa:
Random r = new Random();
//A generlt szm ltrehozsa s eltrolsa:
int dobott = r.Next(1, 7);
Console.WriteLine("A dobott szm " + dobott);
Console.ReadKey();
Lebegpontos, vals szmok generlsra a nv.NextDouble() fggvnyt kell hasznlni. Itt mr nem adhat
meg hatrrtk alaprtelmezetten 0.0 s 1.0 kz fogja generlni a szmokat, ami azrt baj, mert gy nem
14
Karsa Zoltn
tudunk pl. 0 s 100 kz es vals szmokat generlni. De egy kicsit megpiszklva a szmot tudunk, szorozzuk
meg 100-al a generlt szmot, s gy mr sikerlni fog 0 s 100 kz randomolni. Plda:
Random r = new Random();
double randszam = r.NextDouble() * 100;
Console.WriteLine("Generlt szm: " + randszam);
Console.ReadKey();
Krdsek
1. Milyen egy szmllvezrelt ciklus?
2. Mire hasznlhat a Console.Clear() s a SetCursorPosition()?
3. Mire hasznlhat a Math.Abs s a Sqrt?
4. Mire hasznlhat a break s a continue?
5. Mirt mondja a program, hogy nem ltezik az a vltoz (bra), indok?
6. Csinljuk meg az albbi programnak a folyamatbrjt s struktogramjt: rassuk ki az els 10db 3-mal
oszthat szmot!
Gyakorls
Barkba jtk: Csinljunk egy olyan jtkot, ami 0 s 100 kztt generl egy szmot, majd a felhasznlnak
tippelnie kell, s a program megmondja, hogy a generlt szm kisebb vagy nagyobb a tippelt szmnl.
Random r = new Random();
/*br lehetne int is, de mivel tudjuk, hogy 100-nl nem lesz nagyobb, ezrt byte tpust
alkalmazzunk, gy cskkentve a programunk memria ignyt! A Next fggvny, mivel intet ad vissza
ezrt castolnunk kell.*/
byte randszam = (byte) r.Next(0, 101);
byte tipp = 0;
do {
Console.Write("Tipp: ");
tipp = byte.Parse(Console.ReadLine());
//Bekrjk s talaktjuk a stringet byte-ra, majd utna megvizsgljuk a tipp-et, hogy nagyobb,
kisebb vagy egyenl-e a randomolt szmmal
if (tipp < randszam)
Console.WriteLine("Nagyobb szmra gondoltam!");
else if (tipp > randszam)
Console.WriteLine("Kisebb szmra gondoltam!");
else
Console.WriteLine("Eltalltad!");
} while (tipp != randszam);
//a ciklus addig fog futni, mg a tipp nem lesz egyenl, mint a generlt szm, htul tesztel ciklus
kell.
Console.ReadKey();
15
Karsa Zoltn
Vonal: rajzoljunk a kperny kzepre egy kk cskot az ablak fejlcvel merlegesen!
Console.BackgroundColor = ConsoleColor.Blue;
for (int i = 0; i < Console.WindowHeight - 1; i++)
{
Console.SetCursorPosition(Console.WindowWidth / 2, i);
Console.Write(" ");
}
Console.ReadKey();
A tmbk is adatok trolsra alkalmas, viszont a sima adatszerkezetekkel ellenttben ez mr egy sszetett
adatszerkezet, ami kpes egy bizonyos vltoznv alatt tbb elemet is trolni egy index segtsgvel. Kpzeljnk
el egy szekrnyt, aminek a neve ruhk. A szekrny fikjai pedig meg vannak szmozva, s minden szmhoz
tartozik egy ruhanem, pldul az 1-es fikban vannak a zoknik, a 2-esben a nadrgok, a 3-asban a plk C#-
ban gy lehetne valahogy ltrehozni ezt a ruhs szekrnyt:
string[] szekreny = new string[] { "zokni", "nadrg", "pl", "pulcsi", "sapka" };
Ha a tmbnek nem adunk rtket alaprtelmezetten 0-val fog feltltdni szm tpusok esetben, egyb
tpusoknl a null rtket kapja. A tmbk indexelse 0-tl kezddik, a 0. elem az els, az 1. elem a msodik,
ezrt az utols elemet mindig az eltrolhat elemek n-1 indexe mutatja meg. Tmbket tbbfle mdon is ltre
lehet hozni:
//megadjuk a tmb mrett, ez esetben 10db string trolhat el (vektor)
string[] pelda1 = new string[10];
/*megadjuk felsorolsban az elemeket egy kapcsos zrjelben, ez esetben a kapcsos zrjelen belli
elemek mennyisge hatrozza meg a tmb mrett, teht 5db int tpus trolhat el ebben a tmben:*/
int[] palda2 = new int[] { 5, 31, 78, 124, 4048};
Ha a tmb egy dimenzis (egy indexe van) vektornak, ha 2, akkor mr mtrixnak nevezzk.
Valahogyan gy lehetne elkpzelni egy vektort s egy kt dimenzis mtrixot:
Vektor C#-ban a tmbk tudjk a mretket, gy azt le lehet krni,
Index 0 1 2 3 4 5 vektor esetben a tmbnv.Length-el. Mtrixok esetn a
Adat 342 43 45 12 422 52 mtrixnv.GetLength(dimenzi szma)-val lehet
lekrdezni a mrett.
A mr deklarlt tmb mrett mr nem tudjuk Mtrix
befolysolni, ha olyan indexre mutatunk, ami kvl esik a Index 0 1 2 3 4 5
0 32 32 45 1 22 5
tmb mretn akkor System.IndexOutOfRangeException
1 324 5 3 5 35 64
kvtelt kapunk, azaz az index a tmb hatrain kvlre
2 43 5234 423 45 234 876
mutatott. Pl.: Van egy 10 egysg mret tmbnk s mi 3 42 23 34 234 4 2
leakarjuk krni a tmb 10. elemt (tmbnv[10]), akkor 4 5467 64 567 354 13 56
ilyen kivtelt kapunk, mert ez a tmb 0-9-ig indexelhet, 5 86 34 67 52 76 432
hiszen a 0 is index, ezrt lesz az utols mg j indexnk a
10-1 (0 miatt) a 9. A tmbket legegyszerbben for-ciklussal tudjuk bejrni, a for-ciklus fejlce ltalnosan az
albbi alak: for (int i = 0; i < tmbnv.Length; i++) gy biztos, hogy nem akad ki a programunk. A for-
ciklus rsra s olvassra is feltudjuk hasznlni, viszont van a tmbkhz ksztett foreach-ciklus, ami vgig jrja
a tmbt s mindig az aktulis elemet belerakja egy ideiglenes (pl.: item) vltozba, ez viszont csak olvassra j,
16
Karsa Zoltn
gy elemeket nem tudunk vltoztatni vele. ltalnos alakja: foreach (tpus vltoznv in tmbnv). A
kvetkez kdban feltltnk egy tmbt randomolt szmokkal s kiratjuk ezutn egy foreach-ciklussal.
int[] randomoltszamok_Vektor = new int[10];
Random r = new Random();
for (int i = 0; i < randomoltszamok_Vektor.Length; i++) {
//for ciklusssal rni s olvasni is tudunk
randomoltszamok_Vektor[i] = r.Next(0, 100);
} foreach (int item in randomoltszamok_Vektor) {
//csak olvassra j
Console.WriteLine(item);
}
Console.ReadKey();
Bvebben a mtrixrl: a mtrix egy olyan ktdimenzis tmb melynek van szlessge s magassga is, mg a
vektor csak 1 magas volt s brmekkora szles addig ez mr legegyszerbben egy tblzatknt foghat fel,
hasznlata majdnem ugyan az, mint a vektornl csak itt mr kt indexet kell megadnunk, hogy elrjnk egy
cellt. Deklarlsa hasonl, mint a vektorok esetben, csak egy vesszt kell beszrnunk a ngyzetes zrjelek
kz. Pl.: int[,] mtrix = new int[4, 5]; Ilyenkor egy olyan int tpus mtrix jn ltre, melynek szlessge
4 cella, magassga pedig 5. Mint mr mondtam a tbb dimenzis tmbk esetben a
tmbnv.GetLength(dimenzi szm) tudjuk lekrni az aktulis dimenzi mrett, a dimenzik szmozsa is 0-
tl kezddik s a megadott dimenzikig tart. Szintn tudunk kapcsos zrjelekkel ltrehozni egy mr 0-tl eltr
adatokat tartalmaz tmbt, ilyenkor szintn nem kell megadnunk a tmb mrett. Pl.:
int[,] mtrix = new int[,] {
{ 421, 23, 42, 1 },
{ 45, 674, 341, 52 },
{ 56, 12, 343, 54 }
};
Console.WriteLine("Magassga: " + mtrix.GetLength(0)); //3
Console.WriteLine("Szlessge: " + mtrix.GetLength(1)); //4
Ha ilyen mdon adunk meg tmbket, akkor az egyes sorokban lv elemek szmnak meg kell egyeznie, ne
felejtsk el a zrjelek utn vesszt tenni s a fzrjel utn egy pontosvesszt! Mtrixok krbejrsra 2 db
for-ciklus kell, ltalnos alakja:
//Mtrix feltltse randomolt szmokkal !!-a mtrix nev tmbt mr ltrehoztuk-!!
Random r = new Random();
for (int i = 0; i < mtrix.GetLength(0); i++) {
for (int j = 0; j < mtrix.GetLength(1); j++) {
mtrix[i, j] = r.Next();
}
}
A mtrix elkpzelhet egy olyan vektorknt melynek celliban jabb vektorok vannak, viszont ezek a
vektoroknak meg kell egyeznik a tbbi cellban lv vektorok mretvel, ezek a tmbket szablyos
tmbknek, ngyzetes mtrixoknak, multidimenzis tmbknek nevezzk. Lteznek olyan tbbdimenzis
tmbk, melyeknek a mutat vektoron (f vektor) bell lv vektorok mrete nem azonos, ezek a
mutatvektorok. Plda mutatvektorok ltrehozsra:
int[][] mutatovektor = new int[][] {
new int[] { 6, 2, 2, 7, 3 },
new int[] { 3, 1 },
new int[] { 12, 31, 56 } };
Console.WriteLine("For-ciklussal:"); //vgigjrsa for-ciklussal, olvassra s rsra
for (int i = 0; i < mutatovektor.Length; i++) {
for (int j = 0; j < mutatovektor[i].Length; j++) {
Console.Write(mutatovektor[i][j] + ", ");
}
Console.WriteLine();
}
Konstans: ltrehozhatunk c# nyelvben olyan vltozkat melyeknek az rtke lland, teht biztos, hogy nem
fog vltozni, gy a program csak a vltoz rtkt foglalja le a memriban. Ltrehozhatunk konstans tmbt is
(pl.: a magyar abc-t tartalmaz betkszlet tmbt), ltalnos ltrehozsi alakja, amit ltalban a deklarlskor
kell megadnunk: const vltoztpus vltoznv = rtk; Pl.:
//Br van a Pi-re fggvny, hasznlhatunk egy lland, konstans vltozt is erre, hiszen tudjuk,
hogy a pi rtke nem fog vltozni
const double pi = 3.14159265359;
//erre hibt kapunk:
pi = 5;
A string egy olyan char tmb, ami a tbbi tmbbel ellenttben a mrete vltoztathat, egy string gy nzne ki
tmb formjban:
string alma = "alma"; //egyenl ezzel:
char[] almaT = new char[] {'a', 'l', 'm', 'a'};
Ugyan gy, mint a tmbket a string-eknl is a cellk (ez esetben karakterek) tartalmt az indexk segtsgvel
tudjuk elrni, gy pldul az alma[1] az l karakter, ugyan gy lekrdezhet a hossza is a string.Length -el.
Csinljunk egy olyan programot, ami bekr a felhasznltl egy karakterlncot, majd megmondja, hogy hny db
szkz van az adott string-ben.
Console.WriteLine("Adja meg a karakterlncot: ");
string str = Console.ReadLine(); //mivel tudjuk, hogy a szamlalo sohasem lesz negatv, ezrt
lltsuk uint-re a tpust s 0 kezdrtkkel:
uint szamlalo = 0; for (int i = 0; i < str.Length; i++) {
if (str[i] == ' ') szamlalo++;
}
Console.WriteLine("Szkzk szma: " + szamlalo);
Console.ReadKey();
String metdusok:
string.Substring(honnantl, hny darabot) Kimsol az eredeti stringbl az els
paramterl kapott indextl a 2. paramtert jelent hosszsgig, a kapott index is mr msolva lesz.
string str = "Szoftverfejleszts";
string str2 = str.Substring(8, 3); //fej
18
Karsa Zoltn
string.Replace(rgi string, j string) A kapott string-ben a megadott stringet, ha van,
lecserli a 2. paramterre. Pl.:
string str = "Rges rg vrva vrt";
string str2 = str.Replace("vr", "rt"); //Rges rg rtva rtt
engem
string.ToUpper()/ToLower Az adott stringet nagybetss/kisbetss alaktja. Pl.:
string str = "kisbet";
string str2 = str.ToUpper(); //KISBET
string.Insert(hova , mit)A megadott helytl beszr egy stringet, s a kiegsztett stringet adja vissza
Escape karakterek:
Escape karakterek, olyan vezrlkarakterek, amelyek a console ablakban
megjelen karakterek kimeneti mdjt hatrozza meg. Minden vezrl
karakter egy \ jellel kezddik. \a alert hang
Hasznlata: Console.WriteLine("Tabultor:\t Hell"); Ha \b trls, backspace
\n j sorba ugrik a kurzor
a karakterlnc el egy @jelet tesznk, akkor a karakterlnc
\r vissza ugrik egyet a kurzor
sz szerinti stringknt rtelmezdik, gy az escape
\t tabultor vzszintesen
karakterek gy lesznek kirva, ahogy vannak.
\v tabultor fgglegesen
\ karakter illeszt be
\ karaktert illeszt be
Kirats + nlkl \\ \ karakter illeszt be
Nehz mr + segtsgvel sok vltozt kiratni, fleg akkor,
ha terjedelmes szvegbe kellene beleszrni, erre talltk ki a {index} formtumot ami megknnyti a kiratst. A
string utn egy vesszt tesznk, s ide rjuk a vltozkat vesszvel elvlasztva, balrl jobbra haladva, az itt lv
19
Karsa Zoltn
vltozk beleszrdnak az indexknek megfelelen a {index} helyre, szintn 0-tl szmozzuk az indexet n-1-ig,
hasonlt egy vektorra, vannak formtumkdok is, de azt ksbb vesszk. Pl.:
Console.Write("{0}db pozitv szm, legnagyobb a {1}, legkisebb a {2}", db, legnagyobb, legkisebb);
Vektorok
1. Krjnk be a felhasznltl 20db -100 s +100 kz es szmot, s troljuk el ezeket egy vektorban,
szmoljuk meg mennyi oszthat 3-mal, melyik a legkisebb, illetve a legnagyobb s hatrozzuk meg a szmok
tlagt! A megolds lerssal letlthet a honlaprl a programozs fl alatt: karsazoltan.ddns.net
2. Csinljunk 3 darab 365 mret vektort, az egyikbe randomoltassunk 4000 s 12000 kztt lv szmokat, ez
a tmb lesz egy zlet napi bevtele, a msikba randomoltassunk 2000 s 4000 kztt szmokat ez lesz a kiads
a 3. tmbbe szmtsuk ki az egyes napokra es tiszta hasznot (bevtel - kiads), hatrozzuk meg mennyi volt a
legjobb nap!
3. Csinljunk egy bool tpus 60 elem vektrort, amibe egy pnzrme dobs eredmnyt fogjuk eltrolni (fej-
true, rs-false jelenti), randomoljunk 0 vagy 1-et, ha a random 0, akkor false rjunk a tmbbe, ha 1, akkor true-
t. Jelentsk meg a kapott eredmnyt a kpen lthat mdon
(fej-fehr, rs-piros), valamint rjuk ki, hogy hny %-ban volt
fej s hny % rs!
4. lltsuk el egy 50 elem int tpus vektorba az els 40 Fibonacci szmot (egy olyan sorozat, melynek az els
kt eleme a 0 s az 1, az azt kvet szmok az elz 2 szm sszege). rassuk ki egy foreach ciklussal az gy
kapott vektor elemeit! Ha megvagy, milyen szemantikai hiba lpett fel a programban, mi az oka?
Mtrixok
1. Hozzunk ltre egy olyan tmbt, melybe hmrskletet fogjuk lekrdezni minden rban 30 napig keresztl,
hasznljunk egy 30*24-es mtrixot, randomoljunk bele -5 s +15 kztt rtkeket, ezutn hatrozzuk meg
melyik rban volt az egszhnapot nzve a leghvsebb, s a legmelegebb tlaghmrsklet, valamint melyik
napon volt a legmagasabb tlaghmrsklet a 30 napban.
2. Csinljunk egy 30*20 logikai mtrixot melybe egy sznhz foglalt illetve szabad helyeit fogjuk brzolni (true-
szabad, false-foglalt). Randomoljunk bele true vagy false rtkeket! Krjk be a felhasznltl hny db szket
szeretne lefoglalni egyms mellett, ha van ilyen, akkor rassuk ki a sor s az ls szmot, ha nincs, rjuk ki, hogy
nem tallhat ennyi res szk egyms mellett.
TryParse hasznlata
TryParse, out, kimeneti vltoz
Parse hasznlatval eddig, abban az esetben, ha egy bet kerlt a szmunk kz, kifagyott, teht
System.FormatException kivtel addott, ennek elkerlse rdekben a TryParse talakt fggvnyt kell
hasznlnunk, fontos megjegyezni azt, hogy ugyangy, mint a Parse a TryParse is csak stringbl kpes egy
bizonyos formtumba konvertlni, ms bemenet nem adhat meg neki! A TryParse bool, logikai tpust ad vissza,
ltalnos alakja:
tpus.TryParse(talaktand string, out a tpusnak megfelel kimeneti vltoz);
Ebben az esetben egy int tpus vltozba (szam) szeretnnk eltrolni a Console.ReadLine()-al bekrt stringet,
az out sz utn lv vltozba fog eltroldni sikeres parsols (konvertls) esetn a bekrt string. A logikai
vltozba (tryparse) fog eltroldni egy olyan logikai rtk, amely a sikeres vagy sikertelen konvertlsra utal,
true esetn sikerlt a konvertls, teht bele rakta a kimeneti vltozba az talaktott stringet, a false esetn
viszont nem sikerlt talaktani. Termszetesen hasznlhat ms tpusok talaktsra is, mint pldul a long,
ulong, short, byte
20
Karsa Zoltn
int szam = 0;
bool tryparse = int.TryParse(Console.ReadLine(), out szam);
if (tryparse) Console.WriteLine(szam);
else Console.WriteLine("Rossz bemenet, hiba!");
Console.ReadKey();
Ha egy ilyen megoldst csinlunk, akkor mr nem fagy ki a programunk, de a felhasznlnak jra el kellene
indtani a programot, hogy jra megtudjon adni rtkeket. Ezrt a TryParse-t foglaljuk egy do-while ciklusba, s
abban az esetben fusson le jra a ciklus, ha nem sikerlt a konvertls, teht nem kerlt semmise a kimeneti
vltozba, ergo a TryParse ltal visszaadott logikai rtk false, ezrt kell mg egy felkilt jelet odaszrni el a
ciklus felttelben.
El ne felejtsk az eltroland szm vltozjt a ciklusmagon kvl deklarlni, mivel a ciklusmagon bell
ltrehozott vltoz nem ltszik a ciklusmagon kvl!
long szam = 0;
do {
Console.Write("Adja meg a szmot: ");
} while (!long.TryParse(Console.ReadLine(), out szam));
Console.WriteLine(szam);
Console.ReadKey();
Billentyzet kezels
Console.ReadLine, Read, ReadKey, ConsoleKeyInfo
Mint mr megtanultuk a Console.ReadLine() egy karakterlncot olvas be a bemenetrl enter lenyoms utn,
pedig visszaadja ezt a stringet. Ha nem adunk meg karaktereket, res mez utn nyomjuk le az entert, akkor
null rtket ad vissza. Ellenben a ReadLine a sima Read() egy darab karaktert olvas be enter lenyoms utn s a
bevitt karakter ASCII kdjt adja vissza egy int tpusban, ha ezt a szmot karakterr parsoljuk visszakapjuk a
bekrt karaktert.
int ascii = Console.Read();
Console.WriteLine("Bekrt bet " + (char)ascii + " - ascii kdja: " + ascii);
Plda: Be: r
Ki: Bekrt bet r - ascii kdja: 114
A Console.ReadKey() egy billentyt olvas be a bemenetrl s nem vr enter lenyomsra. ConsoleKeyInfo tpus
struktrt (majd ksbb lesz rla sz) ad vissza, amelyben el van trolva az adott karakter unicode-ja, valamint
a mdost billentyk (Ctrl, Alt ) aktivitst is, kpes eltrolni specilis karaktereket is (escape, lefele nyl ).
Ha megadunk egy true rtket paramternek, akkor nem fog megjelenni a lettt billenty karaktere. A
.KeyChar-ral elrhetjk a megadott karaktert, char tpust ad vissza.
ConsoleKeyInfo cki = Console.ReadKey();
Console.WriteLine(cki.KeyChar);
21
Karsa Zoltn
Billentyzet puffer: amikor lenyomunk egy billentyt a lenyomott billenty bekerl egy puffer-ba. A
Console.ReadKey() metdus ebbl a pufferbl vesz ki mindig egy rtket, ha a puffer-ben mg tallhat
billenty, akkor a Console.KeyAvailable true-t ad vissza, ellenkez esetben false-t. Jelsz bevitel plda:
ConsoleKeyInfo cki;
string jelszo = "";
do
{
cki = Console.ReadKey(true);
if (cki.Key != ConsoleKey.Enter)
{
Console.Write("x");
jelszo += cki.KeyChar;
}
} while (cki.Key != ConsoleKey.Enter);
if (jelszo == "1234") Console.WriteLine("\nJ jelsz");
else Console.WriteLine("\nHelytelen jelsz");
Alprogramok
Eljrsok, fggvnyek, paramtertadsi mdok
A programok felptse alapveten szekvencilis , a fprogram a Main a programunk belpsi pontja, innen
kezddik a futs, az itt meghvott fggvnyek hajtdnak vgre. Az alprogramok a programkd lervidtsre s
tlthatsgra szolgl, minden egyes sajt eljrsnak vagy fggvnynek meg van a maga szerepe s a
szerepre utal neve, gy ha valamilyen javtand problma lenne a programunkban, akkor knnyen nyomon
kvethet a program felptse s jobban korriglhat. Az alprogramok ltalnos alakja:
static tpus Nv(paramter1, p2,..){utasts1; utasts2 (ha fggvny return valami;)} 2 f alprogram tpust
klnbztetnk meg, minden alprogram a static kulcsszval kezddik, ennek lnyegrl majd sz esik az
objektum orientlt programozs rsznl, a paramterezsrl majd ksbb bvebben:
1. Eljrsok: nincs visszatrsi rtke, ezrt void (res) tpus
static void Main(string[] args){
Kiir(); //Meghvs
}
static void Kiir() { //Maga az alprogram
Console.WriteLine("dvzllek a programban! ");
} //visszatrs
2. Fggvnyek: van visszatrsi rtke, a visszaadott rtktl fgg, a return utastssal adjuk meg a
visszaadott rtket, ami minden esetben ktelez a megadsa.
static void Main(string[] args){
int i = Osszeg(); //Meghvs
//az i tartalma mr 12
}
static int Osszeg(){
return 5 + 7;
} // visszatrs int 12-vel
Miutn meghvtunk egy eljrst s az lefut, visszatr a meghvs helyre, a fggvnyeknl a return utastst
kveten tr vissza a fggvny a meghvs helyre. A return utasts utn lv parancsok nem futnak le,
pldul az albbi fggvny 5 rtket ad vissza, hiba futna tovbb a for-ciklus s lenne mg egy return utasts:
static void Main(string[] args){
//Meghvs
int i = Plda();
}
static int Plda(){
for (int i = 0; i < 10; i++) {
if (i == 5) return i;
}
return 0;
}
22
Karsa Zoltn
Az alprogramok egymst is meghvhatjk, egy metdus meghvhat ms fggvnyeket, eljrsokat, st akr
nmagukat is meghvhatjk (rekurzi), viszont ilyenkor le kell kezelni azt is, hogy ne hvja meg magt mindig az
alprogram, klnben System.StackOverflowException kivtel dobdik.
Az alprogramok paramterezse:
A metdus deklarlsnl megadott paramtereket formlis, a metdus meghvsakor megadott
paramtereket pedig aktulis paramternek hvjuk. Az eljrsokat s fggvnyeket 3-fle mdon
paramterezhetjk: rtk, cm s egy u. kimeneti paramterknt, a paramtereket vesszvel vlasztjuk el
egymstl, ha rtket is adunk az alprogramunk fejlcben a paramtereknek, akkor a meghvskor nem lesz
ktelez megadni az adott paramtert.
static void Main(string[] args){
Udvozlet(); //nzzk meg mi lesz a kimenet ez s
Udvozlet("Hell!"); //ez esetn
}
static void Udvozlet(string s = "Kszntelek a programban!"){ Console.WriteLine(s); }
1. rtk sz. paramtertads: Ha nem adunk meg semmilyen kulcsszt, akkor ilyen mdon addnak t a
vltozk (kivve tmbk, objektumok... ). Ilyenkor az alprogram meghvsakor megadott aktulis
paramterek rtke tmsoldik az alprogram egy-egy megfelel formlis paramterbe, ezutn a
formlis paramtert ugyangy hasznlhatjuk, mintha egy vltoz lenne.
static void Main(string[] args){
int a = 6, b = 4, c;
c = KtszerestsszeadFggvny(a, b);
Console.WriteLine("\'a\' rtke:{0}\n\'b\' rtke:{1}\n\'c\' rtke:{2}", a, b, c);
//a: 6, b: 4, c: 20
Console.ReadKey();
}
static int KtszerestsszeadFggvny(int szam1, int szam2) {
szam1 = szam1 * 2; szam2 = szam2 * 2;
return szam1 + szam2;
}
2. Cm (Referencia) sz. paramtertads: A ref kulcsszval rhet el a cm sz. p., a ref kulcsszt az aktulis
s a formlis paramter eltt is kell hasznlni! Ebben az esetben az tadott aktulis paramterre,
vltozra egy hivatkozs jn ltre a memria tartomnyra, csak a memriaterlet cme/azonostja
addik t, gy az alprogramon bell vgzett vltoztatsok rvnybe lpnek az tadott vltozban is!
Fontos: az sszetett adatszerkezetek, tmbk, objektumok () minden esetben referencia, teht cm
szerint addnak t!
static void Main(string[] args){
int a = 6, b = 4, c;
c = KtszerestsszeadFggvny(ref a, ref b);
Console.WriteLine("\'a\' rtke:{0}\n\'b\' rtke:{1}\n\'c\' rtke:{2}", a, b, c);
//a: 12, b: 8, c: 20 itt mr megvltozik az tadott vltoz rtke!!!!
Console.ReadKey();
}
static int KtszerestsszeadFggvny(ref int szam1, ref int szam2) {
szam1 = szam1 * 2; szam2 = szam2 * 2;
return szam1 + szam2;
}
3. Kimeneti vltoz: Az out kulcsszval rhet el ez a paramter tadsi md, szintn a meghvskor s az
alprogram deklarlsakor is meg kell adni! Hasonlt a cm sz. p. -ra viszont az tadott paramternek
kezdetben nincs rtke a fggvnynk hvatott ennek rtket adni, de ktelez az rtkads!
static void Main(string[] args){
bool paros;
Paros(10, out paros);
}
static void Paros(int a, out bool log)
{
if (a % 2 == 0) log = true;
else log = false;
}
23
Karsa Zoltn
A kvetkez feladatban egy ellenrztt bekrs fggvnyt csinlunk, aminek ktelezen meg kell adni egy
zenetet, valamint lehetsge addik a fggvny meghvjnak arra, hogy megadhatja azt, hogy mely szmok
kztt fogadjon el rtkeket a fggvny, a fggvny visszaadja a felttelnek megfelel bekrt szmot.
static int EllBekerf(string bekeresuzi, int mettol = int.MinValue, int meddig = int.MaxValue) {
int szam;
do {
Console.WriteLine(bekeresuzi);
} while (!int.TryParse(Console.ReadLine(), out szam) || !(szam > mettol && szam < meddig));
return szam;
}
A kvetkezben nzznk egy olyan fggvnyt, ami sszegzi egy tmb tartalmt:
static int Oszegzo(int[] tomb){
int ossz = 0;
foreach (int item in tomb){
ossz += item;
}
return ossz;
}
Csinljunk egy olyan fggvnyt, ami egy tetszleges int tmbt tlt fel vletlen rtkekkel a megadott
rtkeken bell, mivel a tmbk minden esetben referencia, teht cm szerint addnak t ezrt nem kell a ref
kulcssz, br oda lehet tenni:
static void RandTomb(int[] tomb, int mettol, int meddig){
for (int i = 0; i < tomb.Length; i++){
tomb[i] = r.Next(mettol, meddig);
}
}
A kvetkezben csinljunk egy fggvnyt erre a mdszerre, ami vissza ad egy int tmbt a megadott rtkeken
bell, randomolt szmokkal, a tmb mrett is paramterknt krjk:
static Random r = new Random();
static int[] RandT(int Tmret, int mettol, int meddig){
int[] visszaT = new int[Tmret];
for (int i = 0; i < visszaT.Length; i++){
visszaT[i] = r.Next(mettol, meddig);
}
return visszaT;
}
Csinljunk egy olyan fggvnyt, ami kirja egy tmb legkisebb elemt:
static void Min(int[] tomb){
int legk = tomb[0];
foreach (int item in tomb){
if (item < legk) legk = item;
}
Console.WriteLine(legk);
}
Ha viszont ezt a fggvnyt lebegpontos szmokra hvjuk meg, akkor a fordt szintaktikai hibt jelez, mit kell
akkor csinlnunk, mg egy fggvnyt rni, melynek neve klnbzik az elztl? Pldul egy sszeadInt s egy
24
Karsa Zoltn
sszeadDouble nev fggvny? A vlasz nem. Lehet azonos nv alatt klnbz szignatrj (ms az tadott
tpus, valamint a visszaadott rtk) fggvnyeket, eljrsokat ltrehozni. Teht ha szeretnnk csinlni, olyan
azonos nev fggvnyeket, amelyek kpesek az int+int-re, a double+double-re, az int+double-re, valamint a
double+int-re visszaadni a kt paramter sszegt, akkor elg 4db azonos nev, de eltr szignatrj
fggvnyt csinlni, ezt nevezzk tlterhelsnek (overloads), pldul a Console.WriteLine() -nak 19 db
tlterhelse van. A felknlkoz tlterhelsek kztt a le-fel nyilakkal vltogathatunk
Lehet egy metdusban is kivltani a fenti metdusokat (sszetudjunk adni int-et is, meg double-t is) de azt itt
nem trgyalom!
25
Karsa Zoltn
Rekurzi: Az olyan mveletet, melynek vgrehajtsakor a sajt mveletsorait hajtja vgre, teht nmagt
ismtli, rekurzinak nevezzk. Programozs esetn a fggvnyek sajt magukat hvjk meg. Amikor egy
fggvny nem nmagt, hanem egy msik fggvnyt hv meg, majd ez a fggvny pedig meghvja azt a
fggvnyt, amibl meghvtk (), akkor azt klcsns rekurzinak nevezzk (pl. A() meghvja B()-t, majd B()
meghvja A()-t). Figyelem: A rekurzi nagyon erforrs ignyes, hiszen akr tbb szzszor is ltrejnnek a
fggvny vltozi s ezzel memrit foglalnak el.
static ulong Faktorialis(ulong n){
if (n <= 1) return n;
return n * Faktorialis(n - 1);
}
static void Main(string[] args){
Console.WriteLine(Faktorialis(3));
}
26
Karsa Zoltn
A felsorols tpus - Enum
enum, Enum.TryParse, enum castols
A felsorols egy olyan adatszerkezet, amelyben egy meghatrozott konstans (nem vltozhat) rtkek
adategysgt jelenti. Enum tpust csak eljrsokon kvl, de mg osztlyon bell szabad csak deklarlni,
klnben szintaktikai hibt kapunk. ltalnos alakja:
enum llatok {Kutya, Tigris, Zsirf, Oroszln }
A felsorols elemeihez alaprtelmezetten egy index trsul 0-n szmozssal, ezt arra tudjuk hasznlni, hogy az
egyes szmoknak megfeleltessnk egy-egy llatok felsorols egy tagjt, ebben az esetben a 0-Kutya, 1-Tigris
Ugyangy a szmokat is ttudjuk alaktani a megfelel felsorols rtkre. Ha nem megfelel rtket adtunk meg,
akkor nem keletkezik kivtel. Plda:
Console.WriteLine("Az 1-esnek megfelelel a(z): {0}", (llatok)1);
Console.WriteLine("A(z) {0} -nak megfelel szm a(z) {1}", llatok.Oroszln, (int)llatok.Oroszln);
Megadhatjuk akr mi is a felsorols elemeinek rtkt, ha az els elem rtkt adjuk meg, akkor a rkvetkezk
mindig az elz +1 lesz, klnben az sszes elemnek adnunk kell egy rtket.
enum Jegyek {Elgtelen = 1, Elgsges, Kzepes, J, Kivl}
static void Main(string[] args)
{
Console.WriteLine((Jegyek)2);
Console.ReadKey();
}
Enum.GetValues/GetNames
Az Enum.GetValues egy tmbt ad vissza, melyben a megadott felsorols elemei szerepelnek, ezt a tmbt t
kell alaktanunk a magadott felsorols tmbre (Felsorols[]), a GetNames is ugyan ez az elven mkdik csak
string tmbt ad vissza. Az Enum.GetName egy karakterlncot ad vissza a megadott felsorolsban.
RgiSlymrtkek[] rsmT = (RgiSlymrtkek[])Enum.GetValues(typeof(RgiSlymrtkek));
foreach (RgiSlymrtkek item in rsmT){
Console.WriteLine(item);
}
string[] rsmTstr = Enum.GetNames(typeof(RgiSlymrtkek));
foreach (string item in rsmTstr){
Console.WriteLine(item);
}
string str = Enum.GetName(typeof(RgiSlymrtkek), 500);
Console.WriteLine(str);
Taln most mr mindenki rjtt, hogy a c#-ban vannak beptett felsorols tpusok, ilyen pldul a ConsoleColor
s a ConsoleKey. Ahogy az elbb is ezekbl a felsorolsokbl is kszthetnk tmbt. Csinljunk egy olyan
programot, ami vltogatja a httr sznt folyamatosan!
ConsoleColor[] consolecolors = (ConsoleColor[])Enum.GetValues(typeof(ConsoleColor));
int i = 0;
while (true)
{
Console.BackgroundColor = consolecolors[i];
Console.Clear();
if (i++ == consolecolors.Length - 1) i = 0;
}
27
Karsa Zoltn
Enum.TryParse() Kpes egy karakterlncbl adott felsorols tpusra talaktani, ha sikerl a konverzi true, ha
nem akkor false rtkkel tr vissza.
enum Sznek {piros, narancs, zld, kk, barna, szrke, fekete, fehr};
static void Main(string[] args){
Sznek szn;
if(Enum.TryParse(Console.ReadLine(), out szn))Console.WriteLine("Sikeres konvertls " + szn);
else Console.WriteLine("Sikertelen konvertls");
Console.ReadKey();
}
Hibakezels
try, throw, catch, Exceptions
Abban az esetben eddig, ha egy nem kezelt kivtel (Exception) keletkezett be, akkor kifagyott a programunk s
a hibt vagy a visual studio, vagy az opercis rendszer kezelte le, s egy hibazenetet dobott. A programunk,
ekkor kifagyott. Pldul a string int-re val parsolsnl, ha nem egsz szmot adtunk meg, vagy karaktereket is
megadtunk a string literlba, akkor FormatException hiba addott, br a TryParse erre megoldst ad, de nem
minden kivtelnek van egy-egy megfelel, a hibt kezelni kpes fggvnye. C#-ban a kivtel egy objektum, amit
akkor indt tjra egy fggvny, ha valamilyen hiba trtnt, ekkor a programunk hibakezels nlkl elszll. A
kivtelek elkapst s lekezelst a try-catch blokk vgzi, a try blokkot vdett blokknak nevezik, itt keletkezhet
a kivtel, melyet majd a catch blokk fog majd lekezelni, a catch-nak meg kell adni egy kivtel objektumot, ami
utal a hiba tpusra, egy try-blokk utn tbb catch-blokk is kvetkezhet, hiszen rdemes a klnbz
kivtelekre, klnbz mdon reaglni, nem csak azt kirni, hogy Hiba! Amint egy kivtel keletkezik a try
blokkban az utna kvetkez utastsok nem hajtdnak vgre! Nzznk egy pldt: Krjnk be egy int szmot,
s kezeljk le az esetleges FormatException-t, mivel a try is egy blokk, el ne felejtsk a bekrt vltozt mr
deklarlni a try eltt, klnben nem tudjuk ksbb hasznlni!
int a = 0;
try{
a = int.Parse(Console.ReadLine());
}
catch (FormatException){
Console.WriteLine("Hiba - Nem sikerlt talaktani a bevitt karakterlncot!");
}
Console.WriteLine(a);
Minden kivtel se (eredete) az Exception osztly, ha ezt lltjuk be a catch blokkba, akkor brmilyen kivtel is
dobdik, minden hiba lekezelsre kerl. A kivtelek csaldfja:
28
Karsa Zoltn
Pldul az IndexOutofRangeException kivtel se a SystemException, gy egy catch(SystemException){ } blokkal
elkaphatjuk ezt a kivtelt is.
Ha jobban tgondoljuk nem kezeltk le az OverFlowException (tlcsorduls) kivtelt, ha megadunk egy nevet a
kivtel objektumunknak, akkor az objektum tartalma lekrhet a nv.Message metdussal. Csinljuk meg akkor
a kiegsztett programot, biztostsknt csinljunk mg egy sima Exception gat.
int a = 0;
try{
a = int.Parse(Console.ReadLine());
}
catch (FormatException){
Console.WriteLine("Hiba - Nem sikerlt talaktani a bevitt karakterlncot!");
}
catch (OverflowException ofe){
Console.WriteLine(ofe.Message);
}
catch (Exception e){
Console.WriteLine("Ismeretlen hiba: " + e.Message);
}
Dobhatunk akr sajt magunk is egy kivtelt, ezzel tudunk reaglni arra az esetekre is, amikor eredetileg nem
keletkezne kivtel, de a ksbbiek folyamn fontos lenne. Kivtelt a throw-val tudunk dobni. Pldul amikor a
felhasznltl egy karakterlncot krnnk be, de csak res stringet kapunk, ezt az res karakterlncot nem
tudjuk mire felhasznlni, ezrt egy sajt kivtelt dobunk, vagy bekrjk a felhasznl keresztnevt, de megad
szmokat is... Ugyangy, mint a rendszerszint kivteleknl is a throw esetn is a rkvetkez utastsok nem
hajtdnak vgre s a megfelel catch gra ugrik a vezrls. Termszetesen, ha azt szeretnnk, hogy a kivtel
utn jra megtudja adni a felhasznl a szveget, akkor kell egy logikai vltoz valamint egy do-while ciklus.
Kivtel dobs ltalnos alakja: throw new Kivtelneve(hiba zenet).
bool hiba = true;
do{
string s = "";
try {
Console.Write("Krem a szveget: ");
s = Console.ReadLine();
if (s.Length == 0) throw new Exception("Nem adott meg szveget");
hiba = false; //ide csak akkor jut el a vezrls, ha nem lesz kivtel
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
} while (hiba);
Finally blokk: a finally blokkot minden esetben az utols blokk-knt kell hasznlni, az itt megadott utastsok
minden esetben lefutnak, ha keletkezett kivtel, ha nem! Plda:
try {
int a = 10;
int b = 0;
Console.WriteLine(a / b);
}
catch (DivideByZeroException) { Console.WriteLine("Nullval osztott!"); }
finally{ //ez az g mindenkppen lefut!
Console.WriteLine("Vge");
}
Feladat: Csinljunk egy ellenrztt bekrs fggvnyt (TryParse nlkl) kezeljk le az esetleges kivteleket:
FormatException, OverflowException majd ezt a fggvny ltal visszaadott szmnak vegyk a ngyzetgykt
(Math.Sqrt) vigyzzunk, mert negatv szmnak nincs ngyzetgyke gy dobjunk sajt kivtelt a
NotFiniteNumberException kivtellel s kezeljk le!
29
Karsa Zoltn
Generikusok
lista, lncolt lista, sztr, verem, sor, halmaz
A generikusokat (using) System.Collections.Generic nvtrben tallhatjuk, el ne felejtsk beemelni! Kell a new kulcssz,
referencia tpusok! A flslegess vlt generikus vltozk felszabadtst a szemtgyjt (Garbage Collector) vgzi.
rtktadskor referencia msols trtnik, lsd: Listk- 31. o.
Remlem, mg emlksznk a tmbkre! Most a lista ismertetse utn teljesen elfeledhetjk ezeket (de azrt
emlkezznk r) a buta adatszerkezetet, a tmbnek az volt a legnagyobb htrnya, hogy kttt volt a mrete,
miutn ltrehoztunk egy tmbt s megadtunk neki egy mretet, akkor a mretnl tbb elemet nem
trolhattunk el benne, hiszen IndexOutofRange kivtelt dobott, ha olyan cella indexre mutattunk, ami nincs. A
lista ezzel szemben egy dinamikus tmb, mrett automatikusan vltoztatja. A lista egy generikus tpus, teht
brmilyen tpusbl (akr tmbbl, osztlybl, struktrbl, listbl [ennek bemutatsa ksbb])
ltrehozhatunk sajt listt. A lista ltalnos alakja: List<T> lista = new List<T>() ,ahol T egy tpus
(nyilvnvalan ennek megfelel elemeket lehet majd a listba felvenni). Kattintsunk bele a List szvegbe, majd
Visual Studio esetn nyomjuk meg az F12-t, megnylt maga a beptett List (bal bra) s benne tallhatjuk a
hasznlhat metdusokat, a List eltt felfedezhetnk egy
class kulcsszt, ez jelenti azt, hogy osztly, ezrt kell a
List<int> lista = new List<int>();
foreach (int item in lista){
Console.Write(item + ", ");
}
pldnyostsnl a vgre () jelek. Ebbl r is jhetnk
arra, hogy a List egy referenciatpus, teht
paramtertads esetn cm szerint addik t (22. o.),
ugyangy, mint a tmbk. Hozzunk ltre egy int tpus
listt, s jrjuk vgig egy foreach ciklussal, futassuk le, mit kaptunk? Mindenkinek gondolom semmit nem rt ki a
kpernyre, tmbk esetben viszont 0-kat rna ki, de ez esetben, ebben a listban valban nincs semmi,
prbljuk meg pl. a 2. index elemt kirni (lista[2]), ez esetben ArgumentOutofRange exception kivtelt
kaptunk. A lista alapveten egy tmb htter sszetett adattpus, alapveten egy 4db kapacits tmb jn
ltre, s ebbe a tmbbe kerl feltltsre a megadott rtkek, ha a kapacits elfogy, nagyobb lesz az eltroland
rtkek szma, mint a kapacits, akkor egy j tmb jn ltre, kapacitsa mr az elz duplja lesz s az rtkek
tmsoldnak ebbe a tmbbe. Ha zrjelben megadunk egy rtket, akkor az a kezd kapacits lesz, a
kapacitst a lista.Capacity metdussal tudjuk lekrni, mrett pedig a lista.Count tal. j elemet a
lista.Add(rtk) metdussal tudunk felvenni, ami mindig az utols helyre szrja be a megadott rtket,
termszetesen az rtknek meg kell egyeznie a lista tpusval. Nzznk egy pldt: A lista kapacitst 8-rl
indtjuk s felvesznk 3db elemet.
List<int> lista = new List<int>(8);
lista.Add(12);
lista.Add(43);
lista.Add(2);
Console.WriteLine("Kapactsa: " + lista.Capacity);
Console.WriteLine("Mrete: " + lista.Count);
A for-ciklus s a foreach-ciklus is hasznlhat az sszes elem kiratsra, az egyes elemeket ugyangy tudjuk
elrni, mint tmb esetn (pl.: lista[1], ha min. 2db elem van benne), for esetn a lista.Count-ig fut a ciklus.
Ksbb a feltlttt listt tudjuk mdostani is, pl. lista[0] = 14;
List<int> lista = new List<int>();
lista.Add(12);
lista.Add(43);
lista.Add(2);
for (int i = 0; i < lista.Count; i++){
Console.WriteLine(lista[i]);
}
A listkat mr kezd rtkekkel is deklarlhatjuk, pl.: List<int> lista = new List<int>() { 10, 23, 4};
30
Karsa Zoltn
A Listk metdusai
Nzznk meg pr hasznos metdust a listk kezelsre, az Add, Capacity s a Count-on kvl:
List.Insert(hova, mit)
A megadott helyre beszrja a megadott rtket, az ezt kvet elemek eggyel jobbra cssznak, ezrt
idignyes adatfelvteli md. Plda: Elszr hozzadunk 3db elemet (12, 43, 2) a listhoz, majd a 1.(43)
indexre szrjuk be a 31-et, ezutn a lista gy nz ki: 12, 31, 43, 2
List<int> lista = new List<int>();
lista.Add(12); lista.Add(43); lista.Add(2);
lista.Insert(1, 31);
List.Remove(mit)
A megadott rtket kitrli az adott listban, a kitrlt rtk valban eltnik, gy az utna lv elemek
eggyel elrbb cssznak, szinten idignyes a sok mozgats miatt. Ha olyan rtket prblunk kitrlni,
ami nincs a listnkban, nem keletkezik kivtel. Plda: 10, 23, 4 -> 10, 4
List<int> lista = new List<int>() { 10, 23, 4};
lista.Remove(23);
List.RemoveAt(index)
A megadott index elemet kitrli a listbl, a kitrlt rtk valban eltnik, gy az utna lv elemek
eggyel elrbb cssznak, szinten idignyes a sok mozgats miatt. Ha olyan index elemet prbl
kitrlni, ami nincs, nagyobb az index, mint a lista mrete, akkor ArgumentOutofRange kivtel
keletkezik. Pldnkban a 2. index (4) elemet trljk ki. 10, 23, 4, 30 -> 10, 23, 30
List<int> lista = new List<int>() { 10, 23, 4, 30};
lista.RemoveAt(2);
List.Clear()
Trli az adott lista teljes tartalmt s egy teljesen res listt ad vissza, a lista kapacitst nem
befolysolja, ezrt elfordulhat, hogy hiba nincs semmisem a tmbben, mgis nagy helyet foglal a
kirtett listnk, a httrtmb mrete miatt!
List<int> lista = new List<int>() { 10, 23, 4, 30, 10, 16, 19, 20, 34, 10};
lista.Clear();
Console.WriteLine("Trls utn a kapacitsa: {0}, mrete:{1}", lista.Capacity, lista.Count);
List.AddRange(kollekci)
Kpes egy tetszleges, megfelel tpus kollekci(tmbk(1dimezis), halmazok, ms listk) sszes
tartalmt tmsolni az adott lista vgre.
int[] tmb = new int[] { 20, 30, 12 };
List<int> lista = new List<int>();
lista.AddRange(tmb);
List.InsertRange(index, kollekci)
Hasonlan, mint az AddRange, ez is kpes kollekcikat hozzadni a listhoz, de a megadott index
elemtl kerlnek beszrsra a kollekci elemei.
int[] tmb = new int[] { 20, 30, 12 };
List<int> lista = new List<int>(){ 10, 24, 32};
lista.InsertRange(2, tmb);
List.Sort()
Az adott listt nvekv sorrendbe rendezi, stringek esetben az abc rend szerint rendezi az elemeket,
egyes rendszereken a magyar abc-t is tmogatja, egyszerbb tpusoknl mkdik.
List<string> lista = new List<string>() { "bann", "alma", "krte", "narancs", "kiwi"};
lista.Sort();
foreach (string item in lista){
Console.WriteLine(item);
}
31
Karsa Zoltn
List.Contains(elem)
Az adott listban, ha a megadott rtk szerepel, akkor true, ha nem akkor false rtkkel tr vissza.
List<string> lista = new List<string>() { "bann", "alma", "krte", "narancs", "kiwi"};
if (lista.Contains("krte")) Console.WriteLine("Van krte");
T[] = List.ToArray()
Az adott listt egy tmbb konvertlja, a tmbbe az sszes listban lv (aktulis) adat tmsoldik.
List<int> lista = new List<int>() { 20, 31, 10};
int[] tmb = lista.ToArray();
Referencia msols
Mint mr emltettem a lista egy referencia tpus, teht cm szerint addik t, ennek eredmnyeknt, ha egy mr
meglv listbl szeretnnk ltrehozni egy jat, akkor nem a lista rtkei, hanem a cme msoldik t az
jonnan ltrehozott listnkba, ezt nevezznk rtkadskor bekvetkez referencia msolsnak, gy a listkon
kln-kln vgzett vltoztatsok hatssal lesznek a msik listra is. Pldul ha n egy rtket akarok
hozzadni a rgi listbl ltrehozott j listnak, akkor a rgi listba is fel fog kerlni az adott rtk, vagy ha
trlm az egyik lista tartalmt, akkor a msik is trldni fog.
List<int> rgilista = new List<int>() { 20, 31, 10};
List<int> jlista = rgilista;
jlista.Add(40);
Console.Write("rgilista tartalma: ");
foreach (int item in rgilista){
Console.Write(item + ", ");
}
Console.Write("\njlista tartalma: ");
foreach (int item in jlista){
Console.Write(item + ", ");
}
sszetett Listk
Tmbk esetben megtudtuk tenni azt, hogy egy vektoron bell ltrehozzunk mg tmbket, ht listk
esetben se sincs ez mskp, gy gyakorlatilag kikszblhet az 1dimenzis hatr. Nzzk meg hogy hogyan:
A lista deklarcijnl a <> rszek kz egy jabb List<T> vesznk fel, s ezutn pedig a {} jelek kz j listkat
hozunk ltre vesszvel elvlasztva, j belslistt a flista.Add(new List<T>)- vel tudunk felvenni, a bels listkat
az indexk segtsgvel tudunk elrni, s gy felvenni bele elemeket. Ltrehozhatunk struktrbl, tmbbl,
osztlybl, halmazbl is listkat, hasonlan, mint itt, de azt nem trgyalom ennl a rsznl.
List<List<int>> lista = new List<List<int>>() { new List<int>(), new List<int>() };
lista.Add(new List<int>());
lista[1].Add(14);
for (int i = 0; i < lista.Count; i++){ //krbejrsa for-ral
for (int j = 0; j < lista[i].Count; j++){
Console.WriteLine(lista[i][j]);
}
}
foreach (List<int> belslista in lista){ //krbejrsa foreach ciklussal
foreach (int elem in belslista){
Console.WriteLine(elem);
}
}
32
Karsa Zoltn
Lncolt listk - LinkedList -Generikusok
A sima listk esetben az adatokat egy httrtmbben troljuk el, gy ez az adatszerkezet lassabb lesz akkor, ha
sok mozgatst vgznk benne, pl. az Insert metdussal j elemeket szrunk be a lista elejbe, ekkor az azt
kvet rtkeket 1-el arrbb kell tolni, s ez nagyon idignyes. A lasssg kikszblsre hoztk ltre a
lncolt listkat (LinkedList), amit akkor rdemes hasznlni, ha adatstruktrnkban sok mozgats van, fontos
megjegyezni, hogy a lncolt lista nem biztos, hogy gyorsabb, mint a sima lista, amg a listnkban csak a vgre
szrunk be elemeket addig teljesen elg. A lncolt listk nagyobb helyet foglalnak, mint a sima eldjeik, a
lncolt lista tbb, egymshoz hivatkozs ltal sszekapcsolt gy. csompontokbl pl fel, ebben a
csompontban szerepel egy adat, valamint egy (egyszeresen lncolt lista) vagy kett (ktszeresen lncolt lista)
hivatkozs, ami az elz s/vagy a kvetkez csompontra hivatkozik. Egy egyszeresen lncolt (fenn) lista egy
null (lila ngyzet) rtkkel kezddik, ami az els valdi csompontra mutat, amiben szerepel a kvetkez
csompontra hivatkoz mutat (srga) s a csomponthoz tartz rtk, adat(kk), a kvetkez csompont
szintn ugyangy pl fel, a legutols valdi csompont, pedig egy null tpusra mutat, gy tudhatjuk, hogy vge
a lncolt listnak.
Ktszeresen lncolt lista esetn 2db hivatkozs (zld s srga) van egy-egy csompontban, az egyik az elz a
msik a kvetkez csompontra mutat, C#-ban ktszeresen lncolt listk vannak.
Hasonlan, mint a listk, szintn osztlybl vannak ltrehozva s ezrt referencia tpus, termszetesen
referencia msols trtnik rtkadsnl.
Mint a listk esetben is a LinkedList bersa utn a <> jelek kz kerl a lncolt listnk tpusa s a megszokott
nv, egyenlsgjel a new opertor valamint jra a LinkedList s el ne felejtsk a zrjeleket!
Plda: LinkedList<string> lncoltlista = new LinkedList<string>();
Ezutn a Linkedlist.AddLast(rtk) metdussal tudunk a listnk vgre beszrni egy elemet, vagy pldul az
AddFirst(rtk) metdussal pedig a lista els helyre. Mit r ki az albbi program, milyen sorrendben?
LinkedList<string> lncoltlista = new LinkedList<string>();
lncoltlista.AddLast("vr");
lncoltlista.AddLast("kv");
lncoltlista.AddFirst("aut");
foreach (string item in lncoltlista){
Console.WriteLine(item);
}
LinkedListNode<T> = LinkedList.Last/First
Visszaadja egy adott listban szerepl els vagy utols csompontot, amelyben megtallhatjuk a
kvetkez csompontra mutat hivatkozst. A LinkedListNode-rl bvebben ksbb.
LinkedList<string> lncoltlista = new LinkedList<string>();
lncoltlista.AddLast("vr");lncoltlista.AddLast("kv");lncoltlista.AddFirst("aut");
LinkedListNode<string> csompont = lncoltlista.First;
33
Karsa Zoltn
LinkedList.AddAfter(LinkedListNode, rtk)/AddBefore
Egy adott listacsompont mg vagy el szr egy msik csompontot, amelyben a megadott rtk
szerepel, s az j adat bepl a lncolt lista szerkezetbe.
//A lncoltlista azonostj LinkedList mr ltre van hozva, elemei: aut, vr, kv
LinkedListNode<string> csompont = lncoltlista.First;
lncoltlista.AddAfter(csompont, "2.hely");
Tovbbi metdusok, melyek ugyangy mkdnek, mint a listk (30 - 31. oldal) hasonl nev metdusai: Clear,
Remove, Count, Contains, viszont kapacits nincs, mivel csompontok szolgltatjk az adatszerkezetet, nem tmbk!
Tovbbi metdusok: Count, Remove (csak kulcs alapjn), Clear. Ezek megtallhatk a listknl, 30-31. oldal.
34
Karsa Zoltn
Verem - Stack -Generikusok
Bonyolult lenne olyan listt krelni, ami a Last in first out
(LIFO) elvet kveti, teht amit utoljra beletettnk
rtket azt tudjuk kivenni az elsnek, az alatta lv
elemeket pedig csak akkor rjk el amikor mr a fltte
lv elemeket kipakoltuk. Az ilyen problmkra talltk
ki a vermet, br nem foglyuk annyiszor hasznlni, mint a
listt, vagy majd a ksbb megismert halmazt, de azrt
ismerkedjnk meg a hasznlatval. Hasonlan, mint a
tbbi generikus, itt is hasonlelven kel ltrehozni, de
nem az Add metdussal tudunk rtket hozzadni,
hanem a .Push(rtk) metdussal, nzznk egy pldt, a
veremhez 1-4-ig adunk hozz elemet, s ezutn egy
foreach ciklussal vgigjrjuk:
Stack<int> verem = new Stack<int>();
verem.Push(1); verem.Push(2); verem.Push(3); verem.Push(4);
foreach (int item in verem){
Console.WriteLine(item);
}
Ha kirattuk az adatokat lthatjuk, hogy pont fordtva rta ki ket, mint ahogy hozzadtuk, hiszen a verem csak
mindig az utols elemet kpes kivenni, s csak gy tudja elrni a lejjebb lv elemeket, ha a fltte lv
elemeket mr eltvoltotta, ezrt rta ki fordtva a ciklus a benne trolt rtkeket. A verem egyszerre csak az
utols benne foglalt elemet tudja kiolvasni! Nzzk meg, hogy hogyan tudunk kiolvasni belle, ezt a .Pop()
metdus vgzi, mely visszaadja mindig az utols elemet, s ugyanakkor ki is trli belle. gy felhasznlhat egy
while ciklusban is, a verem mrett megad Count segtsgvel:
while (verem.Count != 0){
Console.WriteLine(verem.Pop());
}
Hasznlhat tovbb a listnl mr megszokott albbi metdusok: Clear, Contains s a ToArray, ezek
megtallhatk listknl (30-31.o.).
Queue. Sorhoz a .Enqueue(rtk) metdussal tudunk adatot felvenni, kivenni pedig a Dequeue() metdussal,
mely visszaadja az ppen aktulis els rtket s ki is trli a sorbl. Ugyangy, mint a veremnl a bels
elemeket nem tudjuk elrni, csak akkor tudjuk elrni, ha a mellette lev elemeket eltvoltottuk. gy a Dequeue
felhasznlhat arra is, hogy egy while ciklussal krbejrjuk s kzben kis is trljnk a tartalmt:
Queue<int> sor = new Queue<int>();
sor.Enqueue(1); sor.Enqueue(2); sor.Enqueue(3); sor.Enqueue(4);
while (sor.Count != 0) {
Console.WriteLine(sor.Dequeue());
}
Hasznlhat tovbb a listnl mr megszokott albbi metdusok: Clear, Contains s a ToArray, ezek
megtallhatk listknl (30-31.o.).
35
Karsa Zoltn
Halmazok - HashSet -Generikusok
A halmazok olyan listk, amelyekben azonos rtk elembl csak egy szerepelhet, szintn generikusak. Csakgy,
mint listknl halmazok esetben is a .Add(rtk) metdussal tudunk j adatot hozzadni, viszont ha egy olyan
rtket prblunk jbl hozzadni, amit mr tartalmaz, akkor nem addik hozz s nem is keletkezik kivtel.
HashSet<int> halmaz = new HashSet<int>() { 17, 10, 20, 43};
Console.WriteLine("Hozzads eltt: " + halmaz.Count);
halmaz.Add(17);
Console.WriteLine("Hozzads utn: " + halmaz.Count);
gy nem vltozik meg a mrete se a halmaznak, marad ugyanannyi, mint eltte. Ezt knnyen feltudjuk hasznlni
arra, hogy randomolskor ne legyen mg egy olyan szm, amit mr generltunk egyszer. Pldul szmokat
szeretnnk randomolni az ts lotthoz, lott esetn nem lehetnek azonos szmok. Mivel tudjuk, hogy ha olyan
szmot generlunk, ami mr szerepelt, akkor nem nvekszik a halmaz mrete. Plda:
Random r = new Random();
HashSet<int> lottszmok = new HashSet<int>();
while (lottszmok.Count < 5) {
lottszmok.Add(r.Next(0, 91));
}
Console.WriteLine("A sorsolt lottszmok: ");
foreach (int item in lottszmok) {
Console.Write(item + ", ");
}
Sima tmb, vagy lista esetn elfordulhattak volna azonos szmok is, de halmaz esetn ez nem kvetkezhet be.
SymmetricExceptWith(halmaz)
Visszaadja a metdust meghv halmazba a halmazok metszetn kvli elemeket, teht a kt halmaz
metszetnek komplementert. alaphalmaz = (alaphalmaz halmaz1) \ (alaphalmaz halmaz1), vagy
alaphalmaz s halmaz1 metszetnek komplementere
HashSet<int> alaphalmaz = new HashSet<int>() { 10, 32, 4, 8};
HashSet<int> halmaz1 = new HashSet<int>() { 20, 32, 12, 4};
alaphalmaz.SymmetricExceptWith(halmaz1);
ExceptWith(halmaz)
Kivonja a meghvott halmazbl a megadott halmaz elemeit, a megmaradt rtkeket a meghvott
halmazba trolja el. alaphalmaz = alaphalmaz \ halmaz1
HashSet<int> alaphalmaz = new HashSet<int>() { 10, 32, 4, 8};
HashSet<int> halmaz1 = new HashSet<int>() { 20, 32, 12, 4};
alaphalmaz.ExceptWith(halmaz1);
IntersectWith(halmaz)
A megadott kt halmaz metszett adja vissza. alaphalmaz = alaphalmaz halmaz
HashSet<int> alaphalmaz = new HashSet<int>() { 10, 32, 4, 8};
HashSet<int> halmaz1 = new HashSet<int>() { 20, 32, 12, 4};
alaphalmaz.IntersectWith(halmaz1);
Hasznlhat tovbb a listnl mr megszokott albbi metdusok: Clear, Contains s a Remove, ezek
megtallhatk listknl (30-31.o.).
36
Karsa Zoltn
ArrayList- Sorlista - kollekci
A sorlistban eltr tpus adatokat tudunk felvenni, a System.Collections nvtrben tallhatjuk, referencia
tpus, mivel minden fle tpust ArrayList sorlista = new ArrayList();
feltudunk bele venni, ezrt nem kell sorlista.Add("string"); sorlista.Add(7); sorlista.Add('c');
megadnunk semmilyen tpusra utal foreach (var item in sorlista){
Console.WriteLine(item); }
jelzt. Mivel minden tpus eltrolhat
benne, ezrt ciklusoknl var tpust kell hasznlnunk, hogy minden vltoznl mkdjn. Az Add metdussal
tudunk j adatot bevinni, tovbb hasznlhatk az albbi metdusok: AddRange, Capacity, Clear, Count,
Contains, IndexOf, Insert, InsertRange, Sort,(listk, 30-31) valamint pl.:sorlista[0].GetType() visszaadja a tpust.
Alapsznt fjlkezels
System.IO, StreamWriter, StreamReader
Mivel a programunkban ltrehozott vltozk csak a program futsa alatt lnek, a program bezrsa utn, mr
nem lesz lehetsgnk folytatni ott, ahol abbahagytuk, ennek kikszblse vgett a fjlkezelst kell
alkalmaznunk, a felhasznl ltal bevitt adatokat lementjk, majd beolvassuk a program futsa kzben. Hogy
feltudjuk hasznlni az ezekhez szksges metdusokat be kell emelnnk az IO nvteret (using System.IO).
rs - StreamWriter
Ahhoz, hogy rni tudjunk egy fjlba a StreamWriter osztlyt kell hasznlnunk s meg kell adnunk egy elrsi utat
s egy fjlnevet, amibe majd rni fogunk. Abban az esetben, ha nem adunk meg elrsi utat az exe futtathat
llomnyunk mell kell tenni az adott fjlt, az esetben, hogy ha nincsen meg a megadott fjl, akkor ltrehozza.
Ha mi hozzuk ltre a fjlt, UTF-8 karakterkdolst lltsunk be neki. A fjlneve mellett meg kell adnunk a
kiterjesztsest is, kezdetben elg a txt formtum. Miutn pldnyostottuk a StreamReader-t s meg is adtunk
neki egy fjlt, a nevvel mr el is kezdhetjk a fjlba rs a sw_neve.Write/ WriteLine(karakterlnc) metdussal,
ugyangy mkdnek, mint a Console osztly hasonl nev metdusai a Write nem tesz sortrst, viszont a
WriteLine igen. Miutn befejeztk az adatfolyamot (stream-et), ki kell rteni a puffert, mert ezek a metdusok
egy pufferba rnak, s egy meghatrozott idkznknt rtik csak ki ezeket az ideiglenes trolkat, gy nem
biztos, hogy a metdusok lefutsa utn mr minden adat benne lesz a fjlunkba. A puffer tartalmt a
sw_neve.Flush() metdussal tudjuk kirteni a fjlba, ezutn pedig le kell zrnunk az adatfolyamot az
sw_neve.Close() metdussal. Nzznk egy pldt:
StreamWriter sw_gyumolcsok = new StreamWriter("gymlcsk.txt");
sw_gyumolcsok.WriteLine("alma"); //rs
sw_gyumolcsok.WriteLine("bann");
sw_gyumolcsok.WriteLine("anansz");
sw_gyumolcsok.WriteLine("krte");
sw_gyumolcsok.Flush(); //puffer kirtse
sw_gyumolcsok.Close(); //adatfolyam lezrsa
Ebben az esetben a .exe kiterjeszts llomnyunk mell hozta ltre a fjlt a program (ltalban a bin\debug
mappba), s 4db gymlcsnevet rt bele kln-kln sorokba, ennek a fjlnak kdolsa UTF-8-as gy tmogatja
a magyar kezetes betket. Nzznk meg mr egy elrsi ttal rendelkez fjl rst, mivel a \ jel specilis
karakter ezrt @mdostt kell hasznlnunk a mappk megadsnl. Pldul itt a D merevlemez meghajt,
sajt, azon bell is a fjlok mappba jn ltre az albbi szveges llomny:
StreamWriter sw_elrsittal = new StreamWriter(@"D:\Sajt\Fjlok\szveg.txt");
sw_elrsittal.WriteLine("Elrsi ttal rendelkez szveges llomny");
sw_elrsittal.Flush(); sw_elrsittal.Close();
//el ne felejtsk a puffert kirteni s a fjlt lezrni!
Hogyha jra lefuttatjuk ezt a programot s ms adatot runk ki, akkor lthatjuk, hogy az elzen kirt adat
eltnt, ha egy ltez llomnyba akarunk rni, akkor az llomnytartalma kitrldik s bele rdik az j adat.
Abban az esetben, hogyha valamilyen hiba lpne fel a fjlfolyam kzben, valamilyen IOException addik, pl.
tipikus hibaszokott lenni a rossz mappanv, ekkor pldul DirectoryNotFoundException-t kapunk. Javtsuk ki a
programunkat hibakezelssel az albbi mdon:
37
Karsa Zoltn
try {
StreamWriter sw_elrsittal = new StreamWriter(@"D:\Sajt\Flok\szveg.txt");
sw_elrsittal.WriteLine("Elrsittal rendelkez szveges llomny");
sw_elrsittal.Flush(); sw_elrsittal.Close();
}
catch (DirectoryNotFoundException) {
Console.WriteLine("Nem tallhat egy mappa, valsznleg rossz elrsi utat adott meg!");
}
catch (IOException){
Console.WriteLine("Hiba lpett fel a fjl rsa kzben!");
}
Olvass StreamReader
Fjlbl val kiolvasshoz a StreamReader osztlyt kell hasznlnunk, szintn meg kell adni egy elrsi utat,
valamint magt a fjlnevet, fontos hogy a fjl UTF-8 kdolssal legyen elmentve, klnben nem tudunk
kezetes betket olvasni. Abban az esetben, ha a fjl nem ltezik FileNotFoundException kivtel dobdik. A
ReadLine() metdussal egy darab sor tartalmt tudjuk beolvasni, a ReadLine-hoz tartozik egy mutat, abban az
esetben, ha mg egyszer kiadjuk ezt az utastst mr a 2. sort olvassa be s gy tovbb. Az EndofStream azt adja
vissza, hogy mikor van vge a fjlnak, ha a fjl vgre rtnk true, klnben false rtket ad, gy feltudjuk
hasznlni arra, hogy beolvassa egy while ciklussal egy fjl sszes sort: Pldnkban az asztalon lv fjlbl
olvasunk, s a sorok tartalmt egy List-ben troljuk el.
StreamReader sr = new StreamReader(@"C:\Users\zolcsyx\Desktop\nevek.txt");
List<string> nevek = new List<string>();
while (!sr.EndOfStream) {
nevek.Add(sr.ReadLine());
}
foreach (string item in nevek) {
Console.WriteLine(item);
}
sr.Close();
Plda kivtelkezelssel:
try {
StreamReader sr = new StreamReader(@"C:\Users\zolcsyx\Desktop\nevek.txt");
List<string> nevek = new List<string>();
while (!sr.EndOfStream) {
nevek.Add(sr.ReadLine());
}
foreach (string item in nevek) {
Console.WriteLine(item);
}
sr.Close();
}
catch (FileNotFoundException) { Console.WriteLine("Nem tallhat a fjl!"); }
catch (IOException) { Console.WriteLine("Hiba keletkezett a fjl olvassa kzben!"); }
Struktrk
struct, mezk, konstruktor, metdusok
A struktrk olyan adategysgek, amelyekben klnbz tpus adatokat foglalhatunk egy adatszerkezetbe.
Csakgy, mint a felsorolsnl, a struktrkat is az alprogramokon kvl kell ltrehozni, C# esetn a struct
kulcsszval, ezutn kvetkezik a neve, majd a kapcsos zrjelek kztt a magadott mezk public lthatsggal
(OOP). Pldnkban egy Dik struktrt hozunk ltre, nv, letkor s lakhely mezkkel:
struct Dik {
public string nv;
public int letkor;
public string lakhely;
}
//Main, egyb eljrsok
Miutn ezt megtettk ltre kell hoznunk egy pldnyt a Dik struktrbl az egyik alprogramban, s a nevre,
valamint a mezkre hivatkozva megadhatjuk neki az adattagjait, s le is krhetjk:
38
Karsa Zoltn
static void Main(string[] args) {
Dik d = new Dik();
d.nv = "Pter";
d.lakhely = "Nyregyhza";
d.letkor = 15;
Console.WriteLine("Neve: "+ d.nv);
}
Egy struktrban megadhatunk eljrsokat s fggvnyeket is, ezeket nevezzk metdusoknak, pldul
egsztsk ki, a Dik struktrt egy Kir() nev eljrssal,ami kirja az egyn adatait s jegyeit, hozzunk ltre mg
egy listt benne, amibe majd a dik jegyeit adhatjuk meg, valamint egy tlag fggvnyt, ami visszaadja a dik
jegyeinek tlagt. A struktra deklarcijnl automatikusan lefut metdust konstruktornak hvjuk,
konstruktor eljrst a struktra nevvel azonos nev metdussal tudunk csinlni, a konstruktorban pldnkban
gy megadhatjuk a deklarcikor mr az egyes mezket paramterezssel, a konstruktorban fel kell hasznlni az
sszes mezt! A this sz, a struktrn belli mezk azonostsra szolgl, a rgebbi keretrendszerekben
ktelez volt a hasznlata minden esetben, jelenleg elg akkor alkalmaznunk, amikor 2db azonos vltoznv
van egy struktrn bell, pldnkban egy meznvknt s egy paramternvknt szerepel a nv sz. A
this.nv a struktra mezjre, mg a sima nv a kapott paramterre hivatkozik.
struct Dik {
public string nv; //<- erre mutat a this
public int letkor;
public string lakhely;
public List<int> jegyei;
public Dik(string nv, int k, string h) {
this.nv = nv; this.letkor = k; this.lakhely = h; this.jegyei = null;
//^ mivel ktelez az sszes adattagot belltani ezrt a jegyei null
}
public void Kir() {
Console.WriteLine("Nv: " + this.nv);
Console.WriteLine("letkor: " + this.letkor);
Console.WriteLine("Lakhely: " + this.lakhely);
Console.Write("Jegyei: ");
foreach (int item in this.jegyei) {
Console.Write(item + ", ");
}
Console.WriteLine("\nA dik tlaga: " + tlag());
}
public double tlag() {
int sszeg = 0;
foreach (int item in this.jegyei) {
sszeg += item;
}
return sszeg / (double) this.jegyei.Count;
}
}
static void Main(string[] args) {
Dik d = new Dik("Andrs", 17, "Sopron");
d.jegyei = new List<int>() { 4, 5, 3, 5, 5, 4 };
Console.WriteLine("A dik adatai:");
d.Kir();
Console.ReadKey();
}
A struktra egy rtktpus, teht rtkadskor csak a mezk rtkei msoldnak t (ellenben pldul a lista,
aminl referencia msols trtnik, lsd. 31.o.), gy az egyes pldnyokon bell vgzett mdostsok nem hatnak
a msik vltozra. Egy struktrbl ltrehozhatunk akr egy listt vagy tmbt is. Plda a listra s tmbre:
List<Dik> dikok = new List<Dik>();
Dik d = new Dik("Andrs", 17, "Sopron");
dikok.Add(d); //vagy rgtn: dikok.Add(new Dik("Andrs", 17, "Sopron"));
//vagy tmb esetn:
Dik[] dikokT = new Dik[10];
dikokT[0] = d;
39
Karsa Zoltn
Egyb opertorok, bit mveletek
csonkolt opertorok, hromoperandus opertor, bit opertorok
A csonkolt logikai opertorok (|, &) ugyanarra valk, mint a rendes trsaik, csakhogy a csonkolt opertorok a
teljes felttelt kielemzik, ellenben a sima logikai opertorokkal. Pldul a teljes vagy (||) opertor esetn mr
akkor igaz kirtkelst kapunk, ha az els vizsglt elem is mr true, hiszen flsleges megnzni a msodik
operandust is, ezzel szemben a csonkolt opertor a teljes felttelt kirtkeli, hogy ez akkor mirt is kell (?), j
krds, valsznleg ez volt az eredeti vagy opertor, s ksbb jelent meg a prja, csak aztn megmaradt.
if (false && true) Console.WriteLine();
else //rgtn az else gra ugrik
if (false & true) Console.WriteLine();
else //hiba lesz mr false, a msodik operandust is vizsglja
A hromoperandus opertor: C#-ban egyetlen hromoperandus (gy. ternris) opertor van, ami egy if-else
g helyettestsre szolgl, mivel hromoperandus, ezrt hrom rtket kell megadni a ? : opertornak,
szintaktikja: felttel ? ha igaz : ha hamis. Pldul dntsk el egy szmrl, hogy pozitv vagy negatv:
int szm = int.Parse(Console.ReadLine());
//if-else -vel:
if (szm < 0)
Console.WriteLine("Negatv");
else
Console.WriteLine("Pozitv");
//A ternris opertorral:
Console.WriteLine(szm < 0 ? "Negatv" : "Pozitv");
Nem csak ilyen esetekben hasznlhatjuk a ? : opertort, nzznk egy abszolt rtk fggvnyt:
static int Abszoltrtk(int szm) {
return szm > 0 ? szm : szm * -1;
//felttel ^ha nem, akkor a -1-szerest
// ^ha igaz, nmagt adjuk vissza
}
40
Karsa Zoltn
Tagads Not s And Vagy Or Kizr vagy Xor
Negci Konjukci Diszjukci Antivalencia
Ktoperandus
Ktoperandus
Kpoerandus
a ~a a b a&b a b a|b a b a^b
1 0 1 1 1 1 1 1 1 1 0
0 1 0 1 0 0 1 1 0 1 1
1 0 0 1 0 1 1 0 1
Egyoperandus
0 0 0 0 0 0 0 0 0
Bit eltolsra a >> s a << opertor hasznlhat, a >> jobbra tolja el, 1-szeres eltols esetn a bitsorozatunk el
egy darab 0 szrdik be, s az utols bit kitrldik (vehetjk gy is, hogy a semmibe toldik el). Ha a balra tols
<< opertort hasznljuk, akkor a bitsorozatunk mg fog egy darab 0-s beszrdni s az eltte lv szmok
pedig balra elcssznak, tolhatunk akr 2, 3 lptkkel is, szintaktikjuk: eltoland szm >> mennyit
Pldul: int c = a << 2; //2-vel eltolja balra az a vltozt
Console.WriteLine("a: " + Convert.ToString(a, 2)); //1101 = 13 dec
int c = a >> 2;
Console.WriteLine("c: " + Convert.ToString(c, 2)); //0011 = 3 dec
A var-t hasznlhatjuk akr struktrk, listk, osztlyok pldnyostsra is, n azt javaslom, hogy ne hasznljuk a
var azonostt, mert gy nem ltszik rgtn az adott vltoz szerepe, tovbb fordtskor idt pazarlunk vele.
var Struct = new Struktra();
var lista = new List<string>();
A goto utasts
A goto meghvst kveten a vezrls arra a pontra ugrik, ahol a meghvskor megadott cmke/azonost van
megadva, ez lehet a meghvs utn (ebben az esetben tugrunk egyb utastsokat), vagy eltt (ismtls, mint
egy ciklus gyakorlatilag). Formja: goto ugrs; utasts1; utasts2; ugrs: utasts Ebben az esetben a goto
miatt tugrotta a vezrls az utasts1-et s 2-t. Csinlhatunk akr igy ciklusokat is az albbi mdon:
int i = 0;
vissza: Console.WriteLine("Az i rtke: " + (++i));
if (i < 10) goto vissza;
Egy goto-hoz csak egy ugrs tartozhat, gy nem lehet megadni tbbszr ugyanazt a cmkt. Fontos: a goto nem
rsze a struktrlt programozsnak, mert tlthatatlann teszi a kdot, NE HASZNLJUK!
41
Karsa Zoltn
OOP Object-Oriented Programing
alapelv, felptse, plda
Az objektum-orientlt programozs gyakorlatilag egy programozsi mdszertan, a vals vilg modellezsn
alapul. Egy egy osztlyt (class) tbbszr is felhasznlhatunk, gy kevesebb idt vesz ignybe maga a fejleszts, de
az objektum-orientlt program lasabban fut (elhanyagolhat klnbsg). A OOP-ben az sszetartoz adatokat
s az azokkal mveleteket vgz eljrsokat vagy fggvnyeket egy egysgbe, msnven osztlyba szervezzk.
Egy osztlyt tekinthetnk egy mintnak, tervrajznak is melybl pldnyokat tudunk ltrehozni, ez lesz egy-egy
objektum, amit az adott osztly alapjn pldnyostunk. Egy objektum vltozit meznek, adattagnak vagy
tulajdonsgnak (attributum) hvjuk, az objektumhoz tartoz eljrsokat, fggvnyeket pedig metdusnak.
Kezdetben nagyon hasonlt a struktrkra, viszont a struktra rtk, mg egy osztly referenciatpus. Nzznk
egy pldt, csinljunk egy Ember osztlyt, melynek attribtumai: nv, letkor, lakhely s munkahely. Csinljunk
hozz egy Kir nevezet metdust, mely kirja egy adott emberpldny adatait! Egy egy osztlyt a class Program
kvl kell ltrehozni: class Osztlyneve { lthatsg tpus meznv; lthatsg eljrstpus metdusnv(){} }.
gy mint a struktrknl public lthatsgot adjunk meg, hogy mirt majd ksbb!
class Ember {
public string Nv;
public int letkor;
public string Lakhely;
public string Munkahely;
public void Kir() {
Console.WriteLine("Nv: " + Nv);
Console.WriteLine("letkor: " + letkor);
Console.WriteLine("Lakhely: " + Lakhely);
Console.WriteLine("Munkahely: " + Munkahely);
}
}
Hozzunk ltre egy ember pldnyt a Mainen bell, ez lesz egy Ember objektum, mivel ez referenciatpus, gy ha egy
meglv emberbl csinlunk egy msik emberpdnyt, akkor a hivatkozs fog ltrejnni, ezrt az adott
emberpldnyokon elvgzett mdostsok mind a kt pldnyra kihatnak!
//class Program, Main...
Embepr e = new Ember();
e.Nv = "Tth Jzsef"; e.letkor = 32; e.Lakhely = "Eger"; e.Munkahely = "XYZ Kft.";
Ember e2 = e;
e2.Nv = "Horvt Bla";
Az objektumok adatmezit gyakran elrejtjk ms programozk ell, hogy azok ne frjenek hozz, ne tudjk
mdostani, C#-ban 3 lthatsg van:
public: brhonnan hozzfrhetnk, az adatmezt/eljrst lekrhetjk, mdosthatjuk
protected: csak szrmaztatott osztlybl rhetjk el, lsd: OOP rklds, 45. oldal
private: csakis az osztlyon bell rhet el (helyi tagvltoz, sajt), a leszrmaztatott osztlyok nem lthatjk
s nem is mdosthatjk.
Csinljunk egy kutya osztlyt (nagyon erltetett plda, de megteszi), a kutynak lesz egy neve, s egy hsgszintje,
ami privt lesz, mivel az adott kutyapldnyt csak etetssel s jtkkal lehet az hsgszintjt befolysolni, gy
kikszbljk azt a problmt, hogy ksbb mikor egy j kutyt hozunk ltre a fejleszt helytelenl hasznlja fel az
adott mezt
42
Karsa Zoltn
class Kutya {
public string Nv;
private int hsgJelz = 50;
public void Etet(int tel) {
hsgJelz -= tel;
}
public void Jtk() {
if (hsgJelz <= 80) {
hsgJelz += 50;
Console.WriteLine("Jtk...");
}
else Console.WriteLine("A kutya hes, nem tudsz jtszani vele!");
}
}
class Program {
static void Main(string[] args) {
Kutya k = new Kutya();
k.Jtk();
k.Jtk();
Console.ReadKey();
}
}
Konstruktor, destruktor:
Mint mr a struktrknl emltettem a konstruktornak hvjuk egy osztly azon metdust, mely az objektum
pldnyositsakor kerl meghvsra, paramterekkel egytt. A konstruktort az osztly nevvel kell megadni s public
lthatsggal klnben nem tudnnk elrni. A konstruktrbl csinlhatunk tbbet is (tlterhels), ekkor eltr
szignatrj konstruktorokat ksztnk, melyek egymstl fggetlenl hasznlhatk. Az objektum adatmezinek
eltvoltst a destruktor vgzi, mivel a Garbage Collector autmatikusan vgzi a szemt eltakartst nem
determisztikusan (kiszmthatan) trtnik a destruktor meghvsa, destruktort a ~OsztlyNeve alakban tudjuk
megadni, destruktort struktrnl nem lehet megadni mivel rtktpus. Kutya konstruktora:
//class Kutya{...
//Konstruktor
public Kutya(string n, int h) {
this.Nv = n; this.hsgJelz = h;
}
public Kutya() { }
//Destruktor:
~Kutya() {
Console.WriteLine("Destruktor...");
}
Tlterhels esetn az osztlyokban nem kell teljesen j konstruktort megadni, elg egy olyan konstruktort rni ami az
sszes adattagot belltja, majd egy eltr paramtelistval rendelkez konstruktort rni, majd utna : -al
this(paramterek) alakban megadni az adott konstruktort, a nem megadott mezket lltjuk rtktpus(int, double)
esetn 0-ra referencia tpus esetn null rtkre. gy az j konstruktorunk gyakorlatilag csak meghvja a teljes rtkt.
class Ember {
public string nv;
public int letkor;
//sszes rtket bellt konstruktor
public Ember(string nv, int letkor) {
this.nv = nv; this.letkor = letkor;
}
//csak a nevet bellt
public Ember(string nv) : this(nv, 0){ }
}
43
Karsa Zoltn
meghvjuk a Console osztly Write metdust. Statikus metdus esetn nem frnk hozz az osztlyunk mezihez,
gy pldul csak a paramterben tadott pldny elemeit tudjuk hasznlni. Nzznk kt pdt: ltrehozunk egy Dik
osztlyt egy pldny s egy osztlymetdussal:
class Dik
{
public string nv;
public int vfolyam;
public void Kir() { // pldnymetdus
Console.WriteLine("Neve: " + this.nv);
Console.WriteLine("f.: " + this.vfolyam);
}
static public void Kir(Dik d) { // osztly/statikusmetdus
// Console.WriteLine("Neve: " + this.nv); <-- Hibs lenne
Console.WriteLine("Neve: " + d.nv);
Console.WriteLine("f.: " + d.vfolyam);
}
}
Hasonlkppen hasznlhatunk statikus mezket is, mely csak kzvetlenl az osztlyon keresztl frhetnk hozz, pl.:
class llandk {
public static double PI = 3.14;
}
Abban az esetben, ha csak statikus osztlyok s mezk vannak az osztlyunkban, lehetsgnk van statikus osztlyok
ltrehozsra is (ezzel vigyzzunk!!), ekkor az osztlyunk el kell biggyezteni a static szt, de ha ezt csinljuk, akkor az
osztlybl nem lehet pldnyt ltrehozni (pl.: Dik d = new Dik();)
static class llandk {
public static double PI = 3.14;
}
Ez esetben csak gy hasznlhat fel az osztly pi mezje: double pi = llandk.PI;
Publikus adattagoknl, mezknl nem tudunk ellenrzst csinlni, hogy ha csak bizonyos rtkeket adhassunk meg,
akkor kln eljrst kell rnunk, viszont ez nem rhat/olvashat kzvetlenl, ezrt jellemzket, tulajdonsgokat
(property) kell rnunk. Ez egy olyan specilis osztlyelem, amely br mez s vltoz mdjra viselkedik, de
olvassa s rsa esetn a memriaterletek kzvetlen rsa helyett, a megadott olvas (get) s/vagy r (set)
metdusok kerlnek meghvsra s azok futnak csak le. A get akkor kerl meghvsra, amikor rtket olvasunk ki a
mezbl s a return utastssal adjuk meg, a set akkor, amikor egy meznek rtket adunk vagy mdostjuk, a set
metdusnl a megadott rtkre a value azonost hivatkozik. ltalban ekkor a privt mezknek, amit majd a
tulajdonsgok lltanak be, kisbetvel kezdd, mg a tulajdonsg esetn nagybetvel kezdd, de ugyanazt adjuk.
Egy jellemz lehet csak rhat (writeonline csak set metdus), csak olvashat (readonline csak get metdus) vagy
rhat s olvashat is. Visual Studio esetn a Ctrl + R, E billentykombincit lenyomva az adott privt mezn
ltrehozza a hozz tartoz jellemzt. Csinljunk mi is egy ilyen jellemzt: Ksztsnk egy Ember osztlyt nv, letkor
s lakhelynek rnytszm mezkkel, csinljunk rhat s olvashat jellemzket az sszes adattaghoz s kezeljk
le azt, hogy ne tudjunk majd res mezt adni a nv atribtumnak az letkor ne lehessen negatv, az irnytszm
pedig 4jegybl lljon, klnben dobjunk kivtelt!
44
Karsa Zoltn
class Ember {
//Ha a tulajdonsgokkal adjuk meg a konstruktort akkor is ellenrzst vgez
public Ember(string n, int , int isz) {
Nv = n; letkor = ; Irnytszm = isz;
}
private string nv;
public string Nv {
get { return nv; }
set {
if (value.Length != 0) nv = value;
else Exception("A nv mez nem lehet res!");
}
}
private int letkor;
public int letkor {
get { return letkor; }
set {
if (value >= 0) letkor = value;
else Exception("Az letkor mez nem lehet negatv");
}
}
private int irnytszm;
public int Irnytszm {
get { return irnytszm; }
set {
if (value.ToString().Length == 4) irnytszm = value;
else Exception("Az irnytszm mez helytelen!");
}
}
private void Exception(string s) {
throw new FormatException(s);
}
}
45
Karsa Zoltn
OOP rklds Gerincesek
rklds, protected, polimorfizmus
Elmondhatjuk, hogy a gyerekosztlyok public s protected lthatsg esetn hozzfrnek az sosztly mezihez s
metdusaihoz, de ezen kvl bvithetik a tagvltozit, j metdusokat hozhatnak ltre s a szlosztly metdusait
akr fell is brlhatjk, ms metdusokat kszthetnek egyazon nv alatt. A konstruktorok nem rkldnek, abban
az esetben, ha az sosztlyban van paramter nlkli konstruktor, az a leszrmazott class A {
osztly konstruktorban hivdik meg, ha paramterezve van az sosztly private int a;
konstruktora, akkor viszont a gyermek konstruktorban kell meghvni a base public A(int a) {
this.a = a;
kulcsszval. A base kulcssz hasonlan, mint a this az egy csaldfhoz tartoz
}
mezket rhetjk el vele, gy ha olyan paramter van, ami megegyezik egy osztly }
egy mezjvel akkor a base kulcsszval azonosthat. Nzznk egy pldt: adott a
kvetkez sosztly konstruktorral (jobb)
46
Karsa Zoltn
Mivel az leszrmaztatott osztly rkli az a mezt, ezrt hibs az albbi gyermekosztly konstruktora, ez j:
class B : A { class B : A { Ez a mdszer akkor rdemes
protected int b; protected int b; hasznlni, hogyha az
public B(int b) { public B(int b, int a) : base(a){ sosztly mezje privt, gy
this.b = b; this.b = b;
} } csak az sosztly
} } konstruktorval tudnnk
belltani a mezt, klnben
elg lenne a base.meznv = xy; belltani. Attl mg, hogy mi privtnak lltjuk be az sk mezit, attl mg
rkldnek, csak nem ltjuk.
gy meghvjuk az sosztly konstruktort a megadott paramterrel, hogy lltsa be az a attribtum rtkt.
Is a viszony:
Csinljuk meg a kvetkez s s gyermekosztlyt:
class Jrm {
public Jrm(int seb) {
sebessg = seb;
}
public int sebessg;
public int Megy(int h) {
return h * sebessg;
}
}
class Aut : Jrm {
public Aut(int seb, int ajtksz, int cst) : base(seb) {
ajtkSzma = ajtksz; Csomagtr = cst;
}
public int ajtkSzma;
public int Csomagtr;
}
Jrm osztly leszrmazottjai is egy jrm, az aut is egy jrm (az egy - is - a). gy a jrm osztlyra megrt
metdusoknak az Aut objektumokat, pldnyokat is tadhatjuk. (Megj.: Nem tudom ki emlkszik a minden lgy
bogr, de nem minden bogr lgy dologra, ht itt is ez van minden aut jrm, de nem minden jrm aut). Pldul
ez mkdik, nincs szintaktikai hiba:
static void JrmKir(Jrm j, int h) {
Console.WriteLine(j.sebessg);
Console.WriteLine(j.Megy(h));
}
static void Main(string[] args) {
Jrm j = new Jrm(30);
JrmKir(j, 10);
Aut a = new Aut(120, 5, 20);
//nincs szintaktikai hiba, hiba Jrm pldnyt vr az eljrs:
JrmKir(a, 10);
}
De mivel egy jrm nem biztos, hogy aut a kvetkez kd csak explicit konverzival rvnyes:
Jrm j = new Jrm(30); Jrm j = new Jrm(30);
Aut a = j; Aut a = (Aut) j;
Konverzi esetn futs idej hibt kaphatunk, mert a jrm nem tartalmaz az autban lert metdusokat, mezket.
gy ha az adott jrm nem aut a kvetkez hibt kapjuk konverzi esetn: InvalidCastException - Az objektum nem
konvertlhat Jrm tpusrl Aut tpusra. Ennek elkerlse rdekben hasznljuk az is s az as opertort, az is true
rtket ad vissza, ha a baloldaln megadott pldny megfelel a jobb oldalon lv tpussal, az as opertor
megvalstja a konverzit akkor, ha az objektum megegyezik a jobb oldalon megadott tpussal klnben null rtkre
lltja be a pldnyt, plda:
47
Karsa Zoltn
static void JrmKir_1(Jrm j, int h) {
Console.WriteLine(j.sebessg);
Console.WriteLine(j.Megy(h));
if(j is Aut) {
Aut a = (Aut)j;
Console.WriteLine(a.ajtkSzma);
Console.WriteLine(a.Csomagtr);
}
}
static void JrmKir_2(Jrm j, int h)
{
Console.WriteLine(j.sebessg);
Console.WriteLine(j.Megy(h));
Aut a = j as Aut;
if (a != null) {
Console.WriteLine(a.ajtkSzma);
Console.WriteLine(a.Csomagtr);
}
}
gy egy metdusban tbb jrm adatot is bellthatunk/kirhatunk, anlkl hogy esetleg kivtelt dobna. Mivel a
kdunk ms jrm leszrmazottakra is mkdik ne csak a jrm mezit irassuk ki, hanem a megfelel elgazsokban
nzzk meg, hogy az tadott objektum esetleg aut-e, akkor az aut osztly mezit is ratjuk ki.
Az override mdostval elltott eljrsok egyben virtual mdostval elvannak ltva, gy a tovbbi leszrmazott
osztlyok is felltudjk definilni. Nzznk egy pldt:
class Emlsk {
public virtual void Evs() {
Console.WriteLine("Etets");
}
}
class Kutya : Emlsk {
public override void Evs() {
Console.WriteLine("Etets, farok csvls");
}
}
class Labrador : Kutya {
public override void Evs() {
Console.WriteLine("Etets, ugats");
}
}
48
Karsa Zoltn
Vajon mi fut le az albbi kd esetn a Mainben?
Emlsk e = new Emlsk(); e.Evs(); //Etets
Kutya k = new Kutya(); k.Evs(); //Etets, farok csvls
Labrador l = new Labrador();l.Evs(); //Etets, ugats
A new hasznlata:
Az albbi kdban nem jeleztnk semmitse a fordtnak a tagfggvnyekrl, ezrt figyelmeztetst mutat, mivel a
Kutya tagfggvnye eltakarja (shadow). Ha azt akarjuk, hogy ne jelezzen, javtsuk ki:
class Emlsk { class Emlsk {
public virtual void Evs() { public virtual void Evs() {
Console.WriteLine("Etets"); Console.WriteLine("Etets");
} }
} }
class Kutya : Emlsk { class Kutya : Emlsk {
public void Evs() { public new void Evs() {
Console.WriteLine( Console.WriteLine(
"Etets, farok csvls"); "Etets, farok csvls");
} }
} }
Ugyanakkor a kutya tovbbi leszrmazottjai a new mdost miatt nem tudjk fellrni az Evs metdust, gy ha azt
szeretnnk, hogy tovbbra is mdosthat legyen a new sz utn hasznljuk jra a virtual szcskt:
class Kutya : Emlsk { class Kutya : Emlsk {
public new void Evs() { public new virtual void Evs() {
Console.WriteLine( Console.WriteLine(
"Etets, farok csvls"); "Etets, farok csvls");
} }
} }
class Labrador : Kutya { class Labrador : Kutya {
public override void Evs() { public override void Evs() {
Console.WriteLine("Etets, ugats"); Console.WriteLine("Etets, ugats");
} }
} }
49
Karsa Zoltn
OOP Polimorfizmus, ksi s korai kts
Csinljuk meg az albbi programot:
class Fegyverek {
public int Sebzs() { return 20; }
}
class Gpfegyver : Fegyverek {
public int Sebzs() { return 5 * 20; }
}
public class Program {
static void Elst(Fegyverek f) {
Console.WriteLine("Sebzs mrtke: " + f.Sebzs());
}
public static void Main(string[] args) {
Fegyverek f = new Fegyverek(); Elst(f);
Gpfegyver gf = new Gpfegyver(); Elst(gf);
Console.ReadKey();
}
}
Ebben az esetben mivel nem rtuk fell (nem volt virtual s override), ezrt mind a kett fegyver elstsnl 20-at rt
ki a kpernyre a korai kts (early binding) miatt, egsztsik ki teht a virtualal az smetdust s overridal a
Gpfegyver osztly metdust:
class Fegyverek {
public virtual int Sebzs() { return 20; }
}
class Gpfegyver : Fegyverek {
public override int Sebzs() { return 5 * 20; }
}
Ha megint lefutatjuk a mainben lv kdot mostmr eltr sebzst kapunk. Mirt is? A nyelvnek azt a kpessgt,
miszerint futsi idben is kpes dnteni ksi (late binding), mg a deklarcikor, fordtskor lefut
tpusmeghatrozs a korai kts, pldul az els programrszben mikor mg nemvolt virtulis metdusunk
fordtskzben dertette ki a fordt, hogy melyik metdus fog lefutni, mivel Fegyver pldnyt vr az Elst eljrs,
ezrt kerlt meghvsra mind a kt esetben a 20-as, teht a fegyverhez tartoz rtk. A polimorfizmus azt a
tulajdonsgot jelenti, hogy futsi idben dnti el, melyik metdus fusson le. gy pldul ha egy olyan Fegyver
kollekcit hozunk ltre, amelyben klnbz fegyverek vannak, akkor nem kell aggdnunk amiatt, hogy egy foreach
vagy for-ciklus esetn ugyanazok a metdusok futnak le, pl.:
Fegyverek[] fT = new Fegyverek[] { new Fegyverek(), new Gpfegyver() };
foreach (Fegyverek item in fT) {
Console.WriteLine("Sebzs mrtke: " + item.Sebzs());
}
Mivel minden osztly az Object osztlybl szrmazik, rkli a ToString() nevezet metdust, ezt mi fell tudjuk rni:
class Fegyverek {
public override string ToString() {
return "Egyb infk: . . . ";
}
}
Ha nem hvjuk meg kln a ToString metdust s csak kzvetlenl a vltozt ratjuk ki, akkor is a ToString fggvny
rtkt adja vissza:
Fegyverek f = new Fegyverek();
Console.WriteLine(f);
50
Karsa Zoltn
OOP - Begyazott osztlyok
Egy osztly tartalmazhat metdusokat, konstruktorokat, deskruktorokat s mg akr egy bels osztly(oka)t is.
Ezeket a bels osztlyokat begyazott (nested) osztlyoknak nevezzk. A begyazott osztlyok alaprtelmezetten
private mdostval vannak elltva, gy kls osztlyok csak lthatsg mdosts esetn hasznlhatjk:
class Kls {
//Ha nem public lenne nem rnnk el:
public class Bels {
static public void Hell() { Console.WriteLine("Hell"); }
}
}
A main-ben a pont opertor segtsgvel rhetjk el: Kls.Bels.Hell();
A begyazott osztly hozzfr az t tartalmaz kls osztly minden tagjhoz (gy a private lthatsg tagokat s
ms begyazott osztlyokat is belertve), de csak akkor, ha a begyazott osztly egy referencit trol a kls
osztlyrl:
class Kls {
private int szam = 15;
private Bels b;
public Kls() {
b = new Bels(this);
}
public class Bels {
private Kls k;
public Bels(Kls k) {
this.k = k;
}
public void KirKlsSzm(){
//ez hibs: Console.WriteLine(szam); Megolds:
Console.WriteLine(k.szam);
}
}
}
Ebben az esetben csinltunk a bels osztlynak egy olyan konstruktort, ami egy Kls osztlypldnyt vr, hogy
onnan tudjuk kiolvasni a szam tartalmt, a kls osztlyban szintn csinltunk egy konstruktort, ami a meghvsa
esetn tadja a sajt pldnyt, nmagt (a this segtsgvel) a bels osztly konstruktornak.
51
Karsa Zoltn
Igy mind a kt metdust hasznlni tudjuk a mainben egy pldny kszitse esetn:
PartialClass pc = new PartialClass();
pc.Kir1();
pc.Kir2();
Begyazott parcilis osztlyt a parcilis osztly is tartalmazhat (a nem parcilis is). Parcilis osztlyon bell lv
begyazott parcilis osztlyok tredkei az t tartalmaz osztly tredkei kztt oszlik szt.
Lehetsgnk van (C#3.0<) parcilis metdusok hasznlatt is, ekkor csak a metdus deklarcija s defincija oszlik
szt, parcilis metdusnak nem lehet lthatsgi mdostja gy alp. privt lesz, s void-al kell visszatrnie, ebben
az esetben is a partial kulcsszt ki kell tenni minden elfordulsnl:
partial class PartialClass {
partial void Kir();
}
partial class PartialClass {
partial void Kir() {
Console.WriteLine("Szia");
}
}
A Skidom osztlyban az Animci eljrs hibahasznln mr a Rajzol metdust, hiszen az nincs kidolgozva. Ebben az
esetben hiba dolgoznnk ki a skidom osztly gyermekosztlyt a korai kts miatt, akkor is a skidomhoz tartoz
metdus futna le. Akkor mit csinljunk? Prbljuk meg virtual s override hasznlatval:
class Skidom {
protected int x;
protected int y;
public virtual void Rajzol(){ }
public void Animci(int x_A, int y_A) {
Console.Clear();
x += x_A;
y += y_A;
this.Rajzol();
}
}
class Vonal : Skidom {
protected int k;
public override void Rajzol() {
Console.SetCursorPosition(x, y);
for (int i = 0; i < k; i++) {
Console.Write("-");
}
}
}
52
Karsa Zoltn
Viszont ezzel a megoldssal is tbb problmnk van: lehetsges, hogy a fejleszt elfelejti felldefinilni egy virtulis
metdust s erre semmilyen hibazenetet nem kap, ha hasznlnk az adott eljrst nem trtnne semmi. St
flslegesen fordul le egy teljes rtk res metdus s gy helyet foglal (nem tl sokat). A msik problma pl. ha
nem void tpus lenne, akkor mgis valamilyen rtket visszakelljen adjon a fggvny, hogy szintaktikailag helyes
legyen, de mit adjunk vissza? Az ilyen jelleg metdusok/osztlyok megfelel ksztse az abstract szval trtnik,
ezzel a szval megmondjuk a fordtnak, hogy az sosztlyban nem tudtuk megrni ezeket az eljrsokat, de
deklarljuk ket, hogy a gyermekosztlyban hasznlhatk legyenek. Ezeket a metdusoknl nem kell {} tenni csak egy
pontosvesszt a deklarci vgre. Fontos, hogy csakis absztrakt osztlyban lehetnek absztrakt metdusok, s
absztrakt osztly pldnyostst megtiltja a fordt.
abstract class Skidom {
protected int x;
protected int y;
public abstract void Rajzol();
public void Animci(int x_A, int y_A) {
Console.Clear();
x += x_A;
y += y_A;
this.Rajzol();
}
}
class Vonal : Skidom {
protected int k;
public override void Rajzol() {
Console.SetCursorPosition(x, y);
for (int i = 0; i < k; i++) {
Console.Write("-");
}
}
}
rdekessg: Ha pldul az sosztlyban olyan absztrakt metdust hozunk ltre, amit a gyermekosztlyban sem
tudunk megrni, akkor azt a gyermekosztlyt is abstract jelzvel kell elltni, termszetesen ez esetben sem
pldnyosthat az absztrakt osztly.
Az absztrakt osztlyok gyakorlatilag egy kzs felletet biztostanak a leszrmazottjaiknak. Ugyan absztrakt
osztlyokat nem lehet pldnyostani, de ennek ellenre az albbi kd rvnyes:
Skidom[] sT = new Skidom[2];
sT[0] = new Vonal();
Ha jobban belegondolunk nem is trtnt pldnyosts, ez esetben viszont igen, ezrt szintaktikailag helytelen:
sT[1] = new Skidom();
53
Karsa Zoltn
OOP Interfszek
Az absztrakt osztlyok s interfszek nagyban hasonltanak egymsra, ha egy interfsz egy osztly snek lltunk,
akkor meghatrozza az osztly fellett, elr egy mintt. Az interfsznek nagy elnye, hogy mg egy osztly csak
egy db osztlybl rkldhet, addig egy osztly tbb interfszt is hasznlhat (class Osztly : Interfsz1, Int2, ), st
interfszt akr struktrk (38. o.) esetben is hasznlhatunk. Az interfszek neveit konvenci szerint nagy I betvel
kezdjk. Ugyangy, mint az absztrakt osztlyoknl a metdusokhoz, jellemzkhz nem tartoznak defincik, csak
deklarcik.
interface IKszns {
void Reggel();
void Este();
void Napkzben();
}
interface Idvzls {
void Szia(string nv);
}
class Kszns_dvzls : IKszns, Idvzls {
public void Reggel() { Console.WriteLine("J reggelt!"); }
public void Este() { Console.WriteLine("J estt!"); }
public void Napkzben() { Console.WriteLine("J napot!"); }
public void Szia(string nv) { Console.WriteLine("Szia {0}!", nv); }
}
Az interfszek tagjainak nem lehet lthatsgi mdostt megadni alaprtelmezetten publikusak lesznek. Magnak
az interfsznek is alaprtelmezetten publikus a lthatsga, de jellhetjk internal-knt is. Ahogy a pldban is
lthat egy interfszt hasznl osztlynak definilni kell az interfszben deklarlt sszes tagjt, klnben szintaktikai
hibt kapunk. Abban az esetben elhagyhat ez, ha az osztly s tagjai absztarktknt van deklarlva, ebben az esetben
majd az az osztly fogja definilni ezeket a tagokat, amely az absztrakt osztlybl rkldik, pl.:
interface IPlda {
void Plda();
}
abstract class Absztraktplda : IPlda {
public abstract void Plda();
}
class PldaClass : Absztraktplda {
public override void Plda() { Console.WriteLine("Plda"); }
}
Egyszerre szrmaztathatunk egy osztlyt egy osztlybl s tbb interfszbl is, ekkor az sosztlynak kell az els
helyen szerepelnie, majd utna vesszvel elvlasztva kvetkeznek az interfszek, pl.:
class MyClass : PldaClass, IPlda { }
Ez esetben nincs szintaktikai hiba, mirt is? Mert mr az IPlda interfsz Plda metdust a PldaClass osztly mr
definilta, s mivel megtettk ezt az osztlyt az snek, ezrt a MyClass-ban is l a Plda metdus.
Ha egy interfsz snek egy interfszt tesznk meg, akkor ksbb az interfszbl ltrehozott osztlyoknl az
sinterfsznek is meg kell valstani a tagjait:
interface IPlda {
void Plda();
}
interface IPlda2 : IPlda{
void Plda2();
}
class MyClass : IPlda2{
public void Plda() { Console.WriteLine("Plda1"); }
public void Plda2() { Console.WriteLine("Plda2"); }
}
Ebben az esetben nem hasznlhatunk lthatsgi mdostt. Nem tudjuk hasznlni az osztly pldnyostsa utn a
Plda metdust, ezrt konvertlnunk kell a megvalstott interfszre:
MyClass mc = new MyClass();
((IPlda)mc).Plda();
Termszetesen a fenti esetben 2 operandus opertorrl beszlnk, ha kevesebb kell, akkor kevesebb paramtert
kell megadni, vagy tbbet. Nzznk egy pldt: Csinljunk egy sajt integer tpust s adjuk meg a + opertort:
class EgszSzm{
int szam;
public int Szam { get { return szam; } set { szam = value; } }
public EgszSzm(int szam) {
this.szam = szam;
}
static public EgszSzm operator +(EgszSzm sz1, EgszSzm sz2){
return new EgszSzm(sz1.szam + sz2.szam);
}
}
Ezutn nyugodtan hasznlhatjuk megfelel alkalmakkor a += opertort. Szoks szerint a paramterek nevnek lhs-t
(left-hand-side) illetve rhs-t (right-hand-side) szoktak megadni. Tovbbi fellrhat opertorok: +,-,/,*,%,>,<, ++, -- s
logikai opertorok
Abban az esetben, ha logikaiopertorokat adunk meg, akkor meg kell csinlni az opertor prjt is, teht a == is
valamint a != definilni kell, vagy < esetn a prjt a >-t is... Nzzk meg mi lesz az EgszSzm osztlyunk == s !=
statikus metdusa:
static public bool operator ==(EgszSzm sz1, EgszSzm sz2)
{ //ternris opertor(?:) hasznlatval, lsd.:40.o.
return sz1.szam == sz2.szam ? true : false;
}
static public bool operator !=(EgszSzm sz1, EgszSzm sz2)
{ //hvjuk meg a == metdust s vegyk a tagadst, fontos hogy ne != rjunk hiszen azt ebben
definiljuk:
return !(sz1 == sz2);
}
55
Karsa Zoltn
A ++/-- opertorok esetn csak a prefixes formt tudjuk megvalstani, br mkdik a postfixes forma, ugyanazt az
eredmnyt kapjuk, mintha prefixest adtunk volna meg. Nzzk a pldt:
static public EgszSzm operator ++(EgszSzm sz1){
sz1.szam += 1;
return sz1;
}
Implicit s explicit konverzi esetn is megtudjuk mondani az osztlynak, hogy mit csinljon, ehhez az implicit s az
explicit szavakra van szksgnk:
static public implicit operator EgszSzm(int sz) {
return new EgszSzm(sz);
}
static public explicit operator EgszSzm(string sz) {
return new EgszSzm(int.Parse(sz));
}
Hasznlata:
EgszSzm sz1 = 10;
EgszSzm sz2 = (EgszSzm)"4";
Egy delegate pldnya hasonlan mkdik, mint egy sima vltoz, tadhatjuk egyb eljrsoknak, fggvnyeknek is,
amelyek majd meghvjk a benne lv metdusokat.
56
Karsa Zoltn
class Class {
public delegate void Meghvs(int i);
static public void Ciklus(Meghvs mh) {
for (int i = 0; i < 1000; i++) {
mh(i);
}
}
}
class Program {
static void Kir(int i) {
Console.WriteLine("i = {0}", i);
}
static void Main(string[] args) {
Class.Meghvs mhKir = new Class.Meghvs(Kir);
Class.Ciklus(mhKir);
Console.ReadKey();
}
}
Az esemnykezelknek ltalban 2 paramtert szoktak megadni (nem muszj, csak szoks): egy objektumot, amin az
esemny vgbement, valamint a msodik paramter az EventArgs osztly vagy egy se. Hogy tudjuk, hogy mgis mi
trtnt, csinljunk az EventArgs osztlynak egy olyan st, ami kpes egy zenetet megjelenteni. Ezutn az
osztlyunkban mdostsuk az esemny delegate-nek a szignatrjt, valamint az esemnykezel fggvnyt.
class Esemny : EventArgs {
public string zenet;
//aki nem tudja, mit csinl a konstruktor lapozzon vissza!
public Esemny(string str) : base()
{
zenet = str;
}
}
57
Karsa Zoltn
Nzzk, hogyan vltozott az osztlyunk:
class Szm {
public delegate void EsemnykezelDelegate(object o, Esemny e);
public event EsemnykezelDelegate llapotvltozsEsemny;
int szam = 0;
public int Szam {
get { return szam; }
set {
szam = value;
llapotVltozs();
}
}
private void llapotVltozs() {
if (llapotvltozsEsemny != null)
llapotvltozsEsemny(this, new Esemny("A szm megvltozott!"));
//a this-szel tadja az osztly sajt magt
}
}
class Program {
static void EsemnyKezels(object esemnytkivltosztly, Esemny e) {
Console.WriteLine(e.zenet);
}
static void Main(string[] args) {
Szm sz = new Szm();
sz.llapotvltozsEsemny += EsemnyKezels; //feliratkozunk az esemnyre
sz.Szam = 21; //kivltjuk az esemnyt;
Console.ReadKey();
}
}
A rendszernk nyelvtl fggen rja ki az idpontot, pl. angol esetn nap, hnap, v sorrendben. A DateTime.Now
visszaadja a pontos jelenlegi idpontot, az AddDays(), AddYears() fggvnyek hozzadjk a megadott idegysget
az objektumunkhoz. A DateTime.Year/Mont/Day jellemzk visszadjk az adott idpont egy-egy megadott rszt.
DateTime most = DateTime.Now;
DateTime ktnapmlva = most.AddDays(2);
DateTime egyvvelezeltt = most.AddYears(-1);
Console.WriteLine("{0}. van", most.Day);
58
Karsa Zoltn
Kt idpont kztt eltelt idt gy tudunk meghatrozni, ha a kt idpontot levonjuk egymsbl, az eredmny egy
TimeSpan objektum lesz, amiben a klnbsg eltroldik, ezutn a TotalDays(), TotalHours() fgvnyekkel
rhetjk el, hogy sszesen hny nap, ra a klnbsg:
DateTime szlinap = DateTime.Parse("1999.07.23.");
TimeSpan hnyvesvagyok = DateTime.Now - szlinap;
Console.WriteLine(hnyvesvagyok.TotalDays / 365);
59
Karsa Zoltn