A C# programozási nyelv a felsıoktatásban Programozás tankönyv

Dr. Kovács Emıd Hernyák Zoltán Radványi Tibor Király Roland

1/312

Tartalom
Tartalom ..................................................................................................................................... 2 Történeti áttekintı ...................................................................................................................... 7 Elsı generációs programozási nyelvek: GÉPI KÓD........................................................... 8 Második generációs programozási nyelvek: ASSEMBLY ................................................. 9 Változók az assembly nyelvben ........................................................................................... 10 Vezérlési szerkezetek az assembly nyelvben ....................................................................... 13 Eljáráshívás az assembly nyelvben ...................................................................................... 14 Több modulból álló programok az assembly nyelvben ....................................................... 14 Harmadik generációs programozási nyelvek: PROCEDURÁLIS NYELVEK ................ 15 Az elsı nagyon fontos változás – az eljárás fogalmának bevezetése............................... 15 A másik fontos változás a változó fogalmának finomodása: ........................................... 15 A harmadik fontos változás – a típusrendszer bıvíthetısége........................................... 16 A negyedik fontos változás – a vezérlési szerkezetek bevezetése ................................... 17 Az ötödik fontos változás – a hardware függetlenség...................................................... 17 Három-és-fél generációs programozási nyelvek: OBJEKTUM ORIENTÁLT NYELVEK 18 Negyedik generációs programozási nyelvek: SPECIALIZÁLT NYELVEK .................. 18 Ötödik generációs programozási nyelvek: MESTERSÉGES INTELLIGENCIA NYELVEK 18 A programozási nyelvek csoportosítása ............................................................................... 18 A programozási nyelveket más szempontból vizsgálva egy másik csoportosítás fedezhetı fel:......................................................................................................................................... 18 Imperatív (procedurális) nyelvek: .................................................................................... 18 Applikatív (funkcionális) nyelvek:................................................................................... 19 Logikai nyelvek:............................................................................................................... 19 Objektum-orientált nyelvek: ............................................................................................ 19 Futtató rendszerek ................................................................................................................ 19 Bevezetés A Microsoft®.NET ................................................................................................. 22 „Helló Világ!” .......................................................................................................................... 28 Feladatok: ............................................................................................................................. 36 „Alap I/O” ................................................................................................................................ 37 Az alapvetı Input/Output ..................................................................................................... 38 Programozási feladatok ........................................................................................................ 53 „Szelekció alapszint”................................................................................................................ 54 A logikai típusú változó ....................................................................................................... 55 A feltételes utasítás............................................................................................................... 56 Az elágazás........................................................................................................................... 57 Néhány egyszerő példát a szelekció alkalmazására. ............................................................ 58 Döntsük el egy számról, hogy páros-e! ............................................................................ 58 Oldjuk meg az együtthatóival adott másodfokú egyenletet! ............................................ 59 Megoldásra ajánlott feladatok .............................................................................................. 60 Elıírt lépésszámú ciklusok....................................................................................................... 61 Feladatok: ............................................................................................................................. 69 „Vektorok!” .............................................................................................................................. 71 Vektorok kezelése ................................................................................................................ 72 Tömb deklarálása ............................................................................................................. 72

2/312

A tömb elemeinek elérése ................................................................................................ 73 A tömb elemeinek rendezése, keresés a tömbben ............................................................ 74 Vektor feltöltése billentyőzetrıl....................................................................................... 78 Vektor feltöltése véletlenszám-generátorral..................................................................... 80 N elemő vektorok kezelése................................................................................................... 81 Összegzés ......................................................................................................................... 81 Maximum és minimum kiválasztása ................................................................................ 82 Eldöntés ............................................................................................................................ 83 Kiválogatás....................................................................................................................... 84 Dinamikus mérető vektorok ................................................................................................. 86 Az ArrayList fıbb jellemzıi: ........................................................................................... 86 Az ArrayList fıbb metódusai:.......................................................................................... 86 Feladatok dinamikus tömbre ............................................................................................ 87 Többdimenziós tömbök........................................................................................................ 92 További megoldásra ajánlott feladatok ................................................................................ 96 „Logikai ciklusok” ................................................................................................................... 99 A ciklusok .......................................................................................................................... 100 A while ciklus................................................................................................................. 100 A break ........................................................................................................................... 104 A continue ...................................................................................................................... 105 A do while ciklus............................................................................................................ 105 A foreach ........................................................................................................................ 106 Programozási feladatok ...................................................................................................... 108 „Szelekció emelt szint!” ......................................................................................................... 109 Szelekció haladóknak ......................................................................................................... 110 További megoldásra ajánlott feladatok .............................................................................. 116 Stringek kezelése.................................................................................................................... 117 A string típusú változó ....................................................................................................... 118 A string-ek mint vektorok .................................................................................................. 123 Programozási feladatok ...................................................................................................... 126 Eljárások alapfokon................................................................................................................ 127 Feladatok: ........................................................................................................................... 133 Függvények írása.................................................................................................................... 136 Feladatok: ........................................................................................................................... 141 Eljárások és függvények középfokon..................................................................................... 142 Feladatok: ........................................................................................................................... 147 Eljárások és függvények felsıfokon ...................................................................................... 148 „WinForm”............................................................................................................................. 156 A Windows Formok ........................................................................................................... 157 Hibakezelés ........................................................................................................................ 157 A try és a catch ............................................................................................................... 157 A finally blokk ............................................................................................................... 160 Kivételek feldobása ........................................................................................................ 161 Checked és unchecked ................................................................................................... 162 Programozási feladatok ...................................................................................................... 163 Új Projekt készítése............................................................................................................ 164 Feladatok ............................................................................................................................ 170 A látható komponensek, a kontrollok ................................................................................ 171 Button (Gomb) ................................................................................................................... 171 Label, Linklabel ................................................................................................................. 172

3/312

Textbox............................................................................................................................... 173 CheckBox ........................................................................................................................... 174 GroupBox ........................................................................................................................... 175 MainMenu .......................................................................................................................... 176 RadioButton ....................................................................................................................... 178 ComboBox ......................................................................................................................... 179 ListView ............................................................................................................................. 183 TreeView ............................................................................................................................ 186 TabControl ......................................................................................................................... 189 DateTimePicker komponens .............................................................................................. 191 MonthCalendar komponens ............................................................................................... 194 HorizontalScrollBar és VerticalScrollBar komponensek................................................... 197 Listbox................................................................................................................................ 199 Panel ................................................................................................................................... 200 PictureBox .......................................................................................................................... 201 Timer komponens............................................................................................................... 202 NumericUpDown ............................................................................................................... 203 ProgressBar ........................................................................................................................ 205 TrackBar ellenırzés............................................................................................................ 206 HelpProvider ...................................................................................................................... 207 ImageList............................................................................................................................ 211 RichTextBox ...................................................................................................................... 215 ToolTip............................................................................................................................... 218 ContextMenu...................................................................................................................... 220 NotifyIcon .......................................................................................................................... 222 StatusBar ............................................................................................................................ 223 ToolBar............................................................................................................................... 225 Formok használata, formok típusai .................................................................................... 228 A rendszer által biztosított üzenetablakok használata.................................................... 228 Modális és nem modális formok .................................................................................... 231 Dialógusok ......................................................................................................................... 234 A fontDialog................................................................................................................... 234 ColorDialog .................................................................................................................... 236 PrintPreviewDialog ........................................................................................................ 237 Fájl megnyitása és mentése ............................................................................................ 238 MessageBox ................................................................................................................... 238 Feladatok ............................................................................................................................ 239 Többszálú programozás...................................................................................................... 240 Feladatok ............................................................................................................................ 243 „Grafikai alapok!” .................................................................................................................. 244 A grafikus szoftver ............................................................................................................. 245 GDI+................................................................................................................................... 247 GDI+ osztály és interfész a .NET-ben ............................................................................... 247 Névterek, namespaces .................................................................................................... 247 A System.Drawing névtér osztályai és struktúrái .......................................................... 248 A Graphics osztály ......................................................................................................... 248 A GDI+ újdonságai ............................................................................................................ 250 Gazdagabb színkezelés és színátmenetek lehetısége..................................................... 250 Antialising támogatás ..................................................................................................... 250 Cardinal Spline-ok.......................................................................................................... 251

4/312

Mátrix transzformációk .................................................................................................. 252 Skálázható régiók (Scalable Regions)............................................................................ 252 Alpha Blending .............................................................................................................. 252 Sokkféle grafikus fájl formátum támogatása (Support for Multiple-Image Formats): .. 253 Néhány változás a GDI+ porgramozásban......................................................................... 254 Vonal rajzolás GDI+ használatával................................................................................ 254 Metódusok felülbírálása (Method Overloading) ............................................................ 255 Többé nincs a grafikus kurzornak aktuális poziciója (Current Position) ....................... 255 Szétválasztott metódus a rajzolásra (Draw) és a kitöltésre (Fill) ................................... 256 Regiók létrehozása ......................................................................................................... 257 Interpoláció és approximáció ............................................................................................. 261 Hermit-görbe ...................................................................................................................... 261 Bézier-görbe ....................................................................................................................... 262 de Casteljau-algoritmus.................................................................................................. 262 A Bézier-görbe elıállítása Bernstein-polinommal ......................................................... 263 Bézier-görbe néhány tulajdonságai ................................................................................ 263 Harmadfoú Bézier-görbék.............................................................................................. 264 Kapcsolódó Bézier-görbék ............................................................................................. 265 Cardinal spline................................................................................................................ 267 Pontranszformációk............................................................................................................ 271 Homogén koordináták ........................................................................................................ 271 Áttérés hagyományos Descartes koordinátákról homogén koordinátákra:.................... 271 Visszatérés homogén koordinátákról Descartes koordinátákra: .................................... 271 Ponttranszformációk........................................................................................................... 271 Elsı példa: ...................................................................................................................... 272 Második példa: ............................................................................................................... 273 GDI+ transzformációs metódusai....................................................................................... 274 Eltolás:............................................................................................................................ 275 Elforgatás az origó körül alfa szöggel pozitív irányba:.................................................. 275 Tükrözés: ........................................................................................................................ 275 Skálázás:......................................................................................................................... 276 Nyírás: ............................................................................................................................ 276 A koordináta rendszer transzformálása és a Path használata ............................................. 278 Grafikus konténerek ........................................................................................................... 279 „Adatok kezelése!”................................................................................................................. 281 Az ADO.NET Adatkezelés C#-ban ................................................................................... 282 SQL Server Enterprise Manager Az SQL Server és az MMC ........................................... 282 Új elemek létrehozása .................................................................................................... 283 MS SQL szerver elérése C#-ból......................................................................................... 288 Bevezetés az ADO.NET kapcsolódási eszközeihez....................................................... 288 Connection String........................................................................................................... 288 Kapcsolat létrehozása és megszüntetése ........................................................................ 288 Összetett kapcsolatok (Pooling Connections) ................................................................ 289 Tranzakciók .................................................................................................................... 289 Beállítható kapcsolat tulajdonságok............................................................................... 289 Kapcsolatok tervezéskor a Server Explorer-ben ............................................................ 290 Kapcsolat tervezési eszközök Visual Studio-ban........................................................... 290 Kapcsolat létrehozása SQL Server-hez ADO.NET használatával ................................. 290 Kapcsolat bontása........................................................................................................... 291 ADO.NET kapcsolat objektumok létrehozása ............................................................... 291

5/312

Kapcsolat létrehozása ..................................................................................................... 291 Kapcsolat létrehozása SQL Server-hez .......................................................................... 292 SQL Server kapcsolat Server Explorer-ben ................................................................... 292 Kapcsolódás SQL Server-hez az alkalmazásunkból .......................................................... 292 Kapcsolódás létrehozása vizuális eszközökkel .............................................................. 292 Server Explorer-bıl ........................................................................................................ 292 A DataTable osztály ........................................................................................................... 293 Szőrés és rendezés az ADO.NET-ben............................................................................ 293 Szőrés és rendezés a DataView objektum segítségével ................................................. 295 Az alapértelmezett nézet ................................................................................................ 296 A RowFilter tulajdonság ................................................................................................ 296 Rendezés a DataViewban............................................................................................... 296 Tárolt eljárások................................................................................................................... 302 Mi is az a Transact-SQL?............................................................................................... 302 Alapvetı programozási szerkezetek:.............................................................................. 302 Változók ......................................................................................................................... 302 Feltételes szerkezetek használata ................................................................................... 303 CASE utasítások............................................................................................................. 304 While ciklusok................................................................................................................ 304 A CONTINUE utasítás................................................................................................... 305 A BREAK utasítás ......................................................................................................... 305 RETURN utasítások használata ..................................................................................... 305 WAITFOR utasítások használata ................................................................................... 305 RAISERROR utasítások használata............................................................................... 305 KURZOROK használata ................................................................................................ 306 Mint a példaprogramban is látható, a változók típusa meg kell, hogy egyezzen a kinyert sorok oszlopainak típusával. .............................................................................................. 307 Függvények használata .................................................................................................. 307 Felhasználói függvények létrehozása............................................................................. 308 Helyben kifejtett táblaértékő függvények ...................................................................... 309 Többutasításos táblaértékő függvények ......................................................................... 309 Tárolt eljárások létrehozása:........................................................................................... 310 Tárolt eljárások végrehajtása:......................................................................................... 311 Kioldók........................................................................................................................... 311

6/312

Programozás tankönyv I. Fejezet Történeti áttekintı Hernyák Zoltán 7/312 .

. Ezek a számok 0. egyetlen nagy mérető byte-sorozatnak tekinthetı. 0. A bal oldali oszlopban a memóriacímeket adjuk meg (0044F02B... 1. Egy ilyen rekesz tartalma egy egész szám lehet. és többnek speciális feladat volt. története. mások könnyen elkerülhetıek. úgy azokat is számként kell megadni. A regisztereknek kötött nevük van. A memória ma már alapvetıen byte szervezéső.könnyen dokumentálható a kód.könnyen áttekinthetı forráskód. A 32 bites processzorokon a regiszterek nevei felvették az ’E’ elıtagot (Extended AX regiszter – EAX). ezért nem lehetett akármilyen célra felhasználni. elısegítve a programozási hibák minél korábban (lehetıleg fordítási idıben) történı felfedezését.255 értéktartományból. pl. .255 közötti egész számok. Olvassuk be az elsı számot az EAX regiszterbe a memóriából. CX. Egy igazán jó programozási nyelven nagyon sok hibafajta eleve el sem követhetı. A fejlıdés során a programozási nyelvek szintaktikája változott meg. A gépi kódú utasítások a második oszlopban vannak (a 8B45F4 8/312 . 2.könnyen elsajátítható alapelvekkel rendelkezik.könnyen módosítható. Az eredményt (az EAX regiszter új értékét) tároljuk a memória egy másik pontján. Minden byte egy egész számot jelölhet. hogy a mikroprocesszor alapvetıen az utasításokat is számoknak tekinti.nehéz hibát elkövetni kódolás közben. A számkódokat leggyakrabban hexadecimális formában adják meg. DX. A gépi kódban létezı fogalom a regiszter. Aránylag kevés regiszter áll rendelkezésre (kevesebb mint 20 darab). Emeljünk ki néhányat ezek közül: . fejlıdése. Két szám összeadását az alábbi módon kell végrehajtani: 1. 3. BX. Az EAX regiszterhez adjuk hozzá a második számot. AX. Ebbıl az következik. Amennyiben az utasításnak vannak paraméterei. amely a mikroprocesszoron belüli tárlórekeszt jelöl. bıvíthetı a forráskód.…) ahol az adott gépi kódú utasítást tároljuk.A számítástechnika történetének egyik fontos fejezete a programozási nyelvek kialakulása. . ábra Az utasításokat számkódok jelölik. . A gépi kódú programozási nyelvben az utasításokat számkódok jelölik. Egy jó programozási nyelv sokféle jellemzıvel rendelkezik. A programozási nyelveket generációkba lehet sorolni a fejlıdés bizonyos szakaszait figyelembe véve: Elsı generációs programozási nyelvek: GÉPI KÓD A számítógépek a NEUMANN elveknek megfelelıen a végrehajtandó programutasításokat a memóriában tárolják.

Elınyei persze akadnak ennek a nyelvnek is: a gépi kódú utasítások segítségével maximalizálhatjuk a programunk futási sebességét. Ennek már egyértelmően megfelel egy gépi kódú utasításkód (mov eax = 8B). valamint a paramétereit jelöli: honnan kell beolvasni az értéket az EAX regiszterbe (45. Az ASSEMBLY nyelv elsı közelítésben a ’megérthetı gépi kód’ nyelve. hiszen megkötések nélkül felhasználhatjuk a mikroprocesszor minden lehetıségét.<memcím>”. de ezen a szinten újabb fogalmak jelentek meg: 9/312 . Sok más hátránya mellett külön kiemelendı. Az utasítás egyik lehetséges formája „MOV EAX. Nemcsak számkódjukban különböznek. nehezen tanulható. illetve más-más a paraméterezése a hasonló feladatú utasításoknak. elıször még el kellett sajátítania a különbségeket. Ezért az assembly nyelv is processzor-függı.F4)). ábrán a harmadik oszlopban szerepelnek a gépi kódú utasítások assembly nyelvő megfelelıi. Egy nagyobb rendszer elkészítése olyan idıigényes feladat lenne. A programozó szemszögébıl a gépi kódban történı programozás nagyon lassú folyamat. Az utasítások számkódjait néhány betős (2-3-4 betős) ún. mnemonikokkal helyettesítették. vagy memória-kihasználtságát (vagy mindkettıt egyszerre). és szabadon használhatjuk a memóriát is. Például a „memória-tartalom beolvasása egy regiszterbe” (bemozgatás) az angol MOVE=mozgatni szó alapján a MOV mnemonikot kapta. de az utasítások különbözısége sok nehézséget okozott. hanem esetleg kevesebb vagy több utasítás van. Vagyis más processzor esetén az utasításkódok is mások. Második generációs programozási nyelvek: ASSEMBLY A gépi kódú programozási nyelv hátrányai miatt új nyelvet kellett kifejleszteni. Egy ilyen mnemonik (emlékeztetı szócska) a gépi kódú utasítás jelentéstartalmára utalt. egy egyszerő összeadás mővelet is . hogy inkább csak rövidebb. A kész program nehezen megérthetı. A MOV utasítás önnmagában nem lefordítható gépi kódra. Aprólékosan lehet csak a programot felépíteni. A „két szám összeadása” az angol ADD=összeadni mnemonikot kapta. nem áttekinthetı. hogy a gépi kódú programokat alkotó utasítások csak az adott mikroprocesszor számára érthetıek. hogy melyik memória-cím tartalmát kell betölteni melyik regiszterbe. hiszen azt is meg kell adni. Nyilván az alapelvek maradtak.számsorozat egyetlen gépi kódú utasítást (8B). Az utasítások nagyon alacsony szintőek voltak. Az 1. A fentieken is látszik. Ennek megfelelıen az assembly nyelv egy adott mikroprocesszor adott gépi kódjához készült el. Ha egy gépi kódban programozó számára egy másik processzorra kellett programot írni. hogy a gépi kódú programozási nyelv nehézkes. egyszerő programokat készítettek benne a programozók.mint láttuk a fenti példán – három utasításból állt. a memóriacímet pedig a további számkódok írják le.

Ennek során a gépi kódú programváltozatból a programozó megpróbálta visszaállítani annak assembly nyelvő eredetijét. Ez a mővelet persze némi veszteséggel járt – hiszen a tényleges eredeti assembly forráskódban többek között megjegyzések is lehettek. Az assembly nyelvő programok forráskódja olvashatóbb. amely közben a forráskódot egy fordítóprogram (compiler) gépi kódú utasítások sorozatára transzformálja. Egy 128Mb memóriával szerelt számítógépben 128*1024*1024 db 10/312 . Az assembler nem bonyolult program. A gépi kódú programok módosíthatóságának nehézségét jelzi. amelyet a programozók munkájának segítésére (is) alkottak. Fordítás: az a folyamat. ezért visszaállítani sem lehet ıket. hogy az assembly-programozók már nem voltak hajlandók közvetlenül a gépi kódot módosítani. de a programon mégis módosítani kellett. Amennyiben valamely mnemonikot nem ismeri fel (pl. mint a gépi kód. ezért ezt szintaktikai hibának is nevezzük. e közben generálta a gépi kódú utasítássorozatot . emiatt az elsı eszköznek is tekinthetjük. Ezek a megjegyzések a gépi kódú változatba nem kerültek bele. Az assembler végigolvasta a forráskódot sorról-sorra. az assembler hibaüzenettel jelzi a hiba okát és helyét a forráskódban. illetve könnyebben módosítható. inkább helyreállították az assembly forráskódot. mert az eredeti forráskód elveszett. a programozó elgépelte). Erre sokszor azért volt szükség. Az ASSEMBLER a forráskód feldolgozása közben egyszerő ellenırzéseket is elvégez. majd le kell fordítani gépi kódú. A forráskódban az olyan jellegő hibákat. majd újra lefordították (generálták) a gépi kódú programot. hiszen a fordítás egyszerő szabályok szerint mőködik. akkor a fordítási folyamat leáll.Forráskód: az assembly nyelvő programot a CPU nem képes közvetlenül megérteni és végrehajtani. melyek súlyossága folytán a fordítás nem fejezhetı be – fordítási idıben történı hibának nevezzük. tárgyprogramra (object code). Az assembly nyelv esetén ezt a fordítóprogramot ASSEMBLER-nek nevezték. Az assembler a program szintaktikai helyességét ellenırzi le. Ami viszont nagyon fontos lépés – a fordítóprogramok megjelenésével megjelent az igény ezek intelligenciájának fejlıdésére! Változók az assembly nyelvben Az assembly programokban a memória-címekre azok sorszámával lehetett hivatkozni. Ennek oka általában a nyelv szabályai (szintaktikája) elleni vétség. Az assembly nyelvő programot egy szöveges file-ban kell megírni (forráskód). ún. abban elvégezték a módosításokat. A fordítás ellenkezı mővelete a de-compiling.a mnemonikok alapján elıállította a megfelelı gépi kódú utasítás számkódját.

másrészt amennyiben a fizetés értékét mégsem az 1034-es memóriacímen kellett tárolni (változás). hiszen amennyiben a fizetés tárolási igénye 8 byte lenne.[FIZETES]. Az assembly programok sokszor tényleges memóriacímeket (sorszámokat) tartalmaztak számkonstansok formájában. Ez sok szempontból nem volt elég rugalmas: . hogy az ott tárolt adat hány byte-ot foglal el. hogy elkerüljük két tárolóterület átfedését a memóriában (átlapolás).. Megakadályozni nem tudja.[1034] helyett (ami azt jelentette. táblázat-szerő módon írták le: FIZETES ELETKOR NYUGDIJAS = 1034 = 1038 = 1040 Ezek után az assembly programokban az ADD EAX. mivel a memória ennyi db byte-ot tartalmaz. nehezen volt kiolvasható a programból. akkor a fenti esetben az életkor még átlógna a fizetés 1 128*1024*1024-1 11/312 . 134.727] intervallumból kerülnek ki1. Ez az egyszerő és logikus meggondolás indította el a ’változó’ fogalmának fejlıdését. Ezeket a programok elejére összefoglaló jelleggel. mert segíti.217.A programban e memóriacímek sokszor elıfordultak. A fenti esetben a FIZETES volt az azonosító. Ez sokkal olvashatóbb forma. . Ez a változat azért is jobb. hogy a 1034-es memóriacímen milyen adat van.A memóriacím alapján nem dönthetı el. hogy a FIZETES névvel jelölt memóriaterület 4 byte-os tároló hely volt. mi az ott lévı érték jelentése. ugyanis a memóriacím csak a memóriabeli kezdıcímet jelöli. melyhez a programozó konstans formájában rendelt hozzá memóriacímet – helyet a memóriában.A számok nem hordozzák a jelentésüket. akkor egyetlen helyen kellett csak átírni – a program eleji táblázatban. hogy ADD EAX. .sorszámot lehet használni. Ezért a memóriacímek nem voltak könnyen módosíthatóak. A helyzet javítása érdekében a programozók elkezdtek konstansokat használni a programjaikban. hiszen ekkora memória-szakasz fenntartása után a következı memóriaterület (’ELETKOR’ elnevezéssel) 4 byte-tal távolabbi ponton kezdıdik. hogy add hozzá az [1034] memóriacímen található értéket az EAX regiszterben éppen benne levı értékhez) azt írhatták. A példában ezek a sorszámok a [0 . Még fejlettebb assembler fordítók esetén a fenti táblázat az alábbi formában is felírható volt: FIZETES ELETKOR NYUGDIJAS = 1034 = FIZETES+4 = ELETKOR+2 Ebben az esetben már kiolvasható volt a táblázatból.

word. [FIZETES] MOV AL. Az ELETKOR egy szimpla szó (WORD). vagyis egy 4 byte-os helyigényő értéknek még mindig szabad volt az egyik felét beolvasni. 2 byte helyigényő.tárlóhelyének utolsó 4 byte-jára. és adtak értéket az azonosítóknak. Ezek az értékek továbbra is memóriacímek voltak. A fenti problémákon túl az assembler azt sem tudta ellenırizni. A helyes kezelésre a programozónak kellett ügyelnie. A NYUGDIJAS egy byte. 1 byte A fenti utasítások mindegyike elfogadható az assembly nyelv szintaktikai szabályai szerint. aminek helyigénye 4 byte. A fordító mindössze a tárigény-szükséglet kiszámítására használta fel. Amennyiben a fizetés 4 byte-on kerül tárolásra. Többek között meghatározza az adott érték tárolási méretét a memóriában. akkor 2 byte-nyi felhasználatlan terület keletkezne a memóriában (ami szintén nem szerencsés). A típus sok mindent meghatároz. mivel számára a FIZETES csak egy memóriacím volt. Az assembler nem is tudta volna ellenırizni a kódot ebbıl a szempontból. Az elsı esetben a megadott memóriacímrıl 4 byte-nyi adat kerül be az EAX nevő regiszterbe. Második esetben csak 2 byte. Ennek persze a programozó az oka. hiszen nem volt információja arról. aminek helyigénye (mint a neve is mutatja) 1 byte. 2 byte // AL 8 bites regiszter. [FIZETES] MOV AX. és dolgozni vele. Az elsı azonosító címéhez képest a primitív típusnevek (dword. hogy mit is ért a programozó fizetés alatt. hiszen miért olvasnánk be a fizetést tartalmazó számsorozatnak csak az egyik felét? Az ilyen jellegő hibákra azonban az assembler nem tudott figyelmeztetni. aki rosszul írta fel a táblázatot. hogy a tárlórekeszt megfelelıen kezeli-e a programozó a késıbbiekben: MOV EAX. akkor már képesek voltak a tárterület-címeket automatikusan kiosztani. A fenti primitív típusnevek még nem jelölték az azonosítók tényleges típusát. A hibás kezelés lehetıségét még mindig megengedte. de az automatikus kiosztás miatt a memóriaterületek átlapolásának esélye még kisebbre zsugorodott. úgy a második és harmadik utasítás nagy valószínőséggel hibás. 4 byte // AX 16 bites regiszter. …) tárolási igényét ismervén automatikusan növelték a memóriacímeket. A típus ismeretében a fenti táblázat felírható az alábbi formában: DWORD FIZETES WORD ELETKOR BYTE NYUGDIJAS A fenti táblázat szerint a FIZETES egy dupla-szó (DWORD). A memória-beolvasást ugyanis a fogadó regiszter mérete befolyásolja. 12/312 . byte. [FIZETES] // EAX 32 bites regiszter. harmadik esetben csak 1 byte. Ha azonban a fizetés tárolására 2 byte is elég lenne. Amikor az ASSEMBLER-ek már a fenti táblázatot is kezelték. Ezt a plusz információt hívják a programozási nyelvben típusnak.

ahonnan az ugrás történt). Hasonló problémákkal jár a 13/312 . - Ezekbıl kellett összerakni a programot. Visszatérés az ugró utasítást követı utasításra (azon helyre. hatáskör) kezelése is hiányzott az assembly nyelvbıl. majd attól a ponttól kezdve a végrehajtás újra szekvenciális. ’short int’. ’unsigned short int’ típusok. hogy itt valójában feltételes elágazás történt – nem egyszerő. Mivel a jelentést a fordító még nem kezelte. amelynek 1 byte volt a tárolási igénye. Feltétlen vezérlésátadás (ugró utasítás): a program folytatása egy másik memóriabeli pontra tevıdik át. és az assembler programokból. Vezérlési szerkezetek az assembly nyelvben Az assembly nyelv másik szegényes tulajdonsága a vezérlési szerkezetek hiánya. csak egy olyan típusnév volt.Nem voltak ’finom’ típusnevek. csak ezen 1 byte-on hordozott információ jelentésében térnek el. Egy egyszerő elágazást ennek megfelelıen az alábbi módon kellett kódolni: HA feltétel AKKOR kiértékelése … Ut1 UGRÁS_HA feltétel HAMIS CIMKE1-re Ut2 UT1 KÜLÖNBEN Ut3 UGRÁS CIMKE2-re Ut4 @CIMKE1: HVÉGE folytatás @CIMKE2: folytatás … feltétel UT2 UT3 UT4 A fentibıl talán sejthetı. ’bool’. de az ugrást csak akkor kell végrehajtani. Nem volt ’char’. A változó más komponenseinek (élettartam. hogy az assembly nyelvő programból kibogozni. Feltételes vezérlésátadás (feltételes ugró utasítás): mint az egyszerő ugró utasítás. Ezek mindegyike 1 byte tárolási igényő. ha az elıírt feltétel teljesül. Ennek megfelelıen ezt még nem tekinthetjük tényleges típusnévnek. mindössze tárolási-igény névnek. Lényegében csak az alábbi vezérlési szerkezetek találhatóak meg: Szekvencia: a program utasításainak végrehajtása a memóriabeli sorrend alapján történik.

ciklusok megtervezése és kódolása is – különösen az egymásba ágyazott ciklusok esete. akkor hol kapjuk meg a visszatérési értéket? Illetve honnan tudjuk. újra felhasználható eljárásokat és függvényeket. A probléma nem is itt rejtızik. nagyon sokat könnyítenek a programkód olvashatóságán. úgy azt az assembler egy gyors ellenırzéssel észrevette. mint újra megírni a szóban forgó eljárást. hanem függvény. Ugyanakkor a program jelentıs része a fejlesztés közben már elkészült. melyek segítségével a programok fejlesztési ideje. Ezt a szakaszt újra és újra lefordítani az assemblerrel felesleges idı és energiapocsékolás volt. és az assembly nyelv értelemszerően átvette. Így 14/312 . Ezért bevezették a több modulból történı fordítást. De ezek egymással való megosztása a fenti akadályok miatt nehézkes volt. másrészt az akkori számítógépek még nagyon lassúak voltak. és nem generálta újra a hozzá tartozó object kódot. Paraméterek átadására például több mód is van – csakúgy mint a függvények visszatérési értékének visszaadására. Ezeket a lehetıségeket maga a gépi kód tartalmazza. azt a programozó nem módosította – mivel a program már másik pontján járt a fejlesztés. Több modulból álló programok az assembly nyelvben A több modulra tagolás azért volt fontos. Ekkor az assembler a fordításhoz egy listát kapott. Az assembler a forráskód-modulokat egyenként fordította le egy-egy tárgykód (object) állományba. hanem hogy az eljárásnak hogyan adunk át paramétereket? Illetve. ha ez nem eljárás. és a tesztelési ideje is alaposan lerövidült. A nevesített címkék egy jó névválasztással. milyen típusú adattal. hogy mely forráskód-fileokból tevıdik össze a project. de megfelel az eljárásnév primitív fogalmának. A programozók szívesen fejlesztettek általános. nem megfelelıen dokumentált eljárás felhasználása a kódban néha több energia felemésztésével járt. Amennyiben a forráskódon nem történt módosítás. Egy másik programozó által fejlesztett. Egy hosszú forráskód fordítása nagyon sok idıbe került. Eljáráshívás az assembly nyelvben Az assembly nyelv elvileg ad lehetıséget eljáráshívásra is az alábbi formában: ELJARASHIVAS kiiras @kiiras: … VISSZATÉRÉS_A_HÍVÁST_KÖ VETİ_UTASÍTÁSRA A ’kiiras’ itt valójában címke (programsort jelölı név). mert az assembly programok általában nagyon hosszúak voltak. értékkel tér vissza az adott függvény? A fenti kérdésekre a válaszokat maga az assembly nyelv nem tartalmazza.

Ugyanakkor a nyelvi korlátok gátolták a programozási stílus fejlıdését. akik nem hordoztak magukban rossz szokásokat és hibás beidegzıdéseket – azonnal és gyorsan átvették ezeket a szemléletbeli elıírásokat. Ugyanakkor. értékeket kell az eljárás számára átadni. Sıt. és egymás közötti megosztásra. A frissen felnövekvı programozó nemzedék. Ez újabb fontos mérföldkı a fordítóprogram intelligenciájának fejlıdésében. melyek változtak az utolsó fordítás óta. 15/312 . Az eljárásorientált (procedurális) nyelvek sok szempontból elvi. A linker a sok apró kis tárgykód alapján készítette el a mőködıképes programot . szemléletbeli váltást követeltek meg az assembly programozóktól. Ez jelentısen meggyorsította a fordítást egyéb hátrányok nélkül. speciális feladatot végzı program következett. és újabb project kezdése esetén eleve hozzácsatolták a project forráskódlistájához. Ezzel elhárult az általános célú eljárások írásának legjelentısebb akadálya. hogy az eljárás meghívása során milyen adatokat. és rögzített paraméterezése (formális paraméterlista). Az eljárás (és függvény) nyelvi elemmé vált. hogy az assembly nyelv sok olyan lehetıséget rejtett magában. Ezen túl a nyelv rögzítette az átadás módját is. A fentiek bizonyítják. hogy a megadott összes adatot átadjuk-e az eljárásnak (aktuális paraméterlista). Az elsı nagyon fontos változás – az eljárás fogalmának bevezetése. amely miatt megérdemli a külön generációs sorszámot. Ez tovább erısítette a vágyat az általános célú eljárások írására. a szerkesztı program (linker). ezzel lehet a kódban hivatkozni rá. hasonló jelentıs lépésként a fordítóprogram az eljárás hívásakor ellenırizte.csak azon forráskódok fordítása történt meg. A másik fontos változás a változó fogalmának finomodása: A változónak van: Neve (azonosítója). Ez leírta. általános eljárásaikat külön kis kód-győjteményben tárolták. Az eljárásoknak neve volt. a programozók így az újra felhasználható. Harmadik generációs programozási nyelvek: NYELVEK PROCEDURÁLIS Az assembly nyelv hiányosságainak kiküszöbölésére születtek a harmadik generációs nyelvek. egy másik. De az assembly nyelv ez irányú képességeinek hiánya ebben továbbra is komoly gátat jelentett. Miután az assembler végzett a forráskódok fordításával.

Amint feleslegessé vált – megszőnik. belép erre a területre. és ellenırzi a kifejezés típushelyességét. amíg fontos. A dinamikus változó létrehozása és megszőnése ezen lokális területhez kötıdik – amikor a program végrehajtása eléri ezt a pontot. akkor a változó automatikusan megszőnik. összeadás. összeveti. 16/312 . és tárolási (kódolási) módját).globális: a program szövegében több helyen (több eljárásban is) elérhetı.lokális: a program szövegében a változó felhasználása helyhez kötött. helye felszabadul a memóriában. csak egy meghatározott programrészben (körülhatárolt szegmensben) használható fel. A fontos. . struktúrák.. hogy az adott azonosító (változónév) alatt mit ért (milyen típust). listák. . A globális változók minden esetben statikusak is. akkor a változó automatikusan létrejön.A programban lehetetlenné vált a változó tárhelyének részleges kezelése (a változó értékét reprezentáló byte-ok csak egy részének kiolvasása.A típus ezen túl meghatározza az adott nevő változóval elvégezhetı mőveletek körét is (numerikus típusú változóval végezhetı az osztás. felhasználható. . és a helyére késıbb más változó kerülhet. A statikus változók fontosak az adatok megırzése szempontjából. Ezen típusok a meglévı típusok szőkítései (felsorolás típus. …)). módosítása). A harmadik fontos változás – a típusrendszer bıvíthetısége A magas szintő programozási nyelvek eleve adott típusokkal készültek. …). A változó élettartama: . vagy. A változó hatásköre: . míg logikai típusúval a logikai mőveletek (és.A kifejezésekben szereplı adatok és változók típusait a fordítóprogram elemzi. . vagy összetett algebrai adatszerkezetek is lehetnek (pl. kivonás.dinamikus: a változó a program futása közben jön létre és szőnik meg (akár többször is). …). és változatlan helyen lesz a memóriában. résztartomány-típus). A dinamikus változók a memóriaterület gazdaságos felhasználása szempontjából fontosak – a változó csak addig legyen a memóriában. vektorok. Ennek során a programozó bejelentette a fordítóprogram számára érthetı formában.A változókat általában kötelezıen deklarálni kellett.statikus: a változó a program indulásának pillanatától a futás végéig a változó folyamatosan létezik. A dinamikus változók pedig általában lokálisak. Amikor a program végrehajtása elhagyja ezt a területet. Ezzel is nagyon sok tipikus programozó hiba kiszőrhetıvé vált.Típusa (mely meghatározza a memóriabeli helyigényét. sokáig szükséges adatokat statikus változókban tároljuk. A nyelvi alaptípusokból további (felhasználó által definiált) típusokat lehet készíteni. . . A deklaráció helye további információkat jelent a fordítóprogram számára – meghatározza a változó élettartamát és hatáskörét is. szorzás. xor.

A dinamikus változók létrehozását és megszüntetését a fordítóprogram által generált kód automatikusan végzi. 17/312 . . Fennmaradt azonban egy nagyon fontos probléma: a felhasználó által definiált típusokhoz nem lehet operátorokat definiálni.szekvencia: az utasításokat a forráskódban rögzített sorrendben kell végrehajtani. A procedurális nyelvek már nem processzor függıek. Vagyis a felhasználói adattípus kevesebbet ér. …). és melyek nem. könnyen olvasható kódot eredményez. és rögzítették azokat: . A típusokhoz tartozó tárhely-igényt a fordítóprogram kezeli. a ha … akkor … különben … szerkezetek). eleve létezı elemi típus. Természetesen. Amennyiben a programot más platformon is szeretnénk futtatni. hogy minden algoritmus kódolható a fenti három vezérlési szerkezet használatával. egyszerő. logikai feltételhez kötött ciklusok.iteráció: adott programrész ismétlése (elıírt lépésszámú ciklus. A fordítóprogram ismeri az adott számítógép processzorának gépi kódját – és a procedurális nyelven megírt magas szintő kódot az adott gépi kódra fordítja. .A negyedik fontos változás – a vezérlési szerkezetek bevezetése Az assembly nyelv ugróutasításaiból megszervezhetı vezérlési szerkezetek körét csökkentették. amikor a fordítóprogram a gépi kódú változatot generálja. A vezérlési szerkezetek e formája áttekinthetı. kizárt a memória-átlapolás és nem keletkeznek fel nem használt memóriaterületek. úgy a magas szintő forráskódot az adott számítógépre írt fordítóprogrammal újra kell fordítani – a forráskód bármilyen változtatása nélkül. Mills bizonyította. akkor a fenti szerkezeteket ugró utasítások formájában valósítja meg – hiszen a gépi kódban csak ezek szerepelnek. hogy mely változók érhetık el. Ezen a szinten a nyelv fejlıdése nem haladhatja meg ezt a pontot. Az ötödik fontos változás – a hardware függetlenség. mint a ’gyári’. emiatt kifejezésekben nem lehet az új típusokat felhasználni.szelekció: feltételes elágazás (pl. így az ugró utasítások szükségtelenné váltak. A program egy adott pontján mindig egyértelmően megadható a változó hatáskörök figyelembevételével. A memóriaterület kiosztását a fordítóprogam végzi a változó-deklarációk alapján. Emiatt nagyon sok lehetséges programozási hiba egyszerően megszőnt létezni. halmaz alapú ciklusok.

iteráció). amelyek az adott típusú adatokkal végeznek valamilyen mőveletet. Erre jó példa az SQL nyelv. gyakorlatilag e nyelvek kutatása. Mivel ezen függvények és operátorok az adott típushoz tartoznak. Ötödik generációs programozási nyelvek: MESTERSÉGES INTELLIGENCIA NYELVEK A mesterséges intelligencia programozási nyelvekkel elvileg az emberi gondolkodás leírása történne meg. hogy nagyon kevés nyelvi elemmel dolgoznak. és nagyon egyszerő. A programozási nyelvek csoportosítása A programozási nyelveket más szempontból vizsgálva egy másik csoportosítás fedezhetı fel: Imperatív (procedurális) nyelvek: 18/312 . a hozzájuk tartozó mőveletek és operátorok csoportját (halmazát) osztálynak nevezzük.Három-és-fél generációs programozási nyelvek: ORIENTÁLT NYELVEK OBJEKTUM Az objektum orientált programozási nyelvek (OOP nyelv) ezen a ponton jelentenek fejlıdést. A felhasználó sokkal egyszerőbben és szabadabban készítheti el a saját típusait. mint kódolási technikákban. Ezért az OOP nyelvek inkább csak szemléletmódban mások (melyik eljárást és függvényt hova írjuk meg). A saját típusokhoz nem csak operátorokat rendelhet. hanem megadhat függvényeket és eljárásokat is. Ezek után a saját típus szinte minden szempontból egyenragúvá válik a nyelvi alaptípusokkal. Meglévı típusok továbbfejlesztésével (öröklıdés) kevés munkával készíthet új típusokat. illetve a paraméterek. amely elsısorban adatbázis-kezelésre van felkészítve. szinte mondatszerően olvasható utasítások fogalmazhatók meg. A vezérlési szerkezetek is a megszokott három formára épülnek (szekvencia. Az egy típusba sorolt adattároló változók (mezık). Negyedik generációs programozási nyelvek: SPECIALIZÁLT NYELVEK A negyedik generációs nyelvek speciális feladatkörre készült nyelvek. fejlesztése még folyamatban van. Ezen nyelvek jellemzıje. a típus részeinek tekintendık. változók. Ezért az OOP nyelveket nem tekintik külön generációnak. A saját típusaihoz (általában) készíthet operátorokat is (melyeknek jelentését természetesen le kell programozni). Egy OOP nyelvben tehát szintén megtalálhatóak az eljárások és függvények. szelekció.

általában nincs ciklus (helyette rekurzió van). Az értékadó utasítások során részeredményeket számolunk ki – végül megkapjuk a keresett végeredményt. Futtató rendszerek A fordító programok által generált tárgykódokat a szerkesztı program önti végleges formába. Értékadó utasítás sincs. Az elkészült futtatható programot ezen idıpont után az operációs rendszer kezeli. csak függvény visszatérési értékének megadása létezik. A program futása közben egyszerően kiszámítja a szóban forgó kifejezést. A ciklusok pedig azért vannak. A programozó munkája a kifejezés kiszámításának leírására szolgál. Az objektumok egymás mőveleteit aktiválják. és futtatja. 19/312 . hogy az értékadó utasításokat többször is végrehajthassunk. Az értékadó utasítás baloldalán egy változó áll. A program ezen kívül egyetlen logikai kifejezést is tartalmaz. megfelelı mennyiségő bemenı adattal. és logikai állításokat írunk le. a tények és szabályok figyelembevételével meghatároz.Ezen nyelvek közös jellemzıje. Objektum-orientált nyelvek: Az OOP nyelveken a program mőködése egymással kölcsönhatásban álló objektumok mőködését jelenti. Ha egy mővelet nem végrehajtható. A logikai nyelvek tipikus felhasználási területe a szakértıi rendszerek létrehozásához kapcsolódik. A szelekció (elágazás) csak azt a célt szolgálja. Logikai nyelvek: Az ilyen jellegő nyelveken tényeket fogalmazunk meg. hogy bizonyos értékadó utasításokat csak adott esetben kell végrehajtani. a jobb oldalán pedig egy megfelelı típusú kifejezés. melynek értékét a programozási nyelv a beépített kiértékelı algoritmusa segítségével. Egy funkcionális nyelvben nincs változó. A funkcionális nyelvek tipikus felhasználási területének a természettudományos alkalmazások tekinthetıek. Applikatív (funkcionális) nyelvek: A funkcionális nyelveken a kiszámolandó kifejezést adjuk meg. hogy a program fejlesztése értékadó utasítások megfelelı sorrendben történı kiadására koncentrálódik. akkor az adott objektum a hívó félnek szabványos módon (kivételkezelés) jelzi a probléma pontos okát. melyeket interface-ek írnak le.

Ilyen rendszerekben az is megoldható. Vagy valamely utasítás paraméterezése lesz értelmezhetetlen. Ekkor a processzor hibás mőködés állapotára tér át. A hibás ugróutasítás emiatt felfedezhetı. Ennek megfelelıen az utasítássorozatot az operációs rendszer egyszerően átadja a mikroprocesszornak és megadja a program kezdı pontját. Az interpreteres rendszerekben a futtató rendszer a lefordított kódot még végrehajtás elıtt elemzi. hogy a mai programok elszeparált területeken tárolják a programkódot. melyek egy mővelet eredményeképpen kapott értéket egy olyan memóriaterületre írná be. A processzor már ekkor leállítja a program futását.A futtatás háromféleképpen történhet: Direkt futtatás: a generált kód az adott mikroprocesszor gépi kódú utasításait tartalmazza. A futtató rendszer ’kitalálja’ az 20/312 . A mai processzorok már védekeznek ez ellen. ezért elvileg elképzelhetı. és szinte lehetetlen eldönteni. Ugyanakkor jegyezzük meg. és az adatokat. hibás-e. hanem egy köztes kódot. Így a processzor képes felfedezni a hibás értékadó utasításokat. követi az ugrási pontokat. hogy a gépi kód szintjén nincs típusfogalom. és az adatokat gépi kódú utasításokként próbálja értelmezni. Mivel a memóriában (a nagy byte-halmazban) az adatok területén is byte-ok találhatóak. A processzor feltétlenül megbízik a programkódban. Másik védelmi mechanizmus szerint a kód-terület nem írható. amely nem értelmezhetı utasításkódnak. hogy tudná valójában mit csinál a program az adott ponton. a paraméterei is már feldolgozott. egyszerősített formában kódoltak. Interpreterrel futtatás: a fordítóprogram ekkor nem generál közvetlenül végrehajtható gépi kódú utasításokat. A processzor e pillanattól kezdve önállóan végrehajtja a következı utasítást. hogy a változókat nem kell deklarálni explicit módon a program szövegében. ahol utasításkódok vannak. csak olvasható. és hajtja végre az elıírt szabályok szerint. Ma már e módszert inkább csak a vírusok és egyéb kártékony programok használják. A hiba bekövetkezése ellen védelmet jelent. Ezen módszer elınye a maximális végrehajtási sebesség. pontosítja azt (pl. Ez persze valószínőleg nem fog menni. Ezt a ’tárgykódot’ egy futtató rendszer (az interpreter) futás közben utasításonként elemzi. írja és olvassa a memória hivatkozott területeit anélkül. ahol az eredeti programozási nyelv utasításai vannak számkódokká átfordítva. vita nélkül engedelmeskedik és végrehajtja a soron következı utasítást. vagy egy olyan kódot fog találni a processzor. szükséges-e. hogy a program vezérlése egy hibás ugró utasításnak köszönhetıen áttér egy ilyen területre. és áttér a hibakezelı állapotra. hogy az adott utasítás a program feladata szempontjából helyes-e. hiszen egy adatterület belsejébe irányul. változóhivatkozások). és ilyen esemény detektálásakor speciális hibakezelı rutinok futtatására térnek át. Ez meggátolja a programkód futás közbeni módosítását (önmódosító kód) amely egy idıben igen elterjedt volt. szükség esetén az utolsó pillanatban korrigálja. amely a számítógép leállásához (lefagyás) is vezethet.

vagy törli a nem megfelelı típusú változót és létrehoz egy megfelelı típusút helyette. hogy a változó típusa futás közben derüljön csak ki. hogy amennyiben egy programozási nyelv fordítóprogramja képes e virtuális gépi kódú program generálására. Ezen kívül az is megoldható. 21/312 . Egy ilyen ’tárgykód’-ból az eredeti forráskód általában szinte veszteség nélkül helyreállítható. hogy milyen változókra van szüksége. Az interpreteres rendszerek vitathatatlan hátránya. nem univerzális. Egy adott nyelv interpretere (pl. nem feltétlenül hordozza az eredeti programozási nyelv szintaktikai lenyomatát. A fordító nem direktben futtatható gépi kódú programot generál. Ezen ’gépi kód’ eltérhet a jelenlegi gépi kódtól. másrészt a generált ’tárgykód’ az adott programozási nyelv szintaktikai lenyomatát hordozza. vagy akár menet közben többször meg is változzon. még a változónevek és az eljárásnevek is visszaállíthatóak. mint a gépi kódból). és sokkal több típust ismer. Ha nem megfelelı.adott programsorhoz érve. hogy egyrészt lassú a futtatás. hiszen a generált kód alacsonyabb szintő utasításokat tartalmaz. hogy megfeleljenek az utasításnak. A virtuális futtatás elınye. belıle az eredeti forráskód csak veszteségesen állítható helyre (bár sokkal kevesebb veszteség árán. sıt. A futtató rendszer az adott utasításhoz érve ellenırzi hogy ott éppen milyen változók szükségesek. Virtuális futtatás: ez az interpreteres elv módosítását jelenti. úgy a futtatáshoz már felhasználható a kész futtató rendszer. akár korrigálhatja is a feltételeket. hanem egy nem létezı (virtuális) processzor virtuális gépi kódjára generál programot. Az interpreteres rendszerek sokkal rugalmasabbak. amennyiben azt nem találja megfelelınek. a BASIC interpreter) nem képes futtatni más interpreteres nyelv fordítóprogramja által generált ’tárgykódot’. mint általában az interpreteres rendszerekben. és pontosan e pillanatban hozza csak létre. Valamint ezen a virtuális nyelven generált kód más-más processzoron is futtatható lesz. Egy adott utasítás végrehajtása elıtt ellenırizheti a szükséges feltételek teljesülését. sokkal magasabb szintő utasításokat tartalmaz. A legismertebb ilyen nyelv a JAVA. Ezen nyelv interpreteres futtató rendszere (processzor-szimulátor. ahol a futtató rendszert Java Virtual Machine-nak (JVM-nek) hívják. A generált kód már nem feltétlenül hasonlít. virtuális gép) sokkal egyszerőbb. amennyiben az adott processzora is létezik a futtató rendszer. Ezen rendszerek futtatása sokkal biztonságosabb. akkor vagy leáll hibaüzenettel. A felügyelı interpreter idıben leállíthatja a futó programot. ellenırzi hogy azok pillanatnyi típusa megfelelı-e.

Fejezet Bevezetés A Microsoft®.Programozás tankönyv II.NET Hernyák Zoltán 22/312 .

amelyek képesek kapcsolatba lépni egymással csakúgy. mint egy felhasználó. Egy operációs rendszer API leírásában szerepelnek a következı információk: . Ezen szolgáltatásokat pl. amelyeket nem. Az operációs rendszert egy programozó teljesen más szempontból nézi. Ez volt a DOS. akár egér segítségével. amelyeket az operációs rendszer elvégez a program feladatai közül.A Microsoft. amelyeket az operációs rendszer eleve tartalmaz. amely információkat.milyen módon jelzi a függvény a hibákat. feladatok.mik a lehetséges visszatérési értékek. mint nagyobb mérető alkalmazásokkal az Internet-en keresztül.”2 Másik lehetséges meghatározás szerint a dotNet egy programfejlesztési környezet. . amelyben az alkalmazása futni fog.a függvény melyik DLL-ben van benne. Amikor egy programozó egy alkalmazás fejlesztésébe kezd. . A felhasználó számára az operációs rendszer az. A dotNet egyféle szemszögbıl nézve az operációs rendszert helyettesíti elrejtvén. Ez nem tartalmazott túl sok elérhetı szolgáltatást – lévén a DOS egy egyfelhasználós.com/net/basics/whatis. egyfeladatos operációs rendszer. Ez az új generációs technológia a Web szolgáltatásokon alapul – kis alkalmazásokon. általuk elıállított operációs rendszer tartalmazta. és amelyeket a programozó a fejlesztıi munka során felhasználhat.a függvénynek mi a feladata (mit csinál). mely számtalan hasznos szolgáltatással segíti a programozók mindennapi munkáját. embereket. melyekre hivatkozhatunk a programjainkban is. stb… A Microsoft-os világban az elsı ilyen API-t az elsı.microsoft. rendszereket és eszközöket kapcsol össze. sok más dolog mellett ismernie kell. a Windows a rendszer-könyvtáraiban megtalálható DLL (Dynamic Link Library) file-okban tárolja. Minden DLL több függvényt és eljárást tartalmaz. E függvények és eljárások összességét nevezzük API-nak.mi a függvény neve. eltakarván a tényleges operációs rendszert a fejlesztı elıl. . és figyelembe kell vennie azt a környezetet. A környezet egyik legfontosabb jellemzıje az operációs rendszer. A Microsoft honlapján például az alábbi meghatározás szerepel: „ez egy software technológiák halmaza. .mik a paraméterei. . Az API – Application Programming Interface – írja le egy adott operációs rendszer esetén. Ezzel szemben a programozó az operációs rendszert elsısorban az API szempontjából nézi: melyek azok a funkciók. parancsokat lehet rajta keresztül kiadni akár karakteres felületen. és melyek azok. 2 http://www. alkönyvtárakat és file-okat kezel.asp 23/312 . hogy melyek azok a szolgáltatások. amibe be kell jelentkezni.NET-et (továbbiakban dotNet) sokféleképpen lehet definiálni.

a Windows ’95. Ez már nem csak a grafikus felület miatt tartalmazott több felhasználható szolgáltatást. mint pl. Ez a réteg egy jól megírt operációs rendszer esetén nem kerülhetı meg. file-rendszer. Ebben javítottak a többszálú programok kezelésén. A dotNet ezen szempontból egy új API-nak tekinthetı. …) – vagyis az operációs rendszer API-n keresztül. Tekintsük át a Microsoft. A Win32-API a fejlettebb Windows operációs rendszerekben jelent meg.1-el került be a köztudatba. biztonságos operációs rendszer nem engedi meg. használhatják fel az erıforrásokat (hálózat. hogy egy dotNet környezetben a programozónak semmilyen más API-t (elvileg) nem kell ismernie.DOS-API ⇒ Win16-API ⇒ Win32-API ⇒ dotNet-API A Win16-API sokkal több szolgáltatást tartalmazott. ezért a programok csakis az operációs rendszeren keresztül kommunikálhatnak egymással. Mivel egy jól megírt. hanem mivel ez egy többfeladatos operációs rendszer – teljesen új területeket is megcélzott. memória. a Windows 3. A dotNet (elvileg) ma már több különbözı operációs rendszeren is képes mőködni – de a programozónak ezt nem kell feltétlenül tudnia – hiszen ı már nem használja az adott operációs rendszer API-ját. hogy a felügyelete alatt futó programok önállóan kezeljék a számítógép hardware elemeit. csak a dotNet-et által definiált függvényeket és eljárásokat. és bevezettek bizonyos jogosultsági módszerek kezelését is (és még számtalan mást is). 24/312 . Ez olyannyira igaz.NET felépítését: Legalsó szinten az operációs rendszer található. lévén hogy az már grafikus operációs rendszerrel.

A CLR lényegében egy processzoremulátor. míg más 25/312 .A következı szinten van a Common Language Runtime – a közös nyelvi futtató rendszer. Internet Explorer vagy Mozilla. ezért a programkód futtatása közben a memória-hozzáféréseket ellenırizni lehet – így meggátolható a helytelen. A Windows Forms tartalmazza azon API készletet. ugyanis a dotNet-es programok egy virtuális mikroprocesszor virtuális gépi kódú utasításkészletére van fordítva. Az elsı ilyen elıny. névterekbe és osztályokba szervezett a sok ezer hívható szolgáltatás. Ez a réteg írja le az alaptípusok méretét.beleértve a string-eket . vagy hagyományos interaktív grafikus felületen valósítjuk meg. A következı réteg kétfelé válik – aszerint hogy az alkalmazás felhasználói felületét web-es. onnan induláskor azokat visszaolvasni. A következı réteg. hogy a C alapú nyelvekben a vektorok indexelése mindig 0-val kezdıdik. mint a natív kódú programoké. Ennek futtatását végzi a CLR. A rétegek segítségével a programok a háttértárolókon képesek adatokat tárolni. Ez nem csak áttekinthetıbb. A futtatás maga interpreter módban történik. tárolási módját . az ADO. A másik lehetséges választás a WEB-es felülető. melyeket a különbözı programozási nyelvek a fejlıdésük során történelmi okokból különbözı módon értelmeztek. Ezek futtatásához szükséges valamilyen web szerver. hogy a szóban forgó virtuális gépi kódú nyelv típusos. valamilyen browser-ban futó nem kifejezetten interaktív program írása. Fontos eltérés például. A második réteg tartalmazza a dotNet API nagyobb részét. A Base Class Library tartalmazza azokat a szolgáltatásokat. mivel a mai alkalmazások egyre gyakrabban használják fel e professzionális és szabványos technikákat adatok tárolására. A következı réteg – a Common Language Specification – definiálja azokat a jellemzıket. vagy file-ba írni. pl. hibás viselkedés. hogy a végrehajtás megfelelı hatékonysággal történjen. futási sebessége elhanyagolhatóan kisebb. Ezen technikák ma már egyre hangsúlyosabbak. Ez az egyik legérdekesebb réteg. módosítására.NET és XML a 21. az objektum orientált programozásban jártas programozó számára. interaktív alkalmazásokat készíthetünk. hálózati kapcsolatot létesíteni. hogy egy JIT Compiler (JIT=Just In Time) gondoskodik arról. hogy ez már nem csak eljárások és függvények halmaza. elérésére. amelyeket egy dotNet-es programozó felhasználhat a fejlesztés közben. hanem struktúrált. századi adatelérési technológiákat tartalmazza. Ugyanakkor meg kell jegyezni. a kliens oldalon pedig valamilyen internetes tallózó program. de hatékonyabb felhasználhatóságot jelent egy. ugyanakkor a dotNet fejlett futtató rendszere a virtuális gépi kódú utasításokat futás közben az aktuális számítógép aktuális mikroprocesszorának utasításkészletére fordítja le.a tömböket. Másrészt az utasítások végrehajtása elıtt ellenırizni lehet a jogosultságot is – vagyis hogy az adott felhasználó és adott program esetén szabad-e végrehajtani az adott utasítást – pl. és hajtja végre. melyek segítségével grafikus felülető ablakos. Lényeges különbség a megelızı API-kal szemben. Ezért egy dotNet-es program hatékonysága.

független lesz az adott számítógép hardware-tıl is. valamint tervezett egy új nyelvet is. Ennek tudatában a programozónak csak arra kell ügyelni.NET-ben programozni) . amely folyamatosan felügyeli a futó programokat. Tiszta szintaktikájával nagyon jól használható eszköz azok számára. Ugyanakkor nem csak a Microsoft készít fordítóprogramokat erre a környezetre. A réteg nem kevés vita után elsimította ezeket.nem kell új programozási nyelvet megtanulnunk ha már ismerünk valamilyen nyelvet (valószínőleg olyan nyelven is lehet . hogy egy nagyobb projekt esetén a projekt egyik felét egyik programozási nyelven írjuk meg. melynek jelentıségét nem lehet eléggé hangsúlyozni: automatikus szemétgyőjtés. de már nem használt memória felszabadítását végzi. Ha megpróbálnánk összegezni. így nyelvfüggetlen. a különbségeket. illetve a Basic nyelvekhez készítette el a dotNet-es fordítóprogramot. A memória felszabadításáról nem kell intézkednie. Ezt egy Garbage Collector nevő programrész végzi. és a különbözı nyelven megírt részek zökkenımentesen tudnak egymással kommunikálni. és nem hordozza magával a kompatibilitás megırzésének terhét. akik most ismerkedek a dotNet világával. Az új nyelv sok más nyelv jó tulajdonságait ötvözi.kihasználhatjuk az automatikus memória-menedzselés szolgáltatásait (Garbage Collector) 26/312 . Mivel mindkét nyelv fordítóprogramja a közös rendszerre fordítja le a saját forráskódját – így a fordítás során az eredeti forráskód nyelvi különbségei eltőnnek. A fenti két követelmény betartásának van egy nagyon érdekes következménye: elvileg lehetıség van arra. A dotNet nem épül egyetlen nyelvre sem rá. Egyik legismertebb. gondolván itt elsısorban a mikroprocesszorra . A CLS réteg fölött helyezkednek el a különbözı programozási nyelvek és a fordítóprogramjaik.az alkalmazás operációs rendszertıl független lesz . az alábbi fıbb szempontokat hozhatjuk fel: . hogy memóriát igényeljen. és a program által lefoglalt. Elvileg bármilyen programozási nyelven lehet dotNet-es programokat fejleszteni. és képes a CLR virtuális gépi kódjára fordítani a forráskódot. ha arra szüksége van. A Microsoft a C++. nemrégiben csatlakozott nyelv a Delphi. amely ismeri a CLS követelményeit. a másik felét pedig egy másikon. az automatikusan bekövetkezik. melyet C#-nak (ejtsd szí-sharp) nevezett el. A dotNet igazából nem kötött egyetlen programozási nyelvhez sem. amelyekhez létezik olyan fordítóprogram. hogy miért jó dotNet-ben programozni.nyelvekben ez nem ennyire kötött. Ez a szolgáltatás a memória-kezeléssel kapcsolatos. A fentieken túl van még egy olyan szolgáltatása a dotNet rendszernek.

-

felhasználhatjuk a programfejlesztéshez az eleve adott Base Class Library rendkívül széles szolgáltatás-rendszerét, ami radikálisan csökkenti a fejlesztési idıt

A dotNet keretrendszer (Microsoft.NET Framework) jelenleg ingyenesen letölthetı a Microsoft honlapjáról. A keretrendszer részét képezi a BCL, és a CLR réteg, valamint egy parancssori C# fordító. Ennek megfelelıen a dotNet programozási környezet ingyenesen hozzáférhetı minden programozást tanulni vágyó számára. Ami nem ingyenes, az a programozási felület (IDE = Integrated Development Environment – Integrált Fejlesztıi Környezet). A dotNet-ben a Microsoft által fejlesztett ilyen környezetet Microsoft Visual Studio.NET-nek nevezik. Ez nem csak egy színes szövegszerkesztı. Részét képezi egy 3 CD-t megtöltı súgó, mely tartalmazza a BCL leírását, példákkal illusztrálva. Az IDE nem csak a forráskód gyors áttekintésében segít a színekkel történı kiemeléssel (syntax highlight), hanem a program írás közben már folyamatosan elemzi a forráskódot, és azonnal megjelöli a hibás sorokat benne. Környezetérzékeny módon reagál a billentyők leütésére, és kiegészíti ill. javítja az éppen begépelés alatt álló kulcsszót. Ezen túl a felületbıl kilépés nélkül lehet a forráskódot lefordítani, és a generált programot elindítani. A Studio kényelmes módon kezeli a több file-ból álló programokat (project), illetve a több project-bıl álló programokat is (solution).

27/312

Programozás tankönyv

III. Fejezet

„Helló Világ!”

Hernyák Zoltán

28/312

Majd minden programozó ezzel a kedves kis programmal kezdi a programozástanulást: írjunk olyan számítógépes programot, amely kiírja a képernyıre, hogy „helló világ” (angolul: Hello World). Ezen program elhíresült példaprogram – ezzel kezdjük hát mi is ismerkedésünket ezzel a különös, néha kissé misztikus világgal.
class Sajat { static void Main() { System.Console.WriteLine("Hello Világ"); } }

A fenti példaprogramot készítsük el egy tetszıleges editor programmal (akár a jegyzettömb is megfelel) HelloVilag.CS néven, majd command prompt-ból fordítsuk le a kis programunkat: csc HelloVilag.cs parancs kiadása segítségével. A csc.exe – a C-Sharp compiler - a merevlemezen a Windows rendszerkönyvtárában, a C:\WINDOWS\Microsoft.NET\Framework\<version> alkönyvtárban található, ahol a <version> helyében a dotNET Framework verziószámát kell behelyettesíteni (például: v1.1.4322). Amennyiben a számítógép nem ismeri fel a csc programnevet, úgy vagy írjuk ki a teljes nevet, vagy vegyük fel a PATH-ba a fenti alkönyvtárat. A fenti parancs kiadása után ugyanazon alkönyvtárban, ahova a program szövegét is lementettük, elkészül egy HelloVilag.exe futtatható program is. Elindítva e kis programot, az kiírja a képernyıre a kívánt üdvözlı szöveget. Nos, ezen módja a programkészítésnek nagyon ’kıkorszaki’. Nézzük, milyen módon kell ezt csinálni a 21. században… Elsı lépésként indítsuk el a Microsoft Visual Studio.NET fejlesztıi környezetet, majd a File/New/Project menüpontot válasszuk ki:

1. ábra A felbukkanó párbeszédablak arra kíváncsi, milyen típusú program írását kívánjuk elkezdeni:

29/312

2. ábra A fenti párbeszédablak minden pontja roppant fontos! Elsı lépésként a bal felsı részen határozzuk meg, milyen nyelven kívánunk programozni (ez C#). Második lépésként adjuk meg, milyen típusú programot akarunk fejleszteni ezen a nyelven. Itt a sok lehetıség közül egyelıre a Console Application-t, a legegyszerőbb mőködési rendszerő programtípust választjuk ki. Harmadik lépésként a Location részben adjuk meg egy (már létezı) alkönyvtár nevét. Negyedik lépésben válasszuk ki a készülı program nevét a Name részben. Mivel e program több forrásszövegbıl fog majd állni, ezért a Studio külön alkönyvtárat fog neki készíteni. Ezen alkönyvtár neve a Location és a Name részbıl tevıdik össze, és a „Project will be created…” részben ki is van írva, jelen példában ez a C:\Programjaim\HelloVilag alkönyvtár lesz! Az OK nyomógombra kattintva rövid idın belül nagyon sok minden történik a háttérben. Ezt egy Windows Intézı indításával azonnal tapasztalhatjuk, ha megtekintjük a fenti alkönyvtár tartalmát. Több file is generálódott ebben az alkönyvtárban. De térjünk vissza a Studio-hoz!

30/312

using System; namespace HelloVilag { /// <summary> /// Summary description for Class1. /// </summary> class Class1 { /// <summary> /// The main entry point for the /// application. /// </summary> [STAThread] static void Main(string[] args) { // // TODO: Add code to start // application here // } } }

A generált program nagyon sok sorát kitörölhetnénk, és akit zavarnak a programban lévı felesleges programsorok azok tegyék is meg bátran (csak ne végezzenek félmunkát!). Mire figyeljünk? A programunk utasításokból áll. Egyelıre jegyezzük meg a következı fontos szabályt: minden programutasítást a Main függvény belsejébe kell írni! Sehova máshova! A Main függvény belsejét a Main utáni kezdı kapcsos zárójel és a záró kapcsos zárójel jelzi!

using System; namespace HelloVilag { class Class1 { static void Main(string[] args) { // ... // ide kell írnunk a program sorait // ... } } }

Koncentráljunk most a valódi problémára: a programnak ki kell írnia a képernyıre a Helló Világ szöveget! Vigyük a kurzort a Main függvény belsejébe, és a hiányzó sort (System.Console.WriteLine("Hello Világ");) gépeljük be.

31/312

using System; namespace HelloVilag { class Class1 { static void Main(string[] args) { System.Console.WriteLine("Hello Világ"); } } }

A kiíró utasítás neve WriteLine, mely az angol Write=írni, Line=sor szavakból tevıdik össze. A szöveget a konzolra kell írni (Console=karakteres képernyı). Ez egy, a rendszer (angol: System=rendszer) által eleve tartalmazott utasítás, ezért a parancs teljes neve System.Console.WriteLine. A kiírandó szöveget a parancs után gömbölyő zárójelbe kell írni, és dupla idézıjelek közé kell tenni. Az utasítás végét pontosvesszıvel kell lezárni (mint a ’pont’ a mondat végén). Az elkészült programot a File/Save All menüponttal mentsük le, majd indítsuk el. Ennek több módja is van. Az elsı: Debug/Start menüpont. Második: üssük le az F5 billentyőt. A harmadik: kattintsunk az indítás gombra, amelyet egy kis háromszög szimbolizál:

3. ábra Mivel a programindítás igen fontos, és sőrőn használt funkció, ezért javasoljuk, hogy jegyezzük meg az F5 billentyőt!

Máris van egy problémánk: a program elindul, rövid idıre felvillan egy fekete színő kis ablak, esetleg elolvashatjuk a kiírást, de csak ha elég gyorsak vagyunk, mert az ablak azonnal be is csukódik! Miért? A válasz: a program egyetlen utasítást tartalmaz: a szöveg kiírását. Mivel a program ezt már megtette, más dolga nincsen, ezért így a futása be is fejezıdik. És ha a program már nem fut, akkor bezáródik az ablak! A megoldás is erre fog épülni: adjunk még dolgot a programnak, hogy ne fejezıdjön be azonnal! Elsı módszer: utasítsuk arra, hogy várjon valamennyi idı elteltére. A szóban forgó utasítás:
System.Threading.Thread.Sleep(1000);

32/312

} Indítsuk el a programot. de a következı utasítást majd csak egy másodperc letelte után fogja végrehajtani a számítógép! Lényeges. System. System.Thread. hogy hova írjuk ezt a sort! A szabály értelmében a Main függvény belsejébe kell írni.Thread.Sleep(1000).Threading.WriteLine("Hello Világ"). és azonnal bezáródik az ablak.WriteLine("Hello Világ"). Miért? A számítógép a program sorait nem akármilyen sorrendben hajtja végre. kis ideig nem történik semmi. } A kiírt szöveg megjelenik. majd bezáródik az ablak.Threading.Sleep(1000). hogy a program jelen esetben 1 másodpercre ’elalszik’. A megadott érték (1000) éppen 1 másodpercnyi várakozást jelent. De milyen sorrendben? A programozás tanulás legjobb módszere a próbálkozás! Próbáljuk meg a kiírás elé beírni! static void Main(string[] args) { System. Ezt azt elvet késıbb pontosítjuk. Program elindul (ablak megnyílik) ↓ WriteLine végrehajtása (a szöveg kiíródik a képernyıre) ↓ Sleep végrehajtása (a program vár 1 másodpercet) ↓ Program befejezıdik (az ablak bezáródik) 33/312 . Próbáljuk meg fordított sorrendben: static void Main(string[] args) { System.Ezen utasításnak zárójelben (paraméterként) ezredmásodpercben kell megadni a várakozás idejét. e közben nem történik semmi (még csak nem is álmodik). Van egy nagyon fontos szabály: az utasításokat ugyanabban a sorrendben kell végrehajtani.Console. A Sleep=aludni jelentése konkrétan annyi. eltelik egy kis idı (1 másodperc). majd felvillan a kiírás.Console. és gondolkozzunk el a látottakon: a kis ablak elıbukkan. és elnevezzük szekvencia-elvnek. amilyen sorrendben a programozó leírta azokat.

ezért a ReadLine mindaddig nem fejezıdik be. Nos. hogy a program ablaka létrejött. Az adatbevitelt az Enter leütésével jelezzük. ha adatot kérünk be a billentyőzetrıl. de sajnos az Enter leütése elıtt lehetıségünk van bármilyen szöveget begépelni. Mit tapasztalunk? Hogy az ablak nem akar bezáródni! Üssük le az Enter billentyőt – és ekkor az ablak bezáródik. ez az utasítás végrehajtása tehát már befejezıdött! Ekkor csak a ReadLine utasítás maradt. Ez az utolsó pillanat.Console. hogy kiíródott a szöveg a képernyıre. Kerüljünk közelebbi kapcsolatba a programmal. azért nem záródott be! Mivel most összesen két utasításunk van (a WriteLine. amíg le nem ütjük az Enter-t. A Sleep-es sort cseréljük le a fenti sorra.Persze felmerül a kérdés. mert bár a ReadLine ellátja a feladatát. Próbáljuk elindítani a programot. melyik utasítás miatt nem fejezıdött be a program? Az nem lehet a WriteLine. de még egyelıre üres. amit használni fogunk. Egy másodpercig nem történik semmi (a program ’elalszik’). Üssük le újra az F11 billentyőt. Mi történt? Az ablak akkor záródik be. Közben láthatjuk. és a programozással! Figyeljük meg lépésrıl lépésre a mőködést! Ehhez ne az F5 billentyővel indítsuk el a programot. Néha több idıt kellene várni. amikor még ellenırizhetjük a program kiírásait a fekete hátterő ablakban. a ReadLine utasítást alapvetıen akkor használjuk majd. mert a szöveg már kiíródott a képernyıre.ReadLine(). Üssük le újra az F11 billentyőt! A sárga kiemelı csík átlépett a Sleep sorára. majd újra felbukkan a sárga kiemelés a Main függvény blokkjának záró kapcsos zárójelén. néha kevesebbet. hanem az F11 billentyővel (vagy a Debug/Step into menüponttal): 4. De egyelıre ez a módszer lesz az. Újabb F11 leütésére a program végképp befejezıdik. De mennyire? Ez a megoldás nem elég rugalmas. ábra A sárga (szürke) kiemelés a következı végrehajtandó utasítást jelöli. s ez elrontja a dolog szépségét. Ezt azt jelenti. az ablak bezáródik. hogy 1 mp elég-e? Növelhetjük az idıt persze az érték átállításával. amikor a program futása befejezıdik. és a ReadLine). Keressünk más megoldást: System. 34/312 . Ezek szerint a program még futott. Megjegyzés: a megoldás azért nem tökéletes. hogy a WriteLine végrehajtásra került? Ellenırizzük! A programablakra kattintva láthatjuk.

mit is akarunk tıle: 5. hogy miért nem az történik. Késıbb újabb módszerekkel és technikákkal bıvíthetjük ez irányú tudásunkat. Ennek oka az. vagy a Shift-F5 leütésével. vagy a Continue lenyomásával dönthetünk úgy is. hogy ha már elkezdtük a programot futtatni lépésenként. hogy ha pl. és a közben bekövetkezett változásokat nem fogja figyelembe venni. Ha ez mégis elıfordulna. vagy csak nem értjük annak mőködését teljes mértékben. hogy amikor elkezdtük a programot futtatni (az elsı F11 leütésével). Ez azért nagy gond. ábra A szöveg fordítása: „A forráskód megváltozása nem fog jelentkezni a program futásában. a Studio rögzítette az állapotot (a forráskód akkori tartamát). 35/312 .” Ez azt jelenti. akkor is még az eredeti „Helló Világ” fog kiíródni. ha végrehajtjuk a következı lépést! A Restart lenyomásával leállíthatjuk a program futtatását. ha a program nem úgy mőködik. és esetleg nem értjük. a Studio nem fogja tudni. A program futtatását egyébként bármikor megszakíthatjuk a Debug/Stop debugging menüponttal.Nagyon ügyeljünk. és folytatjuk a program futtatását. ahogyan azt szeretnénk. E módszert nyomkövetésnek hívjuk (angolul debugging). Ha folytatja a futtatást. amíg azt újra nem indítja. a forráskód és a futó program nem fog megegyezni. akkor ne módosítsuk a program szövegét (ez fıként akkor fordul elı. átírjuk a szöveget „Helló Világ!”-ról „Helló Mindenki”-re. A fenti módszert fıként akkor használjuk. ha véletlenül leütünk valamilyen billentyőt). hogy a változás ellenére folytatjuk az eredeti program futtatását. amit látunk. mert mi a forráskódban a már megváltozott szöveget látjuk. jelen esetben lépésenkénti programvégrehajtást végzünk.

pl. 36/312 .Feladatok: 1. Programozási feladat: Írassuk ki a képernyıre a családfánk egy részét. *** Sleep *** Várakozik a megadott idıig. és rövid leírásukat. pl. az alábbi formában: Kis Pál (felesége: Nagy Borbála) Kis József Kis Aladár (felesége: Piros Éva) Kis István Kis Pál 2. Programozási feladat: Írassuk ki a képernyıre az eddig megismert C# parancsokat. az alábbi formában: *** WriteLine *** Kiír egy szöveget a képernyıre. *** ReadLine *** Vár egy ENTER leütésére.

Programozás tankönyv IV. Fejezet „Alap I/O” Király Roland 37/312 .

Ezt a folyamatot deklarációnak nevezzük. Ezeken kívül rendelkezik élettartammal és hatáskörrel. hogy a program mely részeiben használható. és tartalma. Minden változónak van neve. Az alábbiakban megvizsgálunk néhány példát a helyes és helytelen névadásokra: Valtozo valtozo Valtozónév szemely_2_neve int alma#fa 10szemely Az elsı négy névadás helyes. hogy adatokat olvasunk be a billentyőzetrıl. és segítségükkel kommunikál a felhasználóval. Az utolsó elnevezés számmal kezdıdik. 38/312 . Az élettartam azt jelenti. a változó típusok ismerete nagyon fontos. mely szintén hibás. bármely programozási nyelvet szeretnénk elsajátítani. Vegyük észre. hogy az adott változó a program futása során mikor és meddig.Az alapvetı Input/Output Az alapvetı input. A kommunikáció a programozási nyelvek esetében körülbelül azt jelenti. vagyis a Konzol alkalmazások ki. mivel a programban használt adatokat változókban és konstansokban tudjuk tárolni. Az ötödik névben a # karakter szerepel. mivel a C# nyelv érzékeny a kis-nagybetők különbségére. vagyis aktuális értéke. valtozo_nev tipus. A program ezekkel számol. A változók névének kiválasztása során ügyelnünk kell a nyelv szintaktikai szabályainak betartására.és bemenetének tárgyaláshoz elsıként meg kell ismernünk néhány C#-ban használatos változó típust.output. vagyis közöljük a fordító rendszerrel.sensitive nyelvnek nevezi. hogy a valtozo és a Valtozo azonosítók két külön változót jelölnek. A változók. típusa. vagy más néven azonosítója. A negyedik elnevezés helytelen. Az angol terminológia ezt Case. s a munka végeztével a kapott eredményt kiírjuk a képernyıre. hogy milyen nével milyen típusú változót kívánunk használni a programban. ami nem használható. a hatókör azt adja. A változókat a programban bevezetjük. mivel az int foglalt kulcsszó.

mivel a . egyszerő típust! típus byte int Méret 1 byte 4 byte Értéktartomány 0 tól 255 ig -2. vagyis minden azonosítóhoz hozzárendeljük a memória egy szeletét. valamivel bonyolultabb a helyzet. de a .NET felügyeli. mert az érték nélkül használt változók kifejezésekben való szerepeltetése esetén a fordító hibát jelez. string s.647 ig float 4 byte ±1.147. és milyen más típusokkal kompatibilis. A kezdıérték adása azért is fontos.NET rendszerben nem kell törıdnünk a memória kezelésével.147. a névvel pedig a változóra hivatkozhatunk. false értékek Unicode karakterek Karakterláncok decimal 16 byte ±1.5 × 10− ±3. char ékezetes_bető. lefoglalja és felszabadítja a memóriát. char c.) Vizsgáljunk meg néhány. a C# nyelvben használatos.0 × 10−28 ±7.A típus határozza meg a változó lehetséges értékeit.0 × 10− ±1.483.483. mint a pointerek. A változóinkat kezdıértékkel is elláthatjuk. 39/312 . int egész. milyen mőveleteket lehet értelmezni rajta. Inkompatibilitás esetén a . mikor az egyik változót értékül akarjuk adni egy másiknak.648 2. (Néhány változó típus esetén.NET fordító hibát jelez. A kompatibilitás akkor fontos. int i. hogy. A változók a memóriában tárolódnak. értéktartományait. illetve azt.7 × 10 324 308 ig tól Valós(lebegıpontos) számok ig True. Más nyelvektıl eltérıen a C#-ban az ékezetes betőket is használhatjuk névadásra. Az alábbi példa bemutatja a deklaráció pontos szintaktikáját. melyet a rendszer lefoglalva tart a változó teljes életciklusa alatt.9 × 10 28 bool char string 1 byte 2 byte - true/false U+0000 tól U+ffff ig A táblázatban felsorolt típusokkal deklarálhatunk változókat.4 × 10 double 8 byte 45 A típusban tárolható adatok Elıjel nélküli egész számok tıl elıjeles egész számok tıl Valós(lebegıpontos) számok ig töl Valós(lebegıpontos) számok 38 ±5.

Bizonyos esetekben. vagyis a class neve megegyezik valamely változó nevével. 40/312 .b=1. namespace deklaracio { class valtozok_ { [STAThread] static void Main(string[] args) { int r=0.int k=0. hogy nem megfelelı típusú kezdı értékkel látjuk el a változókat. Gyakori hiba az is. char ch. float h.c=0. hogy a deklaráció során nem adunk nevet vagy típust a változónak.NET fordító a futtatáskor hibát jelez. string s1.Cannot implicitly convert type 'int' to 'string' Azonos változónevek esetén is hibaüzenetet kapunk. hogyan lehet a változókat deklarálni.l. Elıfordul. vagy egyáltalán nem deklaráljuk. int a=0. A képernyın nem jelenik meg semmi. Ekkor a .Cannot implicitly convert type 'string' to 'int' . char cr='a'. hanem Warning típusú hibaüzenetet kapunk. Ilyen hiba lehet. bool ba. ha egy változót deklarálunk. amitıl az még mőködıképes. Ebben az esetben a következı hibaüzenetek jelenhetnek meg a képernyın: . Ezeket a fejezet késıbbi részeiben tárgyaljuk. a fordító olyan hibát talál a programunkban. esetleg lefoglalt kulcsszót akarunk alkalmazni a névadásnál. string z=”alma”. } } } Gyakran elıforduló hiba. A következı program bemutatja. hogy az osztály. string s2="Hello!". de a programban próbálunk hivatkozni rá. és kezdıértékkel ellátni. de hatékonyságát csökkenti. float f. mivel kiíró és beolvasó utasításokat nem használunk. int k=a+10. amikor nem Error. char c=’a’. int d=a+b. bool bo=true. de nem használunk fel.

f=false.) int a="alma". ügyelnünk kell a programkód helyességére. vagy a változóra vonatkozó következı értékadásig meg is tartanak. a jobb oldalon pedig az érték. string s. string s="ez egy string konstans". hogy lehetıvé tegyük a program használójának a változók értékének manipulálását. vagy kifejezés. a class foglalt szó int void=10. Amennyiben ezt tesszük. namespace AlapIO { class IO_ { int a. c. t. int d=10. Az értékadó utasítás bal oldalán a változó azonosítója áll. és az értéküket nem tudja módosítani. bool t. Ahhoz. int a = 12. int b = a + 10. b. értékkel rendelkeznek. az int típus nem kompatibilis a string konstanssal string f=2. A felhasználó még mindig nem láthatja ıket. hogy a programjaink mely részeiben deklarálhatunk. a void az eljárásoknál használatos cimke A következı példa megmutatja. középen egyenlıség jel. bool t = true. 41/312 .A következı példában láthatunk néhány rossz deklarációt. char c. (. Az értékadásnak jól meghatározott szintaktikája van.b. using System. f) a programunk futása közben használhatóak. [STAThread] static void Main(string[] args) { int l. d.0. melyet a program futása alatt. melynek az aktuális értékét a változóban tárolni szeretnénk. int y = (int)3.hogy a programozás során ne kövessünk el hasonló hibákat. az s változóba számot akarunk elhelyezni int class=10. } } } A fenti változók (a. nekünk kell a megfelelı utasításokat beépíteni a forráskódba. bool f = !t. az értékadások után tartalommal. char c = 'a'.

Console. a System névtérben található Console osztály ide tartozó metódusait (függvények és eljárások). A literálok alapértelmezés szerint int típusúak. a . Adatokat kell kérni tıle. A változók egy érdekes típusa a literál. ha egészek.NET rendszerben igénybe vehetjük a C# alapvetı I/O szolgáltatásait.int d=2. míg a Console.Console. Más nyelvektıl eltérıen. hogy az adatokat. System. A C# programokban állandókat. Akkor használjuk. és double. max_Db = 20. Ahhoz. vagy közölnünk kell. Ez egy ún. s nem lehet felüldefiniálni ıket. A beolvasás azt jelenti.0. ha valósak. A programjainknak fontos része a felhasználóval való kommunikáció. k=(10+4)/2. vagy más néven konstansokat is definiálhatunk. A példában az y változónak egy valós típust adunk értékül.Console. Float_literal = 4. A helytelenül felírt értékadást a fordító hibaüzenettel jelzi.Write() és a Console. c=a+40. long típus esetén az l.WriteLine() a kiírásra.: explicit konverzió. illetve ulong esetén az ul karakterpárt. stb.0 típus kényszerítéssel nem okozunk hibát. hogy az ún. A Console. pl. de ebben az esetben az (int)3. const string s=”string típusú konstans”.Read(). const int a=10. int y = (int)3. A konstansok a program futása alatt megırzik értéküket. mikor a programban egy konkrét értéket szeretnénk szerepeltetni. mi volt a program futásának eredménye.ReadLine(). illetve értékadó utasítással megváltoztatni értéküket.: standard input stream –rıl 42/312 .ReadLine() a beolvasásra használható.Console. System.WriteLine(). az érték után kell írni az f karaktert. vagyis a változók tartalmát be tudjuk olvasni vagy meg tudjuk jeleníteni a képernyın.Write(). Amennyiben float típust szeretnénk készíteni. itt a konstansnak is van típusa. Long_literal = 4l. System.Read() és a Console.5f. System.: hibauzenet_1 = ”Helytelen Értékadás”.

Amennyiben a Read() beolvasó utasítást használjuk.ToInt32(Console. ezért az input adatokat konvertálnunk kell a megfelelı konverziós eljárásokkal.: System. hanem valamennyi névtérre igaz.QueueUserWorkItem(). Jól látszik.a+b). public static string ReadLine(). amelyeket a fordító nem biztos. akkor az adott metódus teljes. int típusú adatot kapunk. Ez nem csak a System -re. Ez kiderül.:System. késıbb még visszatérünk rá) Ahhoz. Ez a minısítı elıtag (pl. (a többszálú programok készítésénél van jelentısége.Thread. 43/312 . Ezt a mőveletet névtér importálásnak nevezzük és a könyv késıbbi fejezeteiben bıvebben olvashatunk a témáról. a ReadLine() viszont string. a using bejegyzés után felvesszük a következı módon: using System. a=Convert. vagy q nevérıl beszélünk.Write("a erteke : ").Console…).ReadLine()). a ReadLine() metódus esetében viszont stringet. melyekre késıbb bıvebben kitérünk. minısített.a. hogy a Read() int típusú.b. Console. namespace ConsoleApplication7 { class Class1 { [STAThread] static void Main(string[] args) { int a=0.ToInt32(Console. Mikor eltekintünk a névtér importálástól.Threadpool. hogy használni tudjuk a Consol metódusait. A System hivatkozás elhagyható a metódusok hívásakor. public static int Read(). ami a függvény névtérben elfoglalt helyével kezdıdik.b=0.várunk adatokat. Erre szükség is lehet. ha megnézzük a két metódus prototípusát. meg kell vizsgálnunk néhány példát. mivel a System névtér is több fájlból (DLL) ál. hogy megtalál a hivatkozás nélkül. b=Convert.ReadLine()).Write("b erteke : "). így a program bármely részébıl meghívhatjuk az adott függvényt. Pl. vagy eljárást. using System. Console. Adat beolvasásakor természetesen nem csak erre a két típusra van szükségünk. amennyiben azt a program elején. Console. A következı program bemutatja a beolvasás és a kiírás mechanizmusát.WriteLine("\n a={0}\n b={1}\n a+b={2}".

Console. és így tovább. vagyis a számunkra megfelelı alakban tudjuk megjeleníteni.ReadLine(). hogy a {.WriteLine(”{{0}} = {0}”. mivel a formátum definiálja. vagyis a képernyıre tudunk írni. Console. A formátum string tartalmaz konstans részeket (a=.Console. vagyis a sorban az elsı változó helyét. }. a+b=) ami változatlan formában kerül a képernyıre. } } } Amennyiben futtatjuk a programot a képernyın a következı output (kimenet) jelenik meg: A System. {2} bejegyzéseket arra használjuk. A kedves olvasó kipróbálhatja a 44/312 . mely a nulladik helyen áll. a {1} a második változó helyét. A metódusban ún.a). Console.WriteLine() paraméter listájában a változók fel vannak cserélve. mivel csak így tudjuk a változók tartalmát a képernyıre írni. de ilyenek nem léteznek. a változók helyét a kiírt szövegben.ra. {1}. (Érdekes kérdés lehet. A példában az elsı és a harmadik változóra hivatkoztunk (sorrendben a második és a negyedik).et. Ezek a bejegyzések nem hagyhatóak el.: formátum string . A sorrendjük sem mindegy. {0} karaktereket hogyan írjuk a képernyıre. mivel az egyetlen változó a kiíró utasításban az i. vagy más néven maszkot alkalmaztunk. Amennyiben a {} zárójelek között olyan értéket adunk meg. a kiírási sorrend mégis megfelelı. pontosabban a képernyın megjelenı Consol alkalmazás ablakába. hogy a változók értékeit formázottan.WriteLine("{0}".WriteLine("{1} {3}". hogy a formátum string megfelelı pontjaira behelyettesítsük a paraméterlistában felsorolt változók értékeit: a {0} jelenti a nulladik. hogy a példaprogramban a második Console. A {0}. Vegyük észre. utasítást…) A formátum maszkjába a következı vezérlı karaktereket helyezhetjük el: A Console.i).WriteLine() metódussal a standard output .i). mely nem létezı változóra hivatkozik. A helyes hivatkozás tehát: Console.a). a program leáll. nem megfelelı.WriteLine(”{} {0} = {0}”. b=.

a. s azok összegét is.WriteLine("\n a={0}\n b={1}\n a+b={2}".Write("b erteke : "). Console. Console. nemcsak int és string típusú adatokat. s ha megtámogatjuk a két metódust a Convert osztály konverziós függvényeivel.ToInt32(Console.Read() . vagy logikai értékeket is beolvashatunk a felhasználótól. vagyis a billentyőzetrıl bevitt adatokat.Write("a erteke : "). b=Convert.a+b). hogyan kezelhetjük le a felhasználótól érkezı inputot.és a Console. hogy tovább tudjunk lépni. de nem ad lehetıséget felhasználónak a változók értékének a megváltoztatására.ReadLine()). A felhasználói input kezelésére lehetıséget biztosítanak a Console. hanem szám típusú.b=0. el kell sajátítanunk.b. vagyis a billentyőzetrıl.\b \* \t \\ \’ \” \n Backspace Újsor vízszintes tabulátor Fordított perjel Aposztróf Idézıjel Sortörés Vegyük észre. A program végén a 45/312 . Ahhoz. Console. hogy a programunk megjeleníti a tárolt értékeket. Console.ReadLine().ReadLine() metódusok.ReadLine()). mely nem konvertálható. Mindkettı esetében adatokat olvashatunk be a standard inputról. a programunk leáll. Ha a beolvasás során az input stream –rıl hibás adatot kapunk. namespace ConsoleApplication7 { class Class1 { [STAThread] static void Main(string[] args) { int a=0. Az ilyen jellegő hibákra megoldás lehet a kivételek kezelése.ToInt32(Console. így a beolvasott adatok változtatásával minden lefutásnál más-más eredményt kapunk. Nézzünk meg a példát a beolvasásra és a konverzióra! using System. A példaprogramban a Convert. } } } Ebben az alkalmazásban a változók a felhasználói inputról nyernek értéket. melyrıl a késıbbi fejezetekben szót ejtünk majd. a=Convert.ToInt32() metódust használjuk az input 32-bites int típussá konvertálására.

ReadLine() utasítást arra használjuk. A b változóval ugyanígy járunk el. miután a program lefutott. Ez fontos a Consol alkalmazások esetén. végrehajtják a programozó által definiált utasításokat. hogy a változók milyen módon kaphatnak értéket! Egyszerő értékadással: A=2.ReadLine(). majd azt konvertáljuk egész számmá (int).Console. A standard inputról: A=Convert. és legtöbbször ez is a célunk. hogy a Consol ablak ne tőnjön el a képernyırıl. Nézzük meg a forráskódot! 46/312 . s adjuk értékül az a változónak. B=Console. ha ez a feltétel nem teljesül. megnézzük. A Convert osztály ToInt32() metódusával alakítjuk a beolvasott. és jól bemutatja a billentyőzetrıl nyert adatok egész számmá konvertálását. E=2*A. és a kimeneti képernyıt is bezárják. hogy melyik a nagyobb. majd az eredményt kiírjuk a képernyıre.ToInt32(Console. C=A+B. Kezdıérték adásával: int D=10. A fentiek ismeretében vegyük sorra. Ez a program viszonylag egyszerő. ha nem kezdünk velük semmit? A következı program két változó értékérıl eldönti. A beolvasást követıen megvizsgáljuk. char c=”a” A változókba beolvasott értékeket fel is tudjuk használni. majd leállnak. hogy melyik változó értéke a nagyobb. B=”alma”. itt még String típusként szereplı számot. A programok elindulnak.ReadLine()). Így a felhasználó nem lát szinte semmit az egészbıl. Miért is olvasnánk be értékeket. mivel ezek nem esemény vezérelt mőködésőek. hogy a számok egyenlık-e.

Biztosan sokan emlékeznek a következı párbeszédre: . ha összefüggı szöveg formájában beszélgetünk. .b. b=Convert.ReadLine().ToInt32(Console. így foglalva mondatba a program futásának eredményét.Write("b értéke? = ").ToInt32(Console. hogy jobban megértsenek minket.Mi mennyi? 47/312 . a=Convert.b).a. } } Console.WriteLine("{0} a nagyobb mint {1}". A program használhatóságát növeli.ReadLine()). namespace Convert { class KN { [STAThread] static void Main(string[] args) { int a=0.Harminc. Console.WriteLine("{0} és {1} egyenlıek".using System.ReadLine()). } } } Az alkalmazás kimenetére kerek mondat formájában írjuk ki az eredményt úgy.WriteLine("{0} a nagyobb mint {1}".Write("a értéke? = ").a).a. Mindenképpen jobb. hogy a kiírt string konstanst konkatenáljuk a változók értékével. A hétköznapi kommunikáció során is jobb. ha kerek mondatokat használunk.Mennyi? . } else { if (a>b) { Console.b=0. vagyis felhasználóbarát programokat készíthetünk. Console. } else { Console. Ez gyakori megoldás a felhasználóval történı kommunikáció megvalósítására. if (a==b) { Console.Mi harminc? .b).

x /= 2.Az ilyen és hasonló párbeszédek érthetetlenné teszik a kommunikációt mind a valós életben. bináris és ternáris mőveletek. x *= 2. (egész osztás) x = x % 2. feltételes mőveletek. Az elnevezések arra utalnak. Honnan vegyük a pí-t? Írhatnánk egyszerően azt. majd kiszámítja annak kerületét és területét. hogy elegendı tudással rendelkezünk a Consol I/O parancsairól és a mőveletek használatáról. Jelentés x = x + 2. és azt. hogy egy változóba beolvassuk az adott kör sugarát. (maradékos osztás) Most. x = x – 2. A programhoz szükséges ismeretek: a kör kerülete: 2r*∏. A mőveleteket csoportosíthatjuk a következı módon: • • • • Értékadás: a = 2.14. tanuljuk meg a másodikban is! A kiíratás és beolvasás mellett a mőveletvégzés is fontos része a programoknak. a < c. összehasonlítások: a = = b. A mőveleti jelek alapján három kategóriát hozhatunk létre. Használjuk inkább a C# math osztályban definiált PI konstanst! Ekkor a program a következı módon írható le: 48/312 . Unáris. x -= 2. és a pí értékét behelyettesítenünk a képletekbe. és a területe: r*r*∏. A feladat az. Az aritmetikai értékadásokat rövid formában is írhatjuk. x %= 2. rövid forma += -= *= /= %= Használat x += 2. x = x / 2. készítsünk programot. hogy a mőveletben hány operandus szerepel. hogy 3. A következı táblázat bemutatja a rövidítések használatát. Az elsıben már egész jól megtanultuk a társas érintkezés formáit. vagy r2*∏. csak a megfelelı formátum string-et kell elkészítenünk. x = x * 2. hogy a rövidített formulák mivel egyenértékőek. de ebben az esetben nem lenne elég pontos a számításunk eredménye. majd a képernyıre írjuk a körhöz tartozó kerületet és a területet. A kifejezések kiszámítását elvégezhetjük a kiíró utasításban is. mely a felhasználótól bekéri egy tetszıleges kör sugarát. matematikai mőveletek: z = a + b. mind a programok világában.

A legtöbb alkalmazásban szükség van a típusok közti konverzióra. Logikai true értéket kapunk eredményül. Console. r=Convert.ReadLine()).r*r*Math.WriteLine("A kör kerülete : {0}. Az eredmény kiíródik a képernyıre. A fejezetben már szóltunk a típusok konverziójáról. hogyan mőködik a program! Az r változóban tároljuk a billentyőzetrıl beolvasott értéket.WriteLine("kör sugara : ").2*r*Math. s a program az enter leütése után befejezi futását. Console. a kör sugarát. de a teljesség kedvéért vegyük sorra a fontosabb metódusait! Az alábbi felsorolás tartalmazza azokat a konvertáló metódusokat. } } } Vizsgáljuk meg. Az egész típusú számokkal már jól boldogulunk.ToInt32(Console.ToBoolean(Console.ReadLine().WriteLine("{0}". területe : {1} ". 49/312 . majd a Console. Console.ReadLine()). de sajnos az élet nem ilyen egyszerő. Console.WriteLine() – metódusban kiszámoljuk a megadott kifejezés alapján a kör kerületét és területét.using System. Bool b=Convert. namespace ConsoleApplication7 { class Class1 { [STAThread] static void Main(string[] args) { int r=0.PI. és a Convert osztályról.PI).Convert. Nullánál false visszatérési értéket kapnánk.ToBoolean(1)). melyeket az alapvetı I/O alkalmazása során használni fogunk: ToBoolean() ToByte() ToChar() ToString() ToInt32() ToDateTime() A ToBoolean() metódus logikai értékkel tér vissza.

23).Convert. Egy bájtnál nagyobb érték nem fér el a byte típusban. A példában a számjegy ASCII kódját toltuk el annyival. de ez a fenti kiíró utasításban nem követhetı nyomon. 50/312 .ReadLine()). mivel string típust készítettünk belıle. átalakíthatjuk a következı módon: Convert. string s=Convert.WriteLine("{0}".…. Amennyiben a ToChar() bemenı paramétere a 11+55 lenne.15=F.A ToByte() metódus byte típust ad vissza. mivel a kilences számrendszertıl fölfelé történı konvertáláskor a 9-nél nagyobb számok esetén az ABC nagy betőit használjuk.ToString(1. Console.ToByte(1)).ToInt32(Console. mint 9. A ToChar() metódus a karakter ASCII kódjával tér vissza. Eredménye az 1.23-al nem végezhetünk aritmetikai mőveletet.WriteLine("{0}". 11=B.s). mivel a kiírt érték byte típusban is 1.Convert. 10=A. A ToString() string-et konvertál a bemenı paraméterbıl. Nagyobb szám konvertálása hibához vezet. A kódot ezután karakterré konvertáltuk. Az átváltáskor. viszont az értéktartomány megváltozik. A következı programrészlet a fent említett eljárás használatával a 10 szám helyett egy A betőt ír a képernyıre.WriteLine("{0}". Console. A ToInt32() metódust már használtuk az elızı programokban. ha az adott számjegy nagyobb. de alkalmas string-ekhez való hozzáfőzésre.ToChar(10+55)).ToChar(szamjegy+55). hogy az megegyezzen a megfelelı tizenhatos számrendszerbeli számjegy ASCII kódjával. int a=Convert.23 szám string-ként. Konvertálás után 1. Console. de álljon itt is egy példa a használatára. Ez a metódus jól használható a számrendszerek közti átváltások programozására. a B bető jelene meg a képernyın.

hogy ToDateTime() paraméterében megadott string-ben az aktuális idıt is fel tudjuk venni a következı módon: Console. ami alapértelmezésként 0:00:00. A fenti programrészlet futásának az eredménye a következı: Látható.ToChar(1). vagy típus konverzió esetén is használhatjuk. Másik lehetıség a konverzióra az i=Int32. de ha dátum típusként tárolt adattal szeretnénk összehasonlítani azt. Console.ToInt32(c). bool b=Convert.ToInt32('1'). de a metódusokat változók értékének a beállításakor. akkor használnunk kell a ToDateTime() függvényt. hogy a dátum mellett az aktuális idı is megjelenik. mivel a dátum típussal még nem foglalkoztunk. Természetesen a C# -ban sokkal több konverziós metódus létezik.A kódrészletben az int típusú változóba a billentyőzetrıl olvasunk be értéket.ToBoolean(1).ToDateTime("2004/12/21")). Elıfordulnak programok. k=2+Convert.NET dinamikus HELP rendszerét!) A példákban a konvertálást a kiíró utasítással kombináltuk.Convert. vagy adatbázisban tárolni. Ennek a kódrészletnek az eredményeként a dátum mellett az idı is kiíródik a képernyıre. Ebbıl következik. A Console.WriteLine("dátum :{0}". Amennyiben ki akarjuk íratni a képernyıre amit beolvastunk. char c=Convert. így a beolvasott érték egész típusú számként (int) kerül a memóriába. hogy az eredmény megjelenjen a képernyın. (Amennyiben a többire is kíváncsiak vagyunk.Convert. forma használata.Parse(Console. nincs szükség konverzióra. string s=Convert. A felsorolás végére hagytuk a ToDateTime() metódust.ToInt32() függvénynek.23). int k=Convert.ToDateTime("2004/12/21 1:10:10")). vagy éppen az aktuális dátumot szeretnénk megkérdezni.ToString(1.WriteLine("datum + idı : {0} ".ReadLine()). de a programjaink megírásához a felsoroltak elegendıek. A két megoldás azonos eredményt szolgáltat.ReadLine() metódust ”paraméterként” átadjuk a Convert. használjuk a . 51/312 . ahol a felhasználótól a születési dátumát.

(Egyszerőbb programok esetén elég. mivel az int típust olvas be. hogy a programozás folyamata nem a fejlesztıi eszköz kód editorában kezdıdik. de nem merítette ki. Nem szerencsés a logikai értékek beolvasásakor a Read() metódust használni. A tervek leírása sok esetben már a program vázlatát adja. Ez kicsit eltér a fent bemutatott bool b=Convert. Elsıként fel kell vázolni a születendı programok mőködését. A teljes körő megismeréshez mindenképpen fontos a következı fejezet tanulmányozása. A szintaktika mellett fontos megemlíteni. meg kell keresni a lehetséges matematikai megoldásokat (persze. vagyis a feltételes elágazások témakörét ez a fejezet is érintette. ha a felhasználói igényeket papírra vetjük ☺. A következı fejezetben a szelekcióval ismerkedünk meg.) A tervezés. 52/312 . A megfelelıen átgondolt.ToBoolean(Console. megtervezett programok elkészítése a késıbbiekben felgyorsítja a programozási folyamatot. b=Convert. A standard Input/Output kezelésének alapjait elsajátítottuk. elıkészítés lépésekeit soha nem szabad kihagyni.Logikai érték esetén a beolvasás a következı módon oldható meg: bool b.ToBoolean(1). A szelekció.ReadLine()). értékadástól. csak ha erre szükség van). tervezni kell. egyszerőbbé teszi a hibák keresését. A beolvasásnál az 1 érték nem megfelelı. javítását. Ennél a programrészletnél a true szót kell begépelni a billentyőzeten.

mely megkérdezi a felhasználó nevét. majd kiírja a két szám számtani közepét! 53/312 . Készítsen programot. hogy a háromszög szerkeszthetı-e! (A háromszög szerkeszthetı. hogy az ne egy kör. majd köszön neki. majd megmondja. de úgy. ha az (a+b>c) és (a+c>b) és (b+c>a) feltétel teljesül. majd írja ki azok összegét. Kérjen be a billentyőzetrıl két számot.Programozási feladatok 1. Írjon programot. mely egy háromszög oldalainak hosszát olvassa be a billentyőzetrıl.) 5. Az elızı programot módosítsa úgy.: Hello Kiss Attila!) 2. hanem egy négyzet kerületét és területét számítsa ki! 3. hogy téglalapok kerületét. hogy a szám negatív. Írjon programot. vagy pozitív! 6. Próbálja meg átalakítani a fejezetben tárgyalt.) 4. mely beolvas egy számpárt a billentyőzetrıl. szorzatát és hányadosát a képernyıre! 7. Írjon programot. területét is ki tudja számítani! (Szükség lesz újabb változó bevezetésére. a kör kerületét és területét kiszámító programunkat úgy. Olvasson be a billentyőzetrıl egy számot és mondjuk meg. mely logikai true/false értékeket olvas be a billentyőzetrıl! True esetén a képernyıre az IGAZ szót írja ki a program! 8. hogy a nevén szólítja! (Pl. különbségét.

Fejezet „Szelekció alapszint” Radványi Tibor 54/312 .Programozás tankönyv V.

Logikai kifejezéseket logikai operátorokkal köthetünk össze.WriteLine("{0}". a TRUE és a FALSE.logikai). Két kompatibilis érték összehasonlításának eredménye vagy igaz (true) vagy hamis (false) lesz. int sz = 2. Ezek az értékek konstansként is megadhatók: bool logikai = true. Például ha Sz változó int típusú. VAGY A TRUE B TRUE A || B TRUE 55/312 . vagy hamis. illetve a logikai vagy operátorok. hogy mi a változó pillanatnyi értéke. Ezek a tagadás. Console. ha mindkét paraméter értéke igaz. vagyis igaz.A logikai típusú változó A logikai típusú változónak két lehetséges értéke van. ÉS A TRUE FALSE TRUE FALSE B TRUE TRUE FALSE FALSE A && B TRUE FALSE FALSE FALSE Azaz kizárólag akkor lesz a mővelet eredménye igaz. akkor az Sz < 4 kifejezés értéke lehet igaz is és hamis is. a logikai és. attól függıen. A C#-ban a mőveleteket a következı képpen jelöljük: Tagadás (negáció) ÉS (konjunkció) VAGY (diszjunkció) ! && || Nézzük az operátorok igazságtáblázatát a bemenı paraméterek különbözı értékei mellett za operációk milyen eredményt szolgáltatnak? Tagadás: A TRUE FALSE !A FALSE TRUE Tehát minden értéket az ellentettjére fordít. logikai = sz < 4. bool logikai = true. Az összehasonlítás eredményét tudjuk tárolni egy logikai típusú változóban.

logikai = (x >= 3) && (x <= 4). y = 5 . ha ez nem dönt. logikai = (x < 3) || (x > 4). VAGY. akkor a kapcsos zárójelek elhagyhatóak. ÉS. ha mindkét paraméter értéke hamis.Write("Igaz kifejezés"). hogy ha mindössze egy utasítást szeretnénk végrehajtani. Látható. // FALSE // FALSE // TRUE // FALSE // TRUE A feltételes utasítás if (logikai kifejezés) { igaz érték esetén végrehajtandó utasítások } if (y > 20) Console. akkor a sorrend: TAGADÁS. Ezt leírhatjuk az és operátor alkalmazásával is: if (x > 10 && y > 20) 56/312 . vagy operatorok segítségével. logikai = logikai && !(y < 3).FALSE TRUE FALSE TRUE FALSE FALSE TRUE TRUE FALSE Látható. Egyenrangú mőveletek esetén a balról-jobbra szabály lép életbe. if (x > 10) if (y > 20) Console. hogy akkor hamis a mővelet eredménye. int x = 2. logikai = x > 4. logikai = x > 3 && !(y < 6) || x < y. A fenti kódrészlet csak akkor írja ki a szöveget. Egy kifejezés kiértékelésében a zárójelek határozzák meg a kiértékelés sorrendjét. bool logikai = true. hogy x > 10 és ugyanakkor y > 20 is.Write("Kifejezés igaz. ha egyszerre teljesül. Elıírhatunk összetett logikai feltételeket az if többszörözésével. igaz esetén").

if (Char.IsLetter(c)) if (Char.Write("Igaz kifejezés"). hogy több utasítás megadása esetén használni kell a kapcsos zárójeleket.Read().Write("Kifejezés igaz. akkor az else utáni utasítások kerülnek végrehajásra. public static void Main() { Console.IsLower(c)) Console. Amennyiben mindkettı feltétel teljesül."). Bármely feltétel hamis állapota esetén a szöveg kiírása elmarad. A billentyőzetrıl bekérünk egy karaktert.WriteLine("a karakter kisbető. else Console.Write("Kérem a karaktert: "). ha ez teljesül.Console. 57/312 . akkor jelenik meg a szöveg a képernyın. if (Char. az elsı if feltételében megvizsgáljuk hogy a kapott karakter bető-e.WriteLine("A karakter kisbető. hogy a karakter kisbető-e.Write("Hamis kifejezés"). Amennyiben a logikai kifejezés értéke hamis. igaz esetén ").Write("Kérem a karaktert: "). Tekintsük az alábbi programrészletet: Console.IsLetter(c)) if (Char. Az elágazás if (logikai kifejezés) { igaz érték esetén végrehajtandó utasítások } else { Hamis érték esetén végehajtandó utasítások } if (y > 20) Console.Read().IsLower(c)) Console. char c = (char) Console. akkor a második if feltételében vizsgáljuk. char c = (char)Console. Két vizsgálatot csinálunk."). Itt is érvényes.

pl. hogy páros-e! static void Main(string[] args) { int szam. szam = Int32.WriteLine("A szám páros"). a szam % 2 megadja a szam nevő változó értékének kettes maradékát. Az if utasítás egyszerő logikai feltételt tartalmaz. Ekkor a "A karakter nem bető" szöveg fog megjelenni. Ez páros szám esetén 0. akkor a beírt karakter már nem is bető. A logikai egyenlıség reláció operátora a == karakterekkel jelöljük. Ne próbáljuk meg az érétékadás = jelével helyettesíteni.else Console. else Console. így ezt vizsgáljuk. mert a hamis esetet külön kezeljük le. } A deklarálás után bekérünk a egy számot. 58/312 .WriteLine(" A szám páratlan"). A % jel a maradékképzés operátora. } Ebben az esetben nem használhatunk a 2 db if utasítás helyett logikai operátorral összekapcsolt kifejezést. if (szam % 2 == 0) Console." szöveg jelenik meg. akkor a "A karakter nagybetős. hanem valami más karakter jelenik meg.WriteLine("A karakter nem bető").ReadLine()). így egész számmá kell konvertálni. Néhány egyszerő példát a szelekció alkalmazására. Döntsük el egy számról. Ha a belsı if utasítás logikai kifejezése hamis. else Console.Parse(Console.WriteLine("A karakter nagybető.").: számjegy. Míg ha a külsı if logikai kifejezése hamis. Mivel ez karaktersorozat.

WriteLine("Így nem másodfokú az egyenlet!").4 * a * c.WriteLine("X1 = {0} } } Console. if (d < 0) Console. double x1.ReadLine()).ReadLine()). else { x1 = (-b + Math. b. 59/312 . a = double.Parse(Console.x2). c = double.Sqrt(d)) / (2 * a).ReadLine(). c. } X2 = {1} ".Sqrt(d)) / (2 * a). d. } else { b = double.x1. Console.Parse(Console.Parse(Console.Oldjuk meg az együtthatóival adott másodfokú egyenletet! static void Main(string[] args) { double a. x2 = (-b + Math.WriteLine("Nincs valós megoldás"). d = b * b . x2.ReadLine()). if (a == 0) { Console.

számról döntse el a program hogy számtani sorozatot alkotnak e! 8. Három adott számról döntse el a program. Három tetszıleges. Egy beolvasott számról döntse el a program hogy -30 és 40 között van-e! 2. rombusz. Írjunk programot. stb)! 60/312 . Határozzuk meg melyik síknegyedben van! 6. hogy lehetnek-e egy háromszög oldalainak mérıszámai. Rendeztessünk sorba 3 egész számot! 7.Megoldásra ajánlott feladatok 1. Vizsgáljuk meg hogy osztható-e egy A egész szám egy B egész számmal! 4. hogy milyen négyszögre gondoltam (négyzet. téglalap. Tetszıleges 0 és egymillió közötti egész számról mondja meg a program hogy hány jegyő! 5. Olvassunk be négy számot és határozzuk meg a páronkénti minimumok maximumát! 10. mely kibarkochbázza. Két beolvasott szám közül írassuk ki a nagyobbikat! 3. 9. Adott egy tetszıleges pont koordinátáival.

Programozás tankönyv VI. Hernyák Zoltán 61/312 . Fejezet Elıírt lépésszámú ciklusok ”Ismétlés a tudás anyja”.

I*I 3.WriteLine(”4. Console. és annak mennyi az értéke. Ezt a szakaszt ciklus magnak nevezzük. ha nem az elsı 5. A program végrehajtása elkezdıdött a Main függvény elsı utasításán. sor lényege. } négyzetszám négyzetszám négyzetszám négyzetszám négyzetszám = = = = = 1”). Console. négyzetszám= 1”. hogy a program sorai nagyjából egyformák. de elsı 50 négyzetszámot kell kiírni a képernyıre! Vegyük észre. stb… amíg el nem értük az utolsó utasítást. ugorj újra a 2. 4”).WriteLine(”2. De képzeljük el ugyanezt a programot. sorból áll. leggyakrabban nem írható fel a megoldás ilyen egyszerő lépésekbıl. és a 3. 25”). amelyek valamely más szám négyzeteként elıállíthatóak . public void Main() { Console. Console. négyzetszám = 9”. négyzetszám = ”. amikor is a program mőködése leállt. stb… A fenti kódot nevezhetjük kezdetleges ciklusnak is. ahol a program bizonyos szakaszát (sorait) többször is végrehajthatjuk. ezzel kényszerítve a számítógépet a ciklusmag újbóli végrehajtására. majd a „2. I := I+1 // az I változó értéke növelve 1-el 4. majd haladtunk a másodikra. 16”). négyzetszám = 4”. A 4. I := 1 // az I változó értéke legyen ’1’ 2. A fenti program még a hagyományos szekvenciális mőködés betartásával íródott.WriteLine(”3. sorra Ennek során kiíródik a képernyıre az „1.ilyen pl. Írd ki: I. Sıt.WriteLine(”1. 9”). a 25). A ciklusok olyan programvezérlési szerkezetek. 62/312 . Az hogy hányadik négyzetszámról van szó – az mindig 1-gyel nagyobb az elızı értéktıl. Console.”. Vegyük az alábbi programozási feladatot: írjuk ki az elsı 5 négyzetszámot a képernyıre (négyzetszámnak nevezzük azokat a számokat. hogy visszaugrik a ciklusmag elsı utasítására. két ponton különböznek egymástól: hogy hányadik négyzetszámról van szó. harmadikra.Az eddig megírt programok szekvenciális mőködésőek voltak. A fenti példaprogramban ez a szakasz (a ciklusmag) a 2. Nézzük az alábbi pszeudó-utasítássorozatot: 1.WriteLine(”5. Nem minden probléma oldható meg ilyen egyszerően. „3.

az 1. hiszen az I értéke e nélkül nem érhetné el a kilépéshez szükséges 6 értéket. Hogy ezen feltétel legelsı alkalommal is kiértékelhetı legyen. • ismétlési feltétel ( i<=5 ). } } A fenti példában a for kulcsszóval jelöljük. sorra 6. akkor befejezzük a ciklusmag végrehajtását. I := I+1 // az I változó értéke növelve 1-el 5. mivel ’kilépünk’ a ciklusból. ugorj újra a 2. hogy kell-e még ismételni a ciklusmagot . • Tartalmaznak egy feltételt (vezérlı feltétel). hogy ciklus szeretnénk írni. sorra. Valamint szintén figyeljük meg a 4. mely ha teljesül. A ciklusoknak tehát az alábbi fontos jellemzıjük van: • Tartalmaznak egy utasításblokkot. A 2. I := 1 // az I változó legyen ’1’ 2. hogy kiléphessünk a ciklusból. I*I 4. 63/312 . Ez jellemzıen helytelen viselkedés. így a program a végtelenségig fut. Írd ki: I. a ciklus utáni elsı utasításra ugorva. sorra 3. az algoritmusok. hogy véges sok lépés végrehajtása után leállnak.WriteLine(”{0}.i=i+1) { Console.Vegyük észre. akkor ugorj a 6. mint 5. • léptetı utasítás ( i=i+1 ). • A ciklusmag tartalmaz olyan utasítást.”. négyzetszám = {1}”. és a programok egyik fontos viselkedési jellemzıje. amelynek segítségével elıbb-utóbb elérjük azt az állapotot. sor elérésekor visszaugrunk a 2. • Tartalmaznak egy kezdıértékadást (a ciklus elıtt). A C#-ban a legnépszerőbb ciklus a FOR ciklus: public void Main() { int i. Ezen sor is nagyon fontos. amely biztosítja. sorban beállítjuk az I változó értékét (értékadás).i<=5. …. hogy ez a ciklus végtelen ciklus lesz. hiszen minden egyes alkalommal a 4. A for kulcsszó után zárójelben három dolgot kell megadni: • kezdıérték beállítása ( i=1 ). Ha az I értéke nagyobb.i*i). sort. sorba egy feltétel került. négyzetszám = ”.i. for (i=1. amely meghatározza. hogy a ciklus feltétele már legelsı alkalommal is egyértelmően kiértékelhetı legyen. amelyet akár többször is végrehajtanak (ciklusmag). Módosítsunk a kódon: 1.

5.Formailag a három részt pontosvesszıvel kell elválasztani. hogy tartozik hozzá egy ciklusváltozó. és ha HAMIS. cv <= végérték. Másik dolog. majd szintén az esetek többségében ezt az értéket minden ciklusmag lefutása után 1-el növeli. akkor végrehajtja a ciklusmag utasításait.. kiértékeli a vezérlı feltételt. amit megfigyelhetünk: a vezérlı feltétel kiértékelése már legelsı alkalommal is a ciklusmag elıtt hajtódik végre. lépésre. A for ciklus egy nagyon gyakori alakja tehát felírható az alábbi módon (’cv’ jelöli a ciklusváltozót): for (cv = kezdıérték.i<=5. hogy a ciklusmag egyetlen egyszer sem hajtódik végre. cv = cv+1) . ezért ebben az esetben a vezérlı feltételt a ciklusban maradás feltételének is nevezhetjük. visszaugrik a 2..WriteLine(i). elsısorban hagyománytiszteletbıl. végrehajtja a léptetı utasítást. A ciklusmagot pedig kapcsos zárójelek közé kell tenni (utasításblokk). melyet az esetek többségében ’i’-vel jelölünk. Például: for (i=10. 2. végrehajtja a kezdıértékadást. 3. Ennek megfelelıen egy hibás kezdıértékadás eredményezheti azt is. 4. amíg túl nem lépjük a végértéket. Ezen i változó felveszi a kezdıértékét. 64/312 .i=i+1) { Console. } A ’for’ ciklusra jellemzı. Ha a vezérlı feltétel igaz. végrehajtja a ciklusmagot. A C# az alábbi módon értelmezi a for ciklust: 1. akkor kilép a ciklusból.

ossz). melyik az utasításcsoport. ). ={0}”.c.a.ossz=0. ). ).ReadLine() ossz = ossz+a.ossz). és írjuk ki a képernyıre a 3 szám összegét. majd i=2.ReadLine() ossz = ossz+a. } Console. hogy a ciklusmag hányszor hajtódik végre: for (i=1. és alakítsuk át ciklusos szerkezetővé. a = Int32.Parse( Console.Parse( Console. Console.ReadLine() ). A fenti program ugyanazt teszi. Ebbıl már könnyő ciklust írni: int i.ossz). a = Int32. ….i<=3. Console. ossz = 0. akkor már célszerőtlen lenne a program ezen formája.i++) { Console.WriteLine(i). for(i=1.ossz.ReadLine() ossz = ossz+a.Ennek megfelelıen elıre kiszámítható. amelyet 3-szor meg kell ismételni.ReadLine() c = Int32. Sokszor ez a legnehezebb lépés.Parse( Console. Vegyük az alábbi programozási feladatot: kérjünk be 3 számot. 65/312 .Parse( Console. ossz = ossz+a. ). Ugyanakkor.Parse( Console.WriteLine(”A számok összege ={0}”. hogy egy már meglévı szekvenciális szerkezető programban találjuk meg az ismételhetı lépéseket. összesen 10 alkalommal.ReadLine() b = Int32.ossz.b.Parse( Console. ha nem 3.ReadLine() ossz = a+b+c.WriteLine(”A számok összege ). mint az elızı. hanem 30 számról lenne szó. i=10 értékekre hajtódik végre. de már látszik. ={0}”. } Ezen ciklus magja legelsı alkalommal az i=1.i<=10. a = Int32.i=i+1) { a = Int32.WriteLine(”A számok összege ).Parse( Console. Az elsı megoldás még nem tartalmaz ciklust: int a. a = Int32. Kicsit alakítsuk át a fenti programot: int a.

a 6 faktoriális úgy számolható ki. Ekkor a C# megengedi. i<=szam . így számolva ki lépésrıl lépésre a végeredményt. A számot kérjük be billentyőzetrıl. Console. i++ ) ossz = ossz + i. Programozási feladat: Határozzuk meg egy szám faktoriálisának értékét. int szam. i=i+1) { ossz = ossz + i.ossz).ossz=0. …. hogy 1*2*3*4*5*6.Programozási feladat: Készítsük el az elsı 100 egész szám összegét. amelynek jelentése: ’csökkentsd 1-gyel az értékét’. A program a ’fakt’ változó értékét megszorozza elıször 1-el. majd 100-t ad az ossz változó aktuális értékéhez.WriteLine(”A(z) {0} szám faktoriálisa = {1}”. int i. for (i=1. így állítván elı az elsı 100 szám összegét. hogy a ciklusmag egyetlen utasításból áll csak. Ezt gyakran i++ alakban írják a programozók. Jegyezzük meg.fakt=1.WriteLine(”Az elsı 100 egész szám összege ={0}”. 66/312 . majd 2-t. jelentése ’növeld meg 1-gyel az értékét’. hogy a ciklusokban az i=i+1 utasítás nagyon gyakori. i<=100 . Ezért a fenti kis program az alábbi módon is felírható: int i. hogy aránylag gyakori. Ugyanakkor a probléma megoldása az elsı N négyzetszám összegképletének ismeretében egyetlen értékadással is megoldható: ossz= 100*101 / 2. Console.ReadLine() ). for (i=1.WriteLine(”Az elsı 100 egész szám összege ={0}”. Megjegyzés: a fenti feladat ezen megoldása. A párja a -. majd 3-al. for (i=1. i++ ) fakt = fakt * i. végül magával a számmal. Másik észrevételünk. Magyarázat: a program minden lépésben hozzáad egy számot az ’ossz’ változóhoz.i.operátor. mint léptetı utasítás. majd 2-vel. szam. i<=100 . Magyarázat: pl. Elsı lépésben 1-et. amelynek induláskor 0 a kezdıértéke. fakt ).ossz). és az alkalmazott módszer érdekes tanulságokat tartalmaz. A ++ egy operátor. …. hogy ne tegyük ki a blokk kezdet és blokk vége jeleket. szam = Int32. majd 3-t.Parse( Console.ossz=0. } Console.

hogy 4*4*4.Megjegyzés: a ’szam’ növelésével a faktoriális értéke gyorsan nı. minden lépésben csökkentve a ciklusváltozónk értékét (i--). ha a szám maradék nélkül 67/312 . vagy sem.”. i<=kitevo .i. i++ ) ertek = ertek * szam. hogy az osztója-e a számnak.) if (i % szam == 0) Console.ReadLine() ). Ez akkor teljesül. Amennyiben az osztási maradék 0. Minden osztó-találat esetén növeljük 1-gyel a ’db’ változó értékét. Magyarázat: pl. i-.ReadLine() ).i.ertek). A % operátor meghatározza a két operandusának osztási maradékát (pl. for (i=1.ertek=1. Minden lépésben megvizsgáljuk. for (i=100. ezért az ’i’ változóban lévı érték egy osztó. mint 100. és a kitevıt kérjük be billentyőzetrıl! int szam. csökkenı sorrendben! A számot kérjük be billentyőzetrıl! int szam.Parse( Console. i++ ) if (szam%i==0) db++. for (i=1.. 15-ig) tesztelhetjük csak a fenti programot. ezért csak kis számokra (kb. Magyarázat: a 10 lehetséges osztói az 1.Parse( Console.ReadLine() ).kitevo. mindegyiket ellenırizve. szam = Int32. 4 harmadik hatványa kiszámolható úgy.i).db=0. hogy sorba próbálkozunk a szóba jöhetı számokkal. szam = Int32. Console. Programozási feladat: Határozzuk meg egy szám pozitív egész kitevıjő hatványát! A számot. szam = Int32.szam. A módszer lényege. amelyek nem nagyobbak.i.db). úgy az ’i’ maradék nélkül osztja a ’szam’ változó értékét.Parse( Console. visszafele haladunk. i<=szam . szam. hogy a szóban forgó ’i’ többszöröse-e az eredeti számnak.WriteLine(”A(z) {0} szám {1}. Programozási feladat: Határozzuk meg egy szám osztóinak számát! A számot kérjük be billentyőzetrıl! int szam. i>=szam . ahányszor azt a kitevı elıírja. A program a ’ertek’ változó értékét megszorozza annyiszor a ’szam’-al. Magyarázat: elindulunk 100-tól.WriteLine(”{0} ”.ReadLine() ). a 14%4 értéke 2 lesz. hatványa = {2}”.WriteLine(”A(z) {0} szám osztóinak száma: {1}.10 tartományba esnek. Console. Az oszthatóságot a ’%’ operátorral ellenırizzük. Programozási feladat: Írassuk ki a képernyıre egy szám összes többszörösét.kitevo.Parse( Console. mert 14 osztva 4-gyel 2 osztási maradékot ad). kitevo = Int32.

akkor a ’100/szam’ eredménye 14. max = (100/szam)*szam. Ez lesz a kiinduló értéke a ciklusváltozónak. Ha a ’szam’ értéke pl. Ha ezt visszaszorozzuk a ’szam’-al. amely biztosan többszöröse a ’szam’-nak. mivel két egész szám típusú érték között kerül végrehajtásra automatikusan egész osztásnak minısül. Ugyanezen feladat megoldható hatékonyabban.osztja az ’i’-t. hogy ezen számok egymástól ’szam’ távolságra vannak: int szam.WriteLine(”{0} ”. mindannyiszor kiírjuk azt a képernyıre. i=i-szam ) if (i % szam == 0) Console.i). és nem nagyobb mint 100. szam = Int32. hogy a kiinduló értéket minden cikluslépésben csökkentjük ’szam’-al. amely nem nagyobb mint 100 (’max’). ha figyelembe vesszük. Valahányszor találunk ilyen ’i’ értéket. A további többszörösöket úgy kapjuk.Parse( Console. Magyarázat: a ’100/szam’ osztási mővelet. i>=szam . akkor megkapjuk a legnagyobb olyan értéket.max. 7. és a legnagyobb ilyen többszöröse a ’szam’-nak.i. 68/312 . for (i=max.ReadLine() ).

11. Programozási feladat: Írjunk olyan programot. hogy mi a legnagyobb közös osztójuk! A legnagyobb olyan szám.! Ellenırizzük le az eredményt a számtani sorozat összegképlete segítségével! 7.23.Feladatok: 1.30. 4. amely bekéri egy tetszıleges mértani sorozat elsı elemét. 3. és az elemek összegét! 10. amely mindkét számot osztja. az elemeket egymástól vesszıvel elválasztva. Programozási feladat: Írjunk olyan programot. és a differenciát! Ezek után kiírja a képernyıre a számtani sorozat elsı 20 elemét.9. Programozási feladat: Állapítsuk meg.…. vagy az Euklideszi algoritmussal is.stb.5.12. Programozási feladat: Állapítsuk meg két billentyőzetrıl bekért számról. egy sorban! 9. Programozási feladat: Állapítsuk meg két billentyőzetrıl bekért számról. Programozási feladat: Állítsuk elı egy szám prímtényezıs felbontását! Pl: 360=2*2*2*3*3*5! 5.17. amely kiszámolja és kiírja az alábbi változó növekményő számtani sorozat elsı 20 elemének összegét: 3. hogy relatív prímek-e! Akkor relatív prímek. ha a legnagyobb közös osztójuk az 1.! 8. Programozási feladat: Írjunk olyan programot. és a kvócienst! Ezek után kiírja a képernyıre a mértani sorozat elsı 20 elemét.8.2.10-re! 11.stb.5. Programozási feladat: Írjunk olyan programot. Ezen értéket meghatározhatjuk kereséssel (ciklus). ha a1=1! 69/312 . hogy egy adott intervallumba esı számok közül melyik a legnagyobb prímszám! Az intervallum alsó és felsı határának értékét kérjük be billentyőzetrıl! Próbáljunk keresni idı-hatékony megoldásokat! 6. Programozási feladat: Számoljuk ki és írjuk ki a képernyıre az an=an-1+2n sorozat elsı 10 elemét. amely bekéri egy tetszıleges számtani sorozat elsı elemét. 2. hogy prímszám-e! A prímszámoknak nincs 1 és önmagán kívül más osztója. Programozási feladat: Állapítsuk meg egy billentyőzetrıl bekért számról.7. amely egy összegzı ciklussal kiszámolja és kiírja az alábbi számtani sorozat elsı 20 elemének összegét: 3. Programozási feladat: Számoljuk ki és írjuk ki a képernyıre a 2n értékeit n=1.

Programozási feladat: Írjunk olyan programot.b] intervallum belsejébe esı négyzetszámokat (írjuk ki a képernyıre). Programozási feladat: Határozzuk meg az elsı n négyzetszám összegét! N értékét kérjük be billentyőzetrıl! 14. Programozási feladat: Határozzuk meg egy [a. és azok összegét! Az a és b értékét kérjük be billentyőzetrıl! 15. amíg a sorozat következı elemének értéke meg nem haladja az 1000-t! A sorozat elsı eleme: a1=1! 13. Programozási feladat: Számoljuk ki és írjuk ki a képernyıre a Fibonacci sorozat elsı 10 elemét! A sorozat az alábbi módon számítható ki: a1 = 1 a2 = 1 an = an-1 + an-2 ha n>2 70/312 . amely addig írja ki a képernyıre a an=2n-2n-1 sorozat elemeit a képernyıre.12.

Fejezet „Vektorok!” Radványi Tibor 71/312 .Programozás tankönyv VII.

mint egy hagyományos változóé. a dimenzió száma nem korlátozott. Ez mindig 0-tól indul és egyesével növekszik. Az elemek típusa azonos. btm[0] = true. // 10 elemő valós tömb A tömb elemeire indexeik segítségével hivatkozhatunk. Ilyenkor a tömbünk még nem használható. feltölthetjük. tm[0] = 1. int[] tm. melynek alapján a többdimenziós tömbök kezelése is elsajátítható. hogy a tömb deklarációjakor meg adjuk az elemeit. tm[2] = 17. stb tömböt deklarálni: string[] stm = new string[5]. vagy egyszerően: int[] tm = new int[5]. bool[] btm = new bool[7]. ha van rá lehetıségünk és ismeretünk: 72/312 . hiszen a memóriában még nem történt meg a helyfoglalás. stm[0] = "Elsı". de elıre meghatározott számú eleme van. tm[1] = 2. valós. Fejezetünkben az egydimenziós tömbök kezelésével foglalkozunk. Ezt a new operátor használatával tehetjük meg. tm[4] = 4. mőveleteket végezhetünk vele. Tömb deklarálása Hasonlóan történik. A fentiekhez hasonlóan tudunk string. tm = new int[5]. tm[3] = 90. int típusú tömböt. A tömb lehet egy vagy többdimenziós. csak a [] jellel kell jelezni. melynek tetszıleges.Vektorok kezelése A tömb egy összetett homogén adatstruktúra. Megtehetjük. Ezzel létrehoztunk egy 5 elemő. hogy tömb következik: int[] tm. // 5 elemő string tömb // 7 elemő logikai tömb double[] dtm = new double[10]. Használhatjuk.

Length.Console. A tömb elemeinek elérése A tömb elemein végiglépkedhetünk egy egyszerő for ciklus alkalmazásával.WriteLine(s. string[] stm2 = new string[3] {"elsı".4. i++) { tm[i] = 2 * tm[i]. int i.ToString()). // alapértéket ad a tm tömb elemeinek } for (i = 0. vagy használhatjuk a foreach ciklust. azaz rögtön megadjuk a kezdıértékeket is.2. i++) { tm[i] = 1.int[] tm2 = new int[3] {3."bbb".5}."harmadik"}. // duplázza a tm tömb elemeit } foreach (int s in tm) { System."ccc"}. for (i = 0. ha általános függvényt szeretnénk írni. 73/312 . i < tm."második". i < 5. akkor a new operátor elhagyható: int[] tm3 = {1. string[] stm3 = {"aaa". melyet akár ciklusban is használhatunk paraméterként.3}. Ha az elıbbi módon használjuk a tömb deklarációt. elemeit } // kiírja a tm tömb A length tulajdonság segítségével megkapjuk a tömb méretét.

melynek egy paramétere van.Console. ShowArray(tm).WriteLine(). helyben rendezi a paraméterként kapott tömböt. Array. 74/312 . Eredmény: Az elsı kiíratáskor: 1 2 17 90 4 A második kiíratáskor: 1 2 4 17 90 Ebben az esetben a teljes tömb rendezésre kerül.Write(j. Deklarációja: public static void Sort(Array array). tm[2] = 17. System. Ha a Sort metódus három paraméteres változatát használjuk. int index.Console. tm[1] = 2. ShowArray(tm).} Ennek a segítségével vizsgáljuk meg az Array osztály lehetıségeit. int length). akkor a tömb egy résztömbjét rendezhetjük. A Sort metódus.ToString()+" "). Használata: tm[0] = 1. tm[3] = 90. Deklarációja: public static void Sort(Array array.A tömb elemeinek rendezése. tm[4] = 4.Sort(tm). keresés a tömbben A tömb kiíratásához használhatunk egy egyszerő metódust: private static void ShowArray(int[] k) { foreach (int j in k) System.

amikor két tömb paramétert használunk. és ez kerül rendezésre. Eredmény: Az elsı kiíratáskor: 1 2 17 90 4 A második kiíratáskor: 1 2 17 4 90 Tehát csak a 90 és a 4 cserélt helyet. A rendezés következı esete. mely tartalmazza a kulcsokat a rendezéshez Items: elemek. Használata: tm[0] = 1.2). A metódus rendezi a keys tömb elemeit. Keys : egy egydimenziós tömb. melyek a Keys tömb elemeinek felelnek meg.Sort(tm. Array.2). ShowArray(tm). tm[3] = 90. 75/312 . Deklarációja: public static void Sort( Array keys. mert csak az utolsó két elem rendezését írják elı a paraméterek (3.3. ShowArray(tm).Ekkor az index paramétertıl kezdve a length paraméterben megadott hosszban képzıdik egy részhalmaza a tömb elemeinek. és ennek megfelelıen az items tömb elemeinek sorrendje is változik. tm[2] = 17. tm[1] = 2. Array items). tm[4] = 4.

System. tm[1] = 34.Console.Write(j+" ")."harmadik". } tm[0] = 1.WriteLine().Sort(tm.stm2). Array. string[] stm2 = new string[5] {"elsı". Eredmény az elsı kiíratás után: 1 34 17 90 4 elsı második harmadik negyedik ötödik Eredmény a második kiíratás után: 1 4 17 34 90 elsı ötödik harmadik második negyedik Az elızı kulcsos rendezéshez hasonlóan.Használata: A string tömb elemeinek kiíratásához használt metódus: private static void ShowArrayST(string[] k) { foreach (string j in k) System. "negyedik". ShowArray(tm). int keys: egy egydimenziós kulcsokat tartalmazó tömb items: egy egydimenziós. "ötödik"}.Console. a kulcsokhoz tartozó elemeket tartalmazó tömb index: a rendezendı terület kezdıpozíciója length: a rendezendı terület hossza 76/312 . tm[3] = 90. tm[4] = 4. tm[2] = 17. de csak részhalmaz rendezésre használható az alábbi metódus: Deklaráció: public length). ShowArrayST(stm2). ShowArrayST(stm2). ShowArray(tm)."második". int index. static void Sort(Array keys. Array items.

tm[3] = 90."harmadik". "negyedik". "ötödik"}. ShowArrayST(stm2).Sort(tm. Array. ShowArrayST(stm2). melyenek megoldásához tömböket használunk. tm[4] = 4. string[] stm2 = new string[5] {"elsı". tm[2] = 17. ShowArray(tm).2).stm2.3. tm[1] = 34. 77/312 ."második". ShowArray(tm). Eredmény az elsı kiíratás után: 1 34 17 90 4 elsı második harmadik negyedik ötödik Eredmény a második kiíratás után: 1 34 17 4 90 elsı második harmadik ötödik negyedik Következzen néhány alapfeladat.Használata: tm[0] = 1.

int i. például „almafa” írunk az adatbekérés helyére.i+1). számot". i++) { Console.ReadLine()). for (i=0. ezért ezt át kell alakítani a megfelelı formátumra a Convert osztály ToInt32 metódusának a segítségével. int[] tm = new int[5].ToInt32(Console. Ha szám helyett szöveget. 78/312 . i<5. melyek még eddig nem szerepeltek.ReadLine() függvény visszatérési értéke string. } ShowArray(tm). Mivel a Console. hogy csak olyan értékeket fogadjon el. akkor a program hibaüzenettel leáll. Azaz kérjünk be a billentyőzetrıl 5 db különbözı egész számot. Semmiféle ellenırzést nem tartalmaz a kód.Vektor feltöltése billentyőzetrıl Ebben az egyszerő példában bekérünk 5 db egész számot a billentyőzetrıl.WriteLine("Kérem a {0}. így csak egész számok esetén mőködik jól. tm[i] = Convert. A futás eredménye: Módosítsuk úgy a programot.

for (j = 0. számot". A futás eredménye: 79/312 . int i. bool nem_volt = true.int[] tm = new int[5].WriteLine("Kérem a {0}.ToInt32(Console. for (i=0. j. break. nem_volt = true. j < i.i+1). i<5.ReadLine()). j = 0. i++) { Console. } } ShowArray(tm). j++) if (tm[i] == tm[j]) { i--. tm[i] = Convert.

Oldjuk meg ezt a feladatot is úgy. hogy az értékek int[] tm = new int[5]. j = 0. int i. de most használjuk a tömb feltöltéséhez a véletlenszám-generátort.//Egy példány a Random osztályból for (i=0. i++) { tm[i] = rnd. 80/312 . hogy ne engedjük meg az ismétlıdést a generált számok között. típushelyesek legyenek. int i. Készítsünk egy rnd nevő példányt belıle.Next(100).Next(100). int[] tm = new int[5]. i++) { tm[i] = rnd. i<5. } } ShowArray(tm). nem_volt = true. j. bool nem_volt. //Egy példány a Random osztályból for (i=0. for (j = 0. Random rnd = new Random(). j < i. j++) if (tm[i] == tm[j]) { break. Ebben az esetben biztosítjuk. Random rnd = new Random(). bool nem_volt. } ShowArray(tm). j. Használatkor az rnd példány paramétereként adjuk meg a felsı határát a generálandó számnak.Vektor feltöltése véletlenszám-generátorral Nézzük meg az elızı feladatot. i<5. A véletlenszám-generátort a Random osztályból érjük el.

Megoldás: int[] tm = new int[10].WriteLine(). i++) { tm[i] = rnd. i++) sum += tm[i]. sum). int i. majd határozzuk meg a számok összegét. Console.WriteLine("A számok összege: {0}".A futás eredménye: N elemő vektorok kezelése Egyszerő programozási tételek alkalmazása vektorokra Összegzés Feladat: Adott egy 10 elemő. ". for (i=0. for (i=0 . i<10.tm[i]). egész típusú tömb. Console.Write("{0} } Console. Magyarázat: 81/312 .Next(100. Random rnd = new Random(). sum = 0.200). i<10. Töltsük fel véletlen számokkal.

max). Az i ciklusváltozó. Rögtön le is foglaljuk a memóriában 10 elem helyét. max. végiglépkedve az elemeken.Next(100.Write("{0} } Console. max = tm[0]. a sum a győjtıváltozó lesz.200). min. i<10. 82/312 . i++) { if (tm[i] > max) max = tm[i]. } Console. Majd kiíratjuk a végeredményt.WriteLine(). i++) { tm[i] = rnd. for (i=0 . min. Ezért ennek 0 kezdıértéket kell adni. Az összegzést a második for ciklus végzi. melyben a tömb elemeinek az összegét generáljuk. if (tm[i] < min) min = tm[i].WriteLine("A számok minimuma: {0}. Maximum és minimum kiválasztása Feladat: Adott egy 10 elemő. majd határozzuk meg a legnagyobb illetve legkisebb elem értékét. és azok értékével növeli a sum változó pillanatnyi értékét. ". Az elsı for ciklusban feltöltjük a tömböt a véletlen számokkal. Console. melynek a neve tm. for (i = 1. Létrehozunk a Random osztályból egy rnd nevő példányt.tm[i]). min = tm[0]. Töltsük fel véletlen számokkal. i < 10. Random rnd = new Random(). egész számokat tartalmazó tömb. Megoldás: int[] tm = new int[10].Az elsı sorban deklarálunk egy int típusú elemeket tartalmazó tömböt. int i. Ennek a segítségével fogjuk elıállítani a véletlen számokat. maximuma: {1}".

Magyarázat: A tömb feltöltése után kérjünk be egy számot a billentyőzetrıl.WriteLine(). int szam = Int32. egész számokat tartalmazó tömb.WriteLine("A szám nem szerepel a tömbben").Parse függvényt használtuk.Magyarázat: A program eleje hasonló az összegzésnél látottakkal. Töltsük fel véletlen számokkal. 83/312 . i<10. Itt fogjuk megjegyezni az aktuális legnagyobb és legkisebb elemet. vagy a min értéke. akkor onnan kezdve az lesz a max. else Console. ".Parse(Console. i = 0.200). Ehhez itt a Int32. Eldöntés Feladat: Feladat: Adott egy 10 elemő. Döntsük el hogy a bekért szám szerepel e a 10 elemő tömbben.Write("{0} } Console. majd kérjünk be egy egész számot a billentyőzetrıl. Ügyelve a konverzió szükségességére. hogy a feladat mit követel meg tılünk. Random rnd = new Random(). while (i < 10 && szam != tm[i]) i++. hogy a tömbindexet tároljuk el. Az értékek feltöltése után a következı for ciklussal végignézzük az elemeket.WriteLine("A szám szerepel a tömbben").tm[i]). de van rá lehetıség. A példában az elem értékét jegyezzük meg. Megoldás: int[] tm = new int[10]. Egy max és egy min változót is deklarálunk. Console.ReadLine(). Console. for (i=0 . i++) { tm[i] = rnd.ReadLine()). int i.Next(100. if (i < 10) Console. és ha találunk az aktuális szélsıértéknél nagyobb illetve kisebb tömbértéket. attól függıen.

int i. Mivel logikai ÉS kapcsolat van a két feltétel között.WriteLine(). Ennek megfelelıen írjuk ki üzenetünket. a párosság 84/312 . i++) if (tm[i] % 2 == 0) Console. i++) { tm[i] = rnd. for (i=0 . a második. mert ha nincs ilyen tömbelem. hogy benne vagyunk e még a tömbben. vagy elfogyott a tömb. így a ciklusmag akkor hajtódik végre. Az elsı feltétel azt ellenırzi.200). ". hogy még nem találtuk meg a keresett értéket. Kiválogatás Feladat: Adott egy 10 elemő.Az eldöntéshez egy while. Magyarázat: A tömb feltöltése után a második cikluson belül írjuk a megfelelı feltételt az if szerkezetbe. Random rnd = new Random(). Figyeljünk oda.Next(100. Megoldás: int[] tm = new int[10]. akkor kilépünk a ciklusból. Így utána az if feltételel döntjük el a kilépés okát.tm[i]). egész számokat tartalmazó tömb.Write("{0} } Console. ha mindkét feltétel igaz. A ciklusmagban az i ciklusváltozó értékét növeljük. i < 10. for (i = 0. azaz hogy megtaláltuk a szám elsı elıfordulását. elıltesztelı ciklust használunk összetett logikai feltétellel. hogy az if feltételben nem alkalmazhatjuk a while feltétel második részét. Töltsük fel véletlen számokkal. majd írassuk ki a páros számokat közülük. A feltétel. Ha bármelyik feltétel hamissá válik. Ennek teljesülése esetén kiírjuk a tömbelemet. akkor a vizsgálatkor már i = 11 lenne. Console. ". így nem létezı tömbelemre hivatkoznánk.tm[i]).WriteLine("{0} Console.ReadLine(). i<10.

akkor a szám páros. Ebben az esetben kerül kiíratásra. 85/312 .vizsgálata. Ha a tömbelem 2-vel osztva 0 maradékot ad. Ezt az maradékképzés % operátorával vizsgáljuk.

Az ArrayList fıbb jellemzıi: Capacity: az elemek számát olvashatjuk illetve írhatjuk elı. CopyTo: Átmásolja az ArrayList-át egy egydimenziós tömbbe. Insert: Beszúr egy elemet az ArrayListbe a megadott indexhez. Deklarálás: ArrayList arl = new ArrayList(). IndexOf: A megadott elem elsı elıfordulásának indexét adja vissza. Count: az elemek számát olvashatjuk ki. Az ArrayList fıbb metódusai: Add: Hozzáad egy objektumot a lista végéhez.Dinamikus mérető vektorok Dinamikus elemszámú tömbök kezelését valósítja meg az ArrayList osztály. Item: A megadott indexő elemet lehet írni vagy olvasni. Sort: Rendezi az elemeket az ArrayListben. A lista elsı elemének az indexe a 0. 86/312 . Csak olvasható tulajdonság. BinarySearch: Rendezett listában a bináris keresés algoritmusával megkeresi az elemet Clear: Minden elemet töröl a listából.

a). míg nullát nem írunk be. hozzáadjuk az ArrayListánkhoz az add metódus meghívásával.Write("{0} } ". elem.ReadLine()). Az adatbekérést mindaddig folytatjuk. if (elem != 0) dtm. A 0 beírása után az ellenırzés miatt vissza írattuk az ArrayList tartalmát az alábbi függvény meghívásával: static void Kiir(ArrayList al) { foreach (int a in al) { Console. } while (elem != 0). int i = 0. do { elem = Int32. Amennyiben ez nem nulla értékő.Parse(Console. Deklarálunk egy dtm nevő ArrayList objektumot.Add(elem). és a konverzió eredményét tároljuk az elem nevő változóba.Feladatok dinamikus tömbre Kérjünk be számokat a nulla végjelig ArrayList dtm = new ArrayList(). Az adatbekéréskor a ReadLine() függvény által visszaadott karakterláncot konvertáljuk Int32 típussá. és példányosítsuk is. 87/312 .

és az általuk meghatározott szakasz. Ehhez a kör középpontjának koordinátáira és a sugarának hosszára lesz szükségünk. public double sugar. class TKor { public TPont kozeppont = new TPont(). y. Használjuk fel a már meglévı TPont osztályt. Ezen az osztályon fog alapulni a feladat megoldása. mint adatmezıt tartalmazza. adjuk meg a középpontját és a sugarát! A feladat elsı felét nézzük most. Hogyan kezeljük a pontokat. ahol egy végpontjainak koordinátáival adott szakasz fölé rajzolt kör adatait tudjuk meghatározni. class TPont { public double x. 88/312 . melyek távolsága a legnagyobb. és adatait. } A feladatunk megkeresni azt a két pontot. Hozzunk létre egy kört leíró osztályt is.Console.WriteLine(). mely a síkbeli pont két koordinátáját. Ehhez használjuk a következı osztályt. Határozzuk meg azt a minimális sugarú kört. } Ezzel létrehoztunk egy TPont osztályt. } Feladat: Adott a síkon koordinátáival néhány pont. mely magába foglalja az összes pontot. mint átmérı fölé rajzolt kört adatait meghatározni.

Tekintsük az alábbi deklarációt.y). } } A kozeppont változó a TKor osztályan lett deklarálva. A pontok nevő ArrayListbe fogjuk tárolni a pontok adatait. public TPont Veg = new TPont(). public long pontok_szama = 0. az öröklés miatt ez az osztály is látja. hogy megoldjuk a feladatot. Itt használjuk ki a dinamikus ArrayList adta lehetıségeket.x)*(Veg.Collections. System.ArrayList().kozeppont.y = (Veg.y))/2.x-Kezd. Ezeket feltölthetjük billentyőzetrıl: 89/312 .Console. public System. sugar = System.y-Kezd.y + Kezd. public void szakasz_fole_kor() { kozeppont.Sqrt((Veg.x + Kezd. Ezek után minden eszközünk megvan ahhoz.Collections.y-Kezd.WriteLine("{0} {1}".x = (Veg.class TSzakasz_kore : TKor { public TPont Kezd = new TPont().x)+ (Veg.y)*(Veg. mely lehetıvé teszi tetszıleges számú pont felvételt a síkon.x)/2. és a public láthatósága miatt használhatja is.kozeppont.y)/2.ArrayList pontok = new System.x. kozeppont.x-Kezd.Math.

public void pontok_beo() { int i = 1; while (i<=pontok_szama) { TPont pont = new TPont(); System.Console.Write("Kérem az {0}. pont X koordinátáját ... ", i); pont.x = System.Convert.ToDouble(System.Console.ReadLine()); System.Console.Write("Kérem az {0}. pont Y koordinátáját ... ", i); pont.y = System.Convert.ToDouble(System.Console.ReadLine()); pontok.Add(pont); i++; } System.Console.WriteLine("Koordináták beolvasva..."); }

Keressük meg a maximális távolságra lévı pontokat a ponthalmazból. Ehhez lehet ezt az egyszerő metódust használni:
private void max_tav_pontok() { double maxtav = 0, tav; foreach (TPont pont1 in pontok) { foreach (TPont pont2 in pontok) { tav = System.Math.Sqrt((pont2.x-pont1.x)*(pont2.x-pont1.x)+ (pont2.y-pont1.y)*(pont2.y-pont1.y)); if (maxtav < tav) { maxtav = tav; Kezd.x = pont1.x; Kezd.y = pont1.y; Veg.x = pont2.x; Veg.y = pont2.y; } } } }

90/312

Ha a fenti metódusokat egy olyan osztályban hozzuk létre, melyet a TSzakasz_kore osztályból származtattunk, akkor a megoldást mindössze két metódus meghívása szolgáltatja:

public void kor_megadasa() { max_tav_pontok(); szakasz_fole_kor(); }

Ekkor a Main függvény tartalma a következı lehet:

System.Console.WriteLine("\n\n Sok pont esete: "); TSik_pontokat_foglalo_kor sk = new TSik_pontokat_foglalo_kor(); System.Console.WriteLine(" --- Kérem a pontok számát: --- "); int p_count = System.Convert.ToInt32(System.Console.ReadLine()); sk.pontok_szama = p_count; sk.pontok_beo(); sk.kor_megadasa(); System.Console.WriteLine("A kör középpontja O( {0} , {1} )és sugara: R = {2}", sk.kozeppont.x, sk.kozeppont.y,sk.sugar);

Ezzel a feladatot megoldottuk.

91/312

Többdimenziós tömbök
Sok feladat megoldásához az egydimenziós tömb struktúra már nem elegendı, vagy túl bonyolulttá tenné a kezelést. Ha például győjteni szeretnénk havonként és azon belül naponként a kiadásainkat. A kiadások számok, de a napokhoz rendelt indexek nehézkesek lennének, mert február 1-hez a 32-t, június 1-hez már a 152-es index tartozna. Egyszerőbb, ha a kiadásainkat két indexel azonosítjuk. Az egyik jelentheti a hónapot, a másik a napot. Ha már az évet is szeretnénk tárolni, akkor egy újabb index bevezetésére van szükségünk.

Nézzük meg egy egyszerő példán keresztül a deklarációt. Töltsünk fel egy 3x3 mátrixot véletlen számokkal és írassuk ki ıket mátrix fromában a képernyıre.

static void Main(string[] args) { int[,] tm = new int[3,3]; int i, j ; Random rnd = new Random(); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { tm[i,j] = rnd.Next(10,20); Console.Write("{0} } Console.WriteLine(); } Console.ReadLine(); } ",tm[i,j]);

Látható, hogy a deklarációkor a két indexet úgy jelezzük, hogy egy vesszıt teszünk a zárójelbe, majd a példányosításkor megadjuk az egyes indexekhez tartozó elemszámot. A kétdimenziós tömböt feltölteni elemekkel, illetve kiíratni azokat elég két ciklus, ahol az egyik ciklusváltozó az egyik indextartományt futja végig, míg a másik ciklusváltozó

92/312

a másik tartományt. Ha nem két, hanem többdimenziós tömböt használunk, akkor a ciklusok számma ennek megfelelúıen fog nıni. A példában látható, hogy a mátrix forma megtartás érdekében egyszerően a sorok elemeit egymás mellé Write utasítás alkalmazásával írattuk ki. A belsı ciklus minden sor kiírásáért felelıs, így a sorok végén a soremelésrıl gondoskodtunk a WriteLine utasítással, melynek nem volt paramétere.

A kétdimenziós tömböt feltölthetjük kezdıértékkel, hasonlóan az egydimenziós esethez:

int[,] tm2 = new int[2,2] {{1,2},{3,4}};

Tekintsük a következı feladatot: Töltsünk fel egy 3x3 mátrixot a billentyőzetrıl egész számokkal. Írassuk ki a szokásos formátumban, majd generáljuk a transzponáltját, és ezt is írassuk ki.

A szükséges tömb és ciklusváltozók deklarálása:

int[,] tm = new int[4,4]; int i, j ;

Töltsük fel a mátrixot billentyőzetrıl egész számokkal:
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { Console.Write("Kérem a {0}. sor {1}. oszlop elemét: tm[i,j] = int.Parse(Console.ReadLine()); } ",i,j);

Írassuk ki a tömb elemeit mátrix formában:
Console.WriteLine("Az eredeti mátrix: "); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) Console.Write("{0} Console.WriteLine(); } ",tm[i,j]);

93/312

Ez futás közben így néz ki:

Deklaráljunk egy tr tömböt a transzponált mátrix elemeinek. Majd generáljuk le az eredeti tm tömbbıl. A transzponált mátrixot az eredeti mátrix oszlopainak felcserélésével kapjuk. sorainak és

int[,] tr = new int[3,3]; for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) tr[i,j] = tm[j,i];

Újra ki kell íratni egy tömböt, most a transzponált mátrixot.

for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) Console.Write("{0} Console.WriteLine(); } ",tr[i,j]);

A program futtatását bemutató képernyı: 94/312

Vegyük észre, hogy a két kiíratásban csak a tömb neve a különbözı. Feleslegesen írjuk le kétszer ugyanazt a kódot. Erre jobb megoldást ad az eljárásokról és függvényekrıl szóló fejezet.

95/312

További megoldásra ajánlott feladatok 1. Ott van tenger. Egy nyilvántartásban a személyekrıl négy adatot tartanak nyilván: magasság. Döntsük el. Határozzuk meg N (N>1) természetes számnál nem nagyobb. Határozzuk meg N db pozitív egész szám harmonikus közepét! 2. van-e ezen a tengerszakaszon sziget! 4. 96/312 . másutt >0. (összesen N mérést végeztünk) A méréseket szárazföld felett kezdtük és fejeztük be. Határozzuk meg a tengerszakaszok hosszát! d. Az elızı feladatból mondjuk meg a. 5 km-enként megmértük a felszín tengerszint feletti magasságát. ahol a mérés eredménye 0. Határozzuk meg két N dimenziós vektor skaláris szorzatát. életkor. Határozzuk meg. Hány szigeten jártunk? b. szemszín. ahol a legmagasabb csúcs van! c. 6. 3. akiket ez a nyilvántartás nem különböztet meg. Állítsunk elı 50 véletlen számot 1 és 500 között. legnagyobb négyzetszámot! 7. Állapítsuk meg hogy van-e két egyforma szélességő sziget! 5. hogy van-e két olyan személy. Adjuk meg azt a szigetet. hajszín. ha adottak a két vektor koordinátái.

N) mátrix. Válogassuk ki a hárommal nem osztható páros számokat! c. Az eredményeket egy sorozatban helyezték el úgy. x 30%. 2-es 20% valószínőséggel következik be.N) mátrix felsı háromszöge elemeinek összegét! 12. Mindegyik mőszer az i. A súly legyen az elem indexe a vektorban. 9. Keressük meg a legnagyobb 3-mal nem osztható. vegyük fogyelembe. hogy az 1-es 50%. 10. melyek a számjegyeinek összege öttel osztható! d. Adott A(N. és számítsuk ki minden egyes mérésnél a 9 mőszeren mért értékek átlagát! 11. de 7-el osztható számot! f. és így tovább. Válogassuk ki a 100-nál nagyobb páratlan számokat! b. adatát azonos pillanatban mérte. hogy a mátrix minden sorában az elemek összege 0 legyen! 97/312 . 3-as számjegyet tartalmazó számokat! e. hogy az elsı 100 szám az elsı mőszeren mért adatot jelenti. Válogassuk ki a 200-nál nem nagyobb és 300-nál nem kisebb számok közül azokat. Készítsünk egy totótipp-sort. Keressük azt a legkisebb számot. Határozzuk meg A(N.a. mely tartalmaz 3-as számjegyet! 8. Az X N elemő vektor elemein végezzük el a következı transzformációt: mindegyik elemet helyettesítsük saját magának és szomszédainak súlyozott átlagával. Egy mennyiség pontos mérését 9 azonos célmőszeren egyenként 100 alkalommal végezték el. ezt a második mőszeren mért adatok követik. Határozzuk meg az összes mérés átlagát. A mátrix fıdiagonálisába írjunk olyan értékeket. Válogassuk ki a 100 és 300 közé esı.

Egy színház pénztárának nyilvántartása tartalmazza.j) tömbelem az i. 14. 0 ha még szabad. Írjunk programot mely keres két szomszédos szabad helyet az adott elıadásra.. Határozzuk meg a csúcsok fokszámát! 16. majd megmondja. melyik tanuló hány jó választ adott. amely összehasonlítja a válaszokat a helyessel. ha az adott helyre szóló jegy már elkelt.j) ugyanezt a jobboldalon. Az A(N. és csak 1 jó. mely kiírja két számokat tartalmazó tömb közös elemeit! 98/312 . 15. A válaszokat egy mátrixban tároljuk. amelyekre az él illeszkedik. sor j.13.2) mátrixban egy gráfot ábrázoltunk: a mátrix egy sora a gráf éleit írja le úgy. Egy osztály tesztlapokat töltött ki. hogy egy adott elıadásra mely helyekre keltek már el jegyek. A helyes válaszokat tároljuk egy vektorban. Írj programot. Készítsünk programot. helyét jelenti a baloldalon. B(i. J(i. A tömbelem értéke 1. Minden kérdésre 4 lehetséges válasz volt. hogy megadja azoknak a csúcsoknak a sorszámát.

Programozás tankönyv VIII. Fejezet „Logikai ciklusok” Király Roland 99/312 .

és sokszor még az sem ismert. Az ismétlések megvalósításának az eszköze a ciklus-utasítás. melyek tetszıleges számban fordulhatnak elı. amikor valamely utasítást. hogy az utasításokat hányszor kell ismételni. Innen tudja a fordító. de javasolt a használatuk a 100/312 . … utasításn. hogy az utasításokat többször egymás után leírjuk. vagy utasítások sorozatát többször kell végrehajtanunk. jelezve ezzel a ciklus utasításainak a kezdetét és végét (egy utasítás esetén a zárójelek elhagyhatóak. A ciklus magjában lévı utasításokat. A ciklus magját kapcsos zárójelek { } közé kell tenni. és hol kezdıdik a következı utasítás. pontosvesszıvel választjuk el egymástól.A ciklusok A programozás során sokszor kerülünk szembe olyan problémával. Ebben a fejezetben a logikai ciklusokat nézzük át. } A fenti ciklus a while kulcsszóval kezdıdik. majd a zárójelek közti részben a ciklusban maradás feltételét kell megadni. mikor egy lépést ezerszer kell végrehajtani. A logikai ciklusoknak két alapvetı formája létezik a C# nyelvben. melynek több formája létezik. Kevés számú ismétlésnél megoldhatjuk a problémát olyan módon is (és ez a rossz megoldás). hogy hol végzıdik az aktuális. Ilyen és ehhez hasonló helyzetekben célszerő az iteráció használata. utasítás2. de gondoljunk arra az esetre. • • Elıl tesztelı while ciklus Hátul tesztelı do while ciklus A while ciklus A while ciklus általános formája a következıképpen írható le: while (feltétel) { utasítás1.

i).WriteLine(”{0}”. vagyis TRUE értékő. int i=0. Az elsı feldolgozást szimbolizáló téglalap csak akkor szükséges. A kapcsos zárójelek közti utasítás blokkot ismétli a rendszer mindaddig.programok jobb áttekinthetısége érdekében). amíg a feltétel igaz. A második feldolgozás blokk tartalmazza a ciklus utasításait. while (i<=10) { Console. } 101/312 . ha a ciklusban használunk ciklus változót. Folyamatábrával szemléltetve a while ciklus a következı formában írható le: A folyamatábra a while ciklus logikai modellje. Nézzünk meg egy konkrét példát a while ciklus használatára! A következı ciklus kiírja a 0-10 közötti egész számokat a konzol képernyıre. A ciklus feltétel része tartalmazza a ciklusban maradás feltételét. esetleg azt a ciklus bennmaradási feltételeként alkalmazzuk. ha van ciklusváltozó. i++. valamint a ciklus változójának léptetését. akkor azok alapján bármilyen while ciklust el tudunk készíteni. természetesen csak abban az esetben. Ha megértjük a folyamatábra és az általános forma mőködési elvét.

hogyan lehet tízes számrendszerbeli számokat átváltani kettes számrendszerbe. utasítással. namespace Atvaltas { class atvalt { [STAThread] static void Main(string[] args) { int[] t=new int[8]. vagyis az értékét minden lefutáskor növeljük meg eggyel. (A IV. A változó léptetésére a következı formulát használtuk: i++. k++. szam=szam / 2. j--. ez a rövidített forma megengedett. using System. A C típusú nyelvekben. int j. A következı példa bemutatja. while (j>=0) { Console. fejezetben az aritmetikai mőveletekrıl és azok rövidítésérıl bıvebben olvashattunk. s nem számláló ciklusként (arra ott van a for ☺). } j=k-1. és az i+=1. mert a for ciklussal ellentétben itt a rendszer errıl nem gondoskodik. } Console. hogy a ciklus változójának mindig adjunk kezdı értéket. Az elızı fejezetekben már láthattunk néhány példát a logikai ciklusokra. hogy a ciklus változóját léptetni kell. így a C# -ban is. } } } 102/312 .Write("{0}". (Emlékezzünk vissza a for ciklusra! Ott a ciklus változó növelése automatikus és nem is célszerő azt külön utasítással növelni). while (szam!=0) { t[k]=szam % 2.t[j]). ellenkezı esetben az ismétlések száma nem lesz megfelelı.) Ügyeljünk arra is. int k=0. Természetesen a while ciklust leginkább a logikai értékek vizsgálatakor használjuk. ekvivalens az i=i+1.ReadLine(). de ott nem részleteztük a mőködésüket. int szam=8.(Természetesen a fenti ismétlést megvalósíthattuk volna egyszerően for ciklussal is.) A while-t használó megoldásnál ügyeljünk arra.

hogy az ismétléseket addig kell végezni. Nulla érték esetén a ciklus befejezi futását. hogy ne csak a 8-as számra mőködjön. hogy ebben a ciklusban nem tudjuk elıre megmondani a lefutások számát. Több leállási feltétel együttes használatakor. vagy más néven feltételes ciklusokat alkalmazni. hogy a feltételek összekapcsolására && vagy || operátort használunk. hogy mikor célszerő logikai. mivel azok a feladat szempontjából nem értékes számjegyek. Ebbıl az következik. és az utolsó lefutáskor még növeltük a k értékét eggyel. illetve VAGY kapcsolatba hozni egymással. A tömb többi értékét nem vizsgáljuk. és az ismétlés befejezıdik. Vannak olyan problémák. • • • • Amennyiben nem tudjuk meghatározni a ciklus ismétlésinek a számát (futás közben dıl el). Több feltétel használatakor az egyes kifejezéseket. vagyis a k-1 helyen van. melyek az osztás során jöttek létre. amelyik a kettes számrendszerbeli számjegyeket írja a képernyıre. vagy a feltételek mindegyike hamissá válik. A második ciklusban. Az értékét nem növeljük. ahol mindkettıt használnunk kell egy kifejezésen belül. így az elsı ciklusunkban négy osztás történt. így a tömbben lévı számjegyeket visszafelé írjuk ki a képernyıre. hanem csökkentjük. A while ciklus ekkor addig fut. Az elızı három pont együttes fennállása esetén. (Próbáljuk meg átírni a fenti programot úgy.Az elsı while ciklus feltétele a (szam!=0). de csak azokat. mert az átváltandó számjegy a 8. Mindig gondoljuk végig. 0 0 0 1 0 0 0 0 Az átváltás után a k változó értéke 5. míg a feltétel minden része igaz. a ciklus változó kezdıértéke a k-1. ahány osztással elérjük a nulla értéket). logikai értékeket célszerő ÉS. Megfigyelhetjük. míg a szam változó értéke nullától nagyobb. a ciklus szempontjából azt jelenti. mivel az mindig a futás közben végrehajtott mőveletek eredményétıl függ (annyi lefutás van. hogy az utolsó értékes számjegy a negyedik indexen. Ha bármelyik rész-feltétel. Ha a leállás valamilyen logikai értéket szolgáltató kifejezés eredményétıl függ. Ügyeljünk a megfelelı zárójelezésre. 103/312 . hanem a felhasználótól beolvasott tetszıleges értékekre!) Vegyük sorra. akkor az egész kifejezés értéke hamis lesz.

s ez hibához vezet. i=0. hogy a feltétel mindig igaz. A break A C# nyelvben a while ciklusból ki lehet ugrani a break utasítással. hogy megáll. } i=0. a futása akkor áll meg. a második viszont hibásat. while ( (i<10) && (t[i] != 0) ) { Console. vagy rossz helyen történı alkalmazása nehezen észrevehetı hibákat eredményez. vagy ha megtaláljuk a nulla elemet. ha az i értéke eléri a tömb elemszámát.WriteLine(” {0} ”. } d += 1. Az alábbi két formula közül az elsı helyes eredményt produkál. mivel abban szándékosan elrontottuk a zárójelezést. ami azt jelenti. amit általában egy feltétel teljesüléséhez kötünk. vagyis az && operátor használatakor ügyeljünk a megfelelı zárójelezésre és a precedencia szabályra. Az alábbi ciklus feltétel részébe a true értéket írtuk. i += 1. while ( (i<10) || (t[i] != 0) ) { Console. A feltételes elágazásban a d=5 feltétel teljesülése esetén a break utasítás állítja meg a while ciklust. A zárójelek elhagyása. vagyis a ciklus soha nem áll meg. While (true) { if (d=5) { break. Az elsı jó eredményt fog szolgáltatni.WriteLine(” {0} ”. A második ciklus nem biztos. } Az ÉS kapcsolat.t[i]). while ( (i<10) && (a!=2)) while ( i<(10 && a)!=2) A rosszul felírt zárójelek miatt a fordító elıször a (10 && a) részt értékeli ki. i += 1.Vizsgáljuk meg az alábbi két ciklust. d = 0. } 104/312 .t[i]).

Ennek érdekessége az. a continue visszadobja a vezérlést a ciklus elejére. do { Utasítások. Ritkán használjuk. if (a<=0) continue.ReadLine() ). mivel a feltétel vizsgálata a ciklus végén van. } while (feltétel) A do while ciklust is érdemes felírni folyamatábrával. Amennyiben negatív szám érkezik az inputról.Parse( Console. } A programrészlet egy tömb elemeinek billentyőzetrıl való feltöltését valósítja meg úgy.A continue A continue utasítással visszaadjuk a vezérlést a while ciklus feltételére. i++. hogy negatív számokat nem fogad el. hogy jobban megértsük a mőködését. de mindenképpen meg kell ismerkednünk vele. A do while ciklus A ciklus utasítás következı típusa a hátul tesztelı változat. Ekkor a continue utáni rész teljesen kimarad az aktuális lefutáskor. 105/312 . while(i<tomb.Count) { int a = Int32. hogy a ciklus magja egyszer mindenképpen lefut. tomb[i]=a.

A foreach Van egy speciális ismétlés. char c. hogy ez 106/312 . Amíg a feltétel igaz. ha a c karakter típusú változóba a ”v” értéket adja meg a felhasználó. és nincs szükség ciklusváltozóra sem. } while (c!=’v’). a foreach. Ahogy a fenti példa is mutatja a do while ciklust jól használható ellenırzött.c). A következı példa egy lehetséges megvalósítását mutatja meg a hátul tesztelı do while ciklusnak. mellyel a tömböt.WriteLine(”Kilépés : v”). de egyszer mindenképpen lefut. Igaz.Write(”a beolvasott változó : {0}\n”. vagy győjteményt indexelnénk. vagy a tömbök végigjárására. így egyszer mindenképpen végrehajtódnak a ciklus magjában definiált utasítások. do { c=Console.Read(). mely képes a győjtemények. Az ismétlés akkor áll meg. vagy végjelig történı beolvasásra.A folyamatábrán jól látszik. Console. hogy a ciklusban maradás feltétele a ciklus utasításai után szerepel. Console. megáll. ha hamissá válik. Ez azt jelenti. a ciklus fut. hogy nem szükséges ciklusutasítást szerveznünk.

hogy ne kelljen figyelni a tömb elemszámát és a tömb elemeit se kelljen a programozónak indexelnie.’h’}. és a kezdıértékrıl is gondoskodnunk kell. s minden olyan probléma megoldásánál.’a’. A következı példában a while ciklussal felírt változatot láthatjuk.c). Fontosak a szöveges információk kezelésénél.’c’.’c’. Az aktuális tömb elem a c változóból olvasható ki. i = 0. } A példában a foreach sorra veszi a t tömb elemeit. vagy while ciklussal is megvalósíthattuk volna. 107/312 .Write(”{0}”.length()) { Console. de a teljesség kedvéért vizsgáljuk meg ezt a típust is! A foreach általános formája a következı: foreach (adattípus változó in tömbnév) { Utasítások.’r’. a fájlkezelésnél. amikor az iterációt for ciklussal nem lehet. hogy túl. hogyan kell használni a foreach utasítást: Char[] t=new char[] {’f’. Ez a program-részlet több utasításból áll.Write(”{0}”. vagy nem célszerő megvalósítani.’h’}. Természetesen a fenti program részletet for.’r’. while (i< t. } A feltétel vezérelt ciklusokat a programozás számos területén használjuk. i += 1. vagyis mikor végigjárta a tömböt. Az ismétlés az utolsó elem kiírása után áll le. char[] t=new char[] {’f’.t[i]).’e’. vagy alul indexeljük a győjteményt. Ráadásul a foreach használatakor nem fordulhat elı.’o’. } Az alábbi program részlet bemutatja. és az összetett adat szerkezetekkel még nem foglalkoztunk. szükség van egy ciklusváltozóra.nem logikai ciklus. melynek az értékét növelnünk kell.’o’. de a foreach-t pontosan arra találták ki.’e’. Foreach (char c in t) { Console.’a’.

hogy az prímszám-e! (Prímszámok azok a számok. melyek 3-mal és 5-tel is oszthatóak! 6. mely beolvas n db számot a billentyőzetrıl. Írjon programot. Írjon programot. mely beolvassa a billentyőzetrıl egy intervallum kezdı és végértékét. majd a végjel beolvasása után írja ki a legnagyobbat és a legkisebbet a kapott értékek közül. Állapítsa meg a felhasználótól beolvasott számról. majd meghatározza a számok átlagát. Az éppen beolvasott számnak írja ki a négyzetét. 10. hogy az csak a páros számokat írja a képernyıre! 3.Programozási feladatok 1. melyek csak önmagukkal és eggyel oszthatóak. Írassa ki a képernyıre az elsı n egész szám összegét! 4. A felhasználótól beolvasott számot a program váltsa át kettes számrendszerbe! végjelig (legyen a végjel -999999). Programja olvasson be a billentyőzetrıl egész számokat egy meghatározott 108/312 . Készítsen programot. 11. 9. Alakítsa át az elızı programot úgy. Írjon programot. Készítsen programot. mely kiírja az elsı n db páros szám összegét a képernyıre! 12.) 7. majd kiírja a képernyıre az intervallumba esı egész számok közül azokat. Írassa ki a képernyıre az elsı n egész négyzetszámot! 5. mely beolvassa a billentyőzetrıl az egész számokat egy meghatározott végjelig. mely kiírja a képernyıre az elsı tíz egész számot visszafelé! 2. Keresse meg az elsı n darab prímszámot! 8.

Fejezet „Szelekció emelt szint!” Radványi Tibor 109/312 .Programozás tankönyv IX.

És így tovább. valakinek az életkorát. vagyis ha az egyik feltétel teljesül.13 évig : gyerek 14 – 17 évig : fiatalkorú 18 – 23 évig : ifjú 24 – 59 évig : felnıtt 60 : idıs 110/312 . akkor a többit már nem kell vizsgálni sem. Az ábra szerint az Utasítás-4 akkor kerül végrehajtásra. klasszikus példát. A végrehajtás legfeljebb egy igaz ágon fog futni. A többágú szelekció folyamatábrája: Egymásba ágyazott if utasítások sorozatával tudjuk megvalósítani a fenti szerkezetet. Ilyenkor a feltételek közül legfeljebb egy teljesülhet.Szelekció haladóknak A szelekciónak több ága is lehet. Feladat: Olvassunk be egy nemnegatív egész számot. Hogyan valósítjuk ezt meg C#-ban? Ehhez nézzünk egy egyszerő. ha egyik feltétel sem teljesült. akkor a második feltétel kiérétkelése következik. Ha az elsı feltétel nem teljesül. Az utolsó else ág elhagyható. és kortól függıen írjuk ki a megfelelı szöveget: 0 .

vagy string kifejezés. Console.WriteLine("Ifjú"). akkor a default ág kerül végrehajtásra. switch (kifejezés) { case konstans1 kifejezés: utasítás1 ugrás case konstans2 kifejezés: utasítás2 ugrás case konstansn kifejezés: utasításn ugrás [default: utasítás ugrás] } Kifejezés: egész típusú. if (kor < 14) Console.ReadLine()).WriteLine("Fiatalkorú"). else if (kor < 24) Console.WriteLine("Idıs"). akkor a belépési ponttól számítva a további case-eket is feldolgozza. Ha elhagyjuk. else if (kor < 60) Console.ReadLine().Parse(Console. else if (kor < 18) Console. else Console. Default: Ha egyetlen case feltétel sem teljesül.Megoldás: static void Main(string[] args) { int kor. kor = Int32. 111/312 . } A többágú szelekció másik megoldása a switch utasítás.WriteLine("Gyerek"). Ugrás: Kilép avezérlés a case szerkezetbıl.WriteLine("Felnıtt").

WriteLine("nem választott megfelelı számot. case 2: Console. default: Console. k = Int32. } 112/312 . break. switch (k) { case 1: Console.ReadLine()).Parse(Console.WriteLine("3-at választotta"). break. break.Egy egyszerő felhasználás: static void Main(string[] args) { int k. Console. break. case 3: Console.WriteLine("1-et választotta").ReadLine().").Write("Kérem válasszon (1/2/3)").WriteLine("2-ıt választotta"). } Console.

switch (k) { case "1": Console. break.ReadLine(). k = Console.").ReadLine(). default: Console.WriteLine("nem választott megfelelı számot.WriteLine("3-at választotta"). stringek felhasználásával is: static void Main(string[] args) { string k. case "3": Console. break.WriteLine("1-et választotta"). } Console.Write("Kérem válasszon (1/2/3)").Ugyanez feladat megoldható konvertálás nélkül. break.WriteLine("2-ıt választotta"). break. } 113/312 . Console. case "2": Console.

WriteLine("Rendben"). és a harmadik lehetıség amikor a hónap száma nem jó.Parse(Console.ReadLine(). Console. második.WriteLine("A nap legfeljebb 28 lehet"). } Nézzük a lehetséges futási eredményeket. amikor minden rendben. Console. if ((ho == 1 || ho == 3 || ho == 5 || ho == 7 || ho == 8 || ho == 10 || ho == 12) && (nap > 31 || nap < 1)) Console. else if ((ho == 4 || ho == 6 || ho == 9 || ho == 11) && (nap > 30 || nap < 1)) Console. ho = int. 114/312 . de a nap nem helyes. A február legyen 28 napos.Write("Kérem a hónapot:").WriteLine("A nap legfeljebb 30 lehet").ReadLine()).ReadLine()). nap. amikor a hónap megfelelı.Feladat: Olvassunk be egy hónap és egy nap sorszámát! Írjuk ki ha a beolvasott számok nem jó intervallumba esnek.Parse(Console."). nap = int.WriteLine("A nap legfeljebb 31 lehet"). Megoldás: static void Main(string[] args) { int ho. else Console.Write("Kérem a napot:").WriteLine("A hónap csak 1 és 12 között lehet. Elsı. Console. else if ((ho == 2) && (nap > 28 || nap < 1)) Console. else if (ho < 1 || ho > 12) Console.

amikor minden rendben Második eset.Elsı eset. amikor a nap 45. 115/312 . ez nem lehet! Harmadik eset. amikor a hónap nem lehet 45.

Határozzuk meg az A(N) vektor elemeinek összegét úgy hogy a páratlan értékő elemek a (-1) szeresükkel szerepeljenek az összegben. 8. Elıször az idısebbeket. 3. Számoljuk meg. Adott egy természetes számokat tartalmazó vektor. hány pozitív érték van a vektor azon elemei között. és írja ki hogy melyik intervallumba esik. személyi száma. Adjon meghárom diszjunkt intervallumot. Olvassa be Zsófi. Olvasson be egy egész óra értéket. A negatívokat és a pozitívokat rakjuk át egy másik sorozatba. 5. Válogassuk ki a halak csillagképben született férfiak neveit (február 21 – március 20). Elemei közül válogassuk ki azokat. 7. 6. 22 – 3 Jó éjszakát. majd számoljuk meg hogy ezekbıl mennyi a negatív. Adott N ember neve. Írja ki a neveket udvariassági sorrendben. Köszönjön a program a napszaknak megfelelıen. Eztán olvasson be egy számot. Juli születési évét. Egy dobókockával 100-szor dobunk. amelyek indexe prímszám. Olvassunk be egy számsorozatot. 10 – 17 Jó napot. Kati. 116/312 . 4 – 9 Jó reggelt. melyek relatív prímek a 15-höz. 18 – 21 Jó estét. 2. Adjuk meg hogy ezek közül hány darab volt páros. Adott egy A(N) vektor.További megoldásra ajánlott feladatok 1. nulla. pozitív. 9. 4. illetve a párosak közül mennyit követett közvetlenül páratlan szám.

Programozás tankönyv X. Fejezet Stringek kezelése Király Roland 117/312 .

Az s="C:\hello" karakter sorozat hibás eredményt szolgáltat. hanem ún.) Fontos megemlíteni. ha elérési útként szeretnénk felhasználni. s="A2347". mint minden magas szintő nyelvben létezik a string típus. string s. akkor induláskor ’null’ értéke van. hogy a C alapú nyelvekben a \ (backslash) karakter ún. b += "ello". de mőködése eltér a számoknál megszokottól. Kiolvashatjuk. viszont a rendszer megpróbálja értelmezni. de dolgozni úgy tudunk velük.: karakterláncliterálként. hogy a fent szereplı értékadásban (s="1234567890") számok sorozatát adtuk értékül az s string típusnak. mint az összes többi programozási nyelv string típusával. Adhatunk nekik értéket: string a = "hello". a string-eket is deklarálni kell. Ilyen esetekben vagy s="C:\\hello" vagy s=@"C:\hello" formulát használjuk! Az elsı megoldásban az elsı \ jel elnyomja a második \ jel hatását. hogy a + mővelet értelmezhetı a string-ekre is. Hasonlóan a többi változóhoz. és minden olyan paraméterük. string w. Figyeljük meg. tulajdonságaik. Az OOP nyelvekben a string-ekre osztályként tekinthetünk.WriteLine(s). string b = "h". (A fejezet késıbbi témáinál kitérünk a + operátor mőködésére. így nem értelmezhetıek rá a numerikus típusoknál használt operátorok. vagy a kiíró utasításokban.A string típusú változó A C#-ban. Igaz.: escape szekvencia. mivel a \h -nak nincs jelentése. Az s változóban szereplı értékkel ebben az esetben nem számolhatunk. vagy éppen a képernyıre írhatjuk a bennük tárolt adatokat: string w=s. mely a többi osztálynak. 118/312 . s="1234567890". mert az nem numerikus értékként tárolódik. A második megoldásnál a @ jel gondoskodik arról. Ha egy string-nek nem adunk értéket. mivel vannak metódusaik. Console. hogy az utána írt string a "C:\hello" formában megmaradjon az értékadásnál.

vagy s=String.} if ( cmp < 0) {Console.} if ( cmp > 0) {Console. A strig-eket is használhatjuk konstansként. a teljes sring-re viszont csak a != és a == relációkat alkalmazhatjuk. Ugyanúgy definiáljuk ıket. mint a többi típus állandóit. Ahogy azt már említettük. if ( cmp == 0) {Console.: a szóközök eltávolításáról. A következı példa ezt be is mutatja: int cmp. vagy > relációba hozni egymással s[1]<s[2]. a keresés metódusainak definiálásáról. elágazások és logikai ciklusok feltétel részében. const string="string konstans". string str1="abc".WriteLine("str1 < str2"). mint a Pascal nyelv pos().WriteLine("str1 > str2"). Ha a kapott érték kisseb. mivel az abc karaktersor elıbb szerepel a sorrendben. A relációk használata kisebb megkötésekkel a string-eknél is megengedett. Ez némiképp megkönnyíti a használatukat. Az Objektum Orientált megközelítés elınyei jól nyomon követhetıek a string típus esetében. Az összehasonlításokat elvégezhetjük logikai kifejezésekben. C# nyelvben a string-ek is rendelkeznek metódusokkal. mint bármely más osztály. akkor str2 van elıbb.} A két string egynısége esetén a visszatérési érték 0. formában.CompareTo("szoveg"). a kis és nagybetős átalakításról. 119/312 . mint 0. A következı példaprogram bemutatja a string-ek használatának néhány lehetıségét. vagy copy() eljárásainál. A string-ek egyes elemeit tudjuk <. mint a cde. Az egységbezárás lehetıvé teszi.Empty formában jelezhetjük. ha nagyobb.WriteLine("str1 = str2"). hogy rendelkezzen saját metódusokkal. a következı megoldást használhatjuk: Str1. cmp="szoveg". mint 0. akkor az str1 ABC sorrendben elıbb van az str2 -nél. A példában a második if feltétele teljesül.Az üres string-et vagy s="".CompareTo(str2) Ezzel a metódussal össze tudjuk hasonlítani két string értékét. Ha mégis szeretnénk összehasonlítani két string-et. és nem kell külsı rutinokhoz folyamodnia. mert nem a programozónak kell gondoskodnia pl. string str2="cde".

ToUpper()).WriteLine("{0} .ban az s string TrimStart() metódusát használtuk.s.) A TrimStart().Kisbetőssé alakítottuk a sztringet.WriteLine("{0} .". mivel az elsı esetben string-et. Console.TrimEnd('a')). hogy az s=”alma” utasításnál a string-et macskakörmök (”…”) közé tettük. hogy a kettıt 120/312 .ReadLine().ToLower()). s="alma".".TrimStart('a')). Ez a string végérıl vágja el a megadott karaktereket.A string végérıl levágtuk az a karaktereket. } } } A program futása a következı: Az elsı WriteLine. A ToUpper() és a ToLower() metódusokkal a kisés nagybetős átalakításról gondoskodhatunk. Gyakori hiba.".Nagybetőssé alakítottuk a sztringet. a másodikban karaktert definiáltunk. mely eltávolítja a szöveg elejérıl a paraméter listájában megadott karakter összes elıfordulását. (Az aaalma string.using System. Console.s. A következı metódus a TrimEnd(). Vegyük észre. Console.s.WriteLine("{0} . míg a TrimStart() és TrimEnd() metódusok paramétereit aposztrófok (’…’) zárják közre.s. namespace String_01 { class Class1 { [STAThread] static void Main(string[] args) { string s. Console.A string elejérıl levágtuk az a karaktereket.". TrimEnd() és a Trim() metódusuk paraméterek nélkül a string elejérıl és végérıl levágják a szóközöket.bıl az lma stringet állítja elı.WriteLine("{0} . Console.

ezért a vizsgálat elıtt a beolvasott adatokat nagybetőssé alakítjuk. Az IndexOf() függvény -1 értéket ad vissza. találat esetén 0-tól a string hosszáig kaphatunk visszatérési értéket. a képernyıre írja a mondatot. vagy karaktersorozat nem szerepel a string. Amennyiben a szó szerepel a mondatban. Console. a szót és azt. hogy az adott string-hez jobbról és balról is hozzáfőzhetünk más string-eket.ben. hogy a szó szerepel-e vagy sem a mondatban. A következı példa megmutatja a Substring() használatát. hogy a string elsı eleme a 0. A következı példa bemutatja.konstanssal. akkor: s=”alma” s=s+” a fa alatt”. A string-bıl kimásolhatunk részeket a Substring() metódussal. A stringek-re a + mőveletet is értelmezhetı. vagypozitív értéket. és a másolandó karakterek számát. eredményül az ” a fa alattalma” karaktersort kapjuk. s=”a fa alatt”+s.Substring(1. Arra is figyelni kell. A C# nyelv kis-nagybető érzékeny (case-sensitive). de ilyenkor öszefőzésrıl beszélünk.2)). Ha a Substring() csak egy paramétert kap és a paraméter értéke belül van a string index tartományán. hogy mindig csak akkora indexet adjunk meg. hogy a tényleges tartalom alapján döntsünk. 121/312 . ha szerepel. Amennyiben a fenti értékadásban szereplı változót és konstanst felcseréljük. indexő elem.felcseréljük. az utolsó pedig a karakeszám-1. Az eredmény: ”alma a fa alatt”. A program beolvas egy tetszıleges mondatot és az abban keresendı szót. Ilyenkor a fordító hibát jelez. ha a paraméter listájában megadott karakter. 0. a kiemelt részlet ={0} ". akkor az adott indextıl a string végéig az összes karaktert kimásoljuk. ahány eleme van a string-nek. az s tartalma megváltozik. Amennyiben a fenti példában szereplı s stringek közé a + operátort írjuk.s.tól vannak indexelve. Ez azt jelenti. vagy karakterláncnak. ahonnan kezdjük a másolást. A keresés mővelete is szerepel a metódusok között. A paraméterezéskor ügyeljünk arra. melynek paraméter listájában meg kell adni a kezdı indexet. mivel a karakterek nem kezelhetıek stringként és fordítva. hogyan használhatjuk az IndexOf() metódust. kiegészül a + jel után írt sring. vagyis a kezdı indexét jelenti a keresett karakternek. ami a találat helyét.WriteLine("Az eredeti szó= alma. Mivel a stringek 0.

és ezekben átmásolni az eredeti változók tartalmát…) 122/312 . } } } A program futásának eredménye: A programunk megfelelıen mőködik. w=w. w=Console. s=s. s=Console.IndexOf(w)>-1) { Console.WriteLine("Gépeljen be egy tetszıleges mondatot : "). Nincs más dolga.s).w. Console. mőveleteket végezhetünk velük. mivel az eredeti mondatot nagybetősre alakítja.WriteLine("A(z) {0} szó nem a(z) {1} mondatban").ToUpper().namespace string_02 { class Class1 { [STAThread] static void Main(string[] args) { string s. a felhasználó által begépelt kis. majd ezt a formáját írja vissza a képernyıre.ReadLine(). azok tartalmát segédváltozókban tároljuk. Console. } Console. csak két újabb változót bevezetnie. A problémára több megoldás is létezik.ReadLine(). } else { Console.ReadLine().WriteLine("A(z) {0} szó szerepel a(z) {1} mondatban". string w.ToUpper(). Az egyik. amiket átalakíthatunk nagybetőssé. (Ezen megoldás elkészítése a kedves Olvasó feladata. majd a program végén az eredeti változók tartalmát írjuk ki a képernyıre.WriteLine("Adja meg a keresendı szót : "). hogy az eredeti változókat megırizzük. de az Output-ja nem tökéletes.nagy betőket vegyesen tartalmazó forma helyett. if (s.

ToString(). az ilyen típusú mőveletek kellı körültekintést igényelnek. A string-ekbe ún. Az értékadás eredménye az s 1-es indexő eleme.i<s. Amennyiben a for ciklusban egyenlıség is szerepelne (i<=s. hogy a string-ek elemenként is olvashatóak. vagy a karakterláncot. értékadó utasítás eredménye a következı hibaüzenet jelenik meg: Cannot implicitly convert type 'char' to 'string'.WriteLine("{0}". Ennél az értékadásnál már nem kapunk hibaüzenetet. s=s[1]. 123/312 . (Gyakori hiba kezdı programozóknál – ne kövessük el!) Az s string i. mint a karaktereket tartalmazó tömbökre. A 0. a string egy eleme karakter. mivel az s-nek elfogytak az elemei. } A fenti példában a string Length tulajdonságával hivatkoztunk a hosszára. Az értékadás akkor válik helyessé. Hivatkozhatunk rájuk elemenként.s[i]). Ezt a következı példán keresztül be is láthatjuk. vagyis az aktuális indexelt elem karakter típus. Az értékadásoknál inkább használjuk a típus megfelelı beszúró rutinját. ha az s[1] elemet konvertáljuk string-gé. for (i=0. Ezt túlindexelésnek nevezzük. eleme. string s=”123456789”.A string-ek mint vektorok A stringek kezelhetıek vektorként is. Annak ellenére.: rész string-eket szúrhatunk be az Insert() metódus segítségével.Length) a ciklus végén hibaüzenetet kapnánk. és a karaktert.i++) { Console. az elsı. A paraméter listának tartalmaznia kell az indexet. majd a ciklus magjában mindig az aktuális elemet írattuk ki a képernyıre. A hossz tulajdonság a string-ben szereplı karakterek számát adja vissza. vagyis az s[i]. ahova szeretnénk beszúrni. az utolsó elem indexe. A következı példa bemutatja az Insert() metódus használatát. mivel karakterek sorozatából épül fel. Az s=s[1]. Vagyis a két típus nem kompatibilis. a length-1.Length.

WriteLine("Gépelje ide a titkosítandó szöveget : "). key=Convert.i<s.Length. int i.ReadLine()). mőködése megegyezik a matematikai logikából ismert kizáró-vagy operátorral.) A C# nyelvben a XOR mőveletet a ^ karakter jelenti. Console.Write((char)(s[i]^key)).) using System.ReadLine().i++) { Console.ReadLine(). int key.WriteLine("Adja meg a titkosítás kulcsát (numerikus adat): "). A fenti programrészlet eredményeként az s változó tartalma az alábbi érték lesz: ”12ABCD3456” A következı példa megmutatja.s=”123456” s=s."ABCD"). namespace ConsoleApplication4 { class Class1 { [STAThread] static void Main(string[] args) { string s. } Console. hogyan tudunk tetszıleges szöveget a felhasználó által megadott kulcs segítségével titkosítani. (A titkosításhoz és a visszafejtéshez érdemes függvényt készíteni. Console. A titkosításhoz a XOR (kizáró-vagy) operátort használjuk fel.Insert(2. for (i=0. } } } A program kimenete a következı képen látható: 124/312 . a XOR újbóli alkalmazásával a string eredeti állapotát kapjuk vissza.ToInt32(Console. (Amennyiben a titkosított szöveget egy változóban tároljuk. s=Console.

de ahol megtaláljuk (ilyen a C# nyelv). mivel a XOR eredményeként kapott érték nem karakter. hanem maga a karakter látható. Console.A for ciklus kiíró utasításában a beolvasott szöveget alakítjuk át úgy. 125/312 . melyben osztályként használhatjuk. A Kiíró utasításban ún. Természetesen a string-ek használatának még rengeteg finomsága létezik. szorzására. hanem numerikus adat. (Természetesen a titkosított szöveg visszafejtése lehetséges. Ezzel a megoldással értük el. csak kiírtuk a képernyıre. és nagyon kevés olyan nyelv van. számos módszer létezik rá. olyan nagy számok összeadására. matematikus ismerısök ☺. pl. hogy a képernyın nem az adott karakter kódja.: karakter statisztikák. kódfejtı algoritmusok. hogy minden karakterét kizáró-vagy kapcsolatba hozzuk a felhasználótól kapott kulccsal. melyet az eredeti kulcs ismerete nélkül nem lehet visszaállítani.: típus-kényszerítést alkalmaztunk.Write((char)(s[i]^key)). Használhatjuk ıket számrendszerek közti átváltások eredményének tárolására.) A titkosítás eredményét az egyszerőség kedvéért nem tároltuk. mert megkönnyíti és meggyorsítja a programozást. éljünk vele. Ez által az eredeti szövegbıl egy matematikai úton titkosított szöveget kapunk. Sajnos nem minden programozási nyelv tartalmazza a string típust. melyekhez nem találunk megfelelı ”mérető” változókat. A string típus szinte minden komolyabb programban elıfordul. különösképpen igaz ez a fájlkezelı programokra.

stb. 5. Készítsen karakter statisztikát a felhasználótól beolvasott szöveg karaktereirıl! A statisztika tartalmazza az adott karaktert. Olvasson be egy számot egy string típusú változóba.) a billentyőzetrıl egy sring típusú változóba. majd alakítsa szám típussá! 9. mivel azok a mondat elején nem szerepelnek. Két mondatról döntse el. mely megszámolja.1*2. hogy a számlálandó betőt is a felhasználó adja meg! 4. hogy hány darab van belıle. Az inputként beolvasott szövegben cserélje ki az összes szóközt a # karakterre.6/2. ”c:\\alma”! 2. Olvasson be egy mondatot és egy szót! Mondja meg. a négy alap-mőveletet tartalmazó kifejezést (1+2. Írja a képernyıre a következı string konstansokat: ”c:\alma”. hogy a szó szerepel-e a mondatban! 7. Írjon programot. a programnak akkor is megoldást kell adnia! 12. hogy az inputként érkezı mondatban hány darab ”a” bető van! 3. Az elızı programot alakítsa át úgy.43. 8. Az input szövegbıl távolítsa el a szóközöket! 6. Állapítsa meg. A beolvasott mondat kisbetőit alakítsa nagybetősre. vagy a ”Géza kék az ég” visszafelé olvasva is ugyanazt jelenti.) Ügyeljen a mondatvégi írásjelekre. hogy az visszafelé is ugyanazt jelenti-e! (Az ”Indul a görög aludni”. hogy az input szövegben szerepelnek-e számok! 126/312 . és azt. majd a kifejezés értékét írja ki a képernyıre! 10. A beolvasott mondatról döntse el.Programozási feladatok 1. Olvasson be egy egyszerő. hogy azonosak-e! Ha a kis és nagybetők különböznek. a nagybetős karaktereket pedig kisbetősre! 11. majd az így kapott szöveget írja ki a képernyıre! 13.

Programozás tankönyv XI. Fejezet Eljárások alapfokon Oszd meg és szedd szét… Hernyák Zoltán 127/312 .

a visszatérési érték típusa kötelezıen void. kigyőjtés. Az eljárás (egyelıre) ’static void’ legyen. amennyiben nincsenek paraméterek.WriteLine("Készült: 2004. Ennek során olyan részeket különítünk el. a Main fv-tıl elkülönítve írjuk meg. Pl: static void Információ() { Console.van neve (azonosító). feltöltés.lehetnek paraméterei. bekérés. a program áttekinthetetlen lesz.Hosszabb programok írása esetén amennyiben a teljes kódot a Main tartalmazza. Console. és folytatódik tovább a program futása: 128/312 . listázás. és a zárójelpár megadása kötelezı abban az esetben is. úgy egyszerően hivatkoznunk kell rá a nevével (eljárás indítása. Console.WriteLine("*******************").11. és saját utasításblokkja van (a ’{’ és ’}’ közötti rész).van törzse. } A fenti példában az eljárás neve ’Információ’. Mindenképpen javasolt a kód részekre tördelése. Az eljárásnak . } Ekkor az adott ponton az eljárás végrehajtásra kerül. stb. elkülönített programrészletet eljárásnak nevezzük. önálló feladattal és névvel ellátott.WriteLine("Programozó: Kiss Aladár Béla").23"). maximális elem megkeresése. . ezeket a program külön részén. E részfeladatoknak jól hangzó nevet találunk ki (pl. majd a végrehajtás visszatér a hívást követı utasításra. Amennyiben a program adott pontján szeretnénk végre hajtani az eljárásban foglalt utasítássorozatot. amelyek önmagában értelmes részfeladatokat látnak el. Console. . eljárás meghívása): static void Main(string[] args) { Információ(). kiírás.). . Az ilyen.WriteLine("** Példa program **").

hogy ne csak a Main()-bıl hívjunk eljárásokat. függvényeket. aláhúzás karakterekkel folytatódhat (de nem tartalmazhat szóközt)! A C#-ban szabad ékezetes karaktereket is használni az eljárás-nevekben. Az osztály (class) mintegy csoportba foglalja az egy témakörbe. változókat. de nem javasolt – karakterkészlet és kódlap függı forráskódot eredményez. e miatt másik gépen másik programozó által nehezen elolvashatóvá válik a forráskód.Természetesen van rá lehetıség. Hová írjuk az eljárásainkat? Az Objektum Orientált programozás elvei szerint a programok építıkövei az osztályok. betővel. E miatt a program felépítése a következı lehet: 129/312 . hanem az eljárásokból is van lehetıség további eljárásokat hívni: C#-ban az eljárások neve azonosító. számjeggyel. ezért érvényes az azonosító névképzési szabálya: betővel vagy aláhúzással kezdıdik. feladatkörbe tartozó eljárásokat.

hogy a változók csak az ıket tartalmazó blokk-on belül ’láthatók’. 130/312 . } static void Feltoltes() { a=10. Ha mégis megpróbáljuk.WriteLine("{0}". } } Az egyéb eljárásainkat ugyanabba a csoportba (osztályba) kell megírni. A sorrendjük azonban lényegtelen. hogy a saját eljárásainkat a Main() fv elıtt. hogy az adott változót a program szövegében mely részeken lehet ’látni’ (lehet rá hivatkozni). Ennek oka a változók hatáskörének problémakörében keresendı. A szabály az.. static void Main(string[] args) { .. Minden változónévhez tartozik egy hatáskör. vagyis a változók hatásköre az ıket tartalmazó blokkra terjed ki. mivel az ’a’ változó hatásköre a ’Main’ függvény belseje. static void Main(string[] args) { int a=0. } A fenti kód hibás. namespace Tetszoleges_Nev { class PeldaProgram { Más eljárások . illetve írhatjuk ıket vegyes sorrendben is. Feltoltes()..a). } További eljárások . az ’a’ változóra a ’Feltoltes()’ eljárásban nem hivatkozhatunk. Ami fontos. Az eljárások egymás közötti sorrendje sem lényeges. vagy után írjuk le.. Az eljárások ’nem látják’ egymás változóit. akkor a C# fordító a The name 'a' does not exist … kezdető fordítási hibaüzenettel jelzi ezt nekünk. mint ahol a Main() fv található. hogy közös osztályba (class) kerüljenek. A programok eljárásokra tagolása persze újabb problémákat szül. mindegy.using System. Console... A hatáskör megadja.

WriteLine("{0}". Ha ezt elmulasztanánk. } } Azokat a változókat. Console. ezen érték a ’Feltoltes()’ eljárásbeli ’a’ változóba kerül bele.a). Ezért hiába tesszük bele az ’a’ változóba a ’10’ értéket.WriteLine("{0}". Ez a változó sajátja lesz a ’Feltoltes()’-nek. } static void Feltoltes() { int a=10. nem a Main()-beli ’a’ változóba.a). addig e változót más eljárásokban nem érhetjük el. amelyeket szeretnénk megosztani az eljárásaink között. Feltoltes(). két különbözı adatterületen helyezkedik el. ezért a közöttük megosztott változókat is ugyanúgy static jelzıvel kell ellátni. 131/312 . és nincs kivétel. amíg az ’a’ változót a Main() függvény blokkjában deklaráljuk. Mivel az eljárásaink static jelzıvel vannak ellátva. akkor a static eljárások nem ’látnák’ a nem static változókat. azokat az eljárásokat összefogó osztály (class) belsejében. A megoldás: ne itt deklaráljuk! class PeldaProgram { static int a=0.Ezt (hibásan) az alábbi módon reagálhatjuk le: static void Main(string[] args) { int a=0. } static void Feltoltes() { a=10. } Ekkor a ’Feltoltes()’ eljárásban is létrehozunk egy másik. de az eljárásokon kívül kell deklarálni. szintén ’a’ nevő változót. Console. ezért mindaddig. Hogyan kell megosztani változókat eljárások között? Mivel a hatáskör-szabály szigorú. de semmilyen kapcsolatban nem áll a ’Main()’ függvény-beli ’a’ változóval. A nevek azonossága ellenére ez két különbözı változó. static void Main(string[] args) { Feltoltes().

Write("A tomb {0}.... } //....... a tényleges mőveleteket eljárásokba szerveztük.......... és a Main() függvény írja ki a képernyıre..Nézzünk egy összetett feladatot: kérjünk be egy tíz elemő vektor elemeit billentyőzetrıl..... } A változók között meg kellett osztani magát a tömböt..Write("{0}........ és jól csengı nevet adtunk nekik: class PeldaProgram { static int[] tomb=new int[10].........tomb[i])....osszeg)........... } //... mert ezen változó értékét az ’OsszegSzamitas()’ eljárás számolja ki.............WriteLine("A tomb elemek osszege={0}" .... } //... for(int i=0.. static void Feltoltes() { for(int i=0........... static void Main(string[] args) { Feltoltes().....i).Length..... Console......Parse( strErtek )... ".. Figyeljük meg.. Console...... tomb[i] = Int32.....Length..... majd írjuk ki a vektor elemeinek értékét a képernyıre egy sorban egymás mellé vesszıvel elválasztva... string strErtek=Console....i++) { Console.............. static int osszeg=0....... hogy a Main() függvény nem tartalmaz lényegében semmilyen kódot.. majd számoljuk ki és írjuk ki a képernyıre a vektor elemeinek összegét..ReadLine()....WriteLine(). } } //........ OsszegSzamitas()....i++) osszeg = osszeg + tomb[i]. mert azt minden eljárás használta...i<tomb...i<tomb..................... 132/312 .... static void OsszegSzamitas() { osszeg=0...Length...... for(int i=0. //.......i++) Console...........i<tomb.... static void Kiiras() { Console..Write("A tomb elemei: ")......... Kiiras()................. eleme=".. Ezen túl meg kellett osztani egy ’osszeg’ nevő változót is..............

Programozási feladat: Készítsünk olyan eljárást. amely egy ilyen tömb 133/312 . és ezen értéket berakja egy megosztott ’maxI’ nevő változóba! 21. és elkészíti a két tömb különbségét egy ’kulonbseg’ nevő szintén megosztott tömbbe! Mekkora legyen ezen ’kulonbseg’ tömb mérete? 25. amely egy megosztott tömb elemeit kéri be billentyőzetrıl. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást. ahol a 0 jelenti a tócsát. Programozási feladat: Készítsünk olyan eljárást. amely két megosztott. feltöltött tömb elemeit mint halmazokat kezeli. amely egy feltöltött. hogy hány különbözı érték szerepel a tömbben! Az eredményt egy ’kulonbozo_db’ nevő megosztott változóba helyezi el! 22.Random osztály példányát kell használni)! 19.Feladatok: 16. és elkészíti a két tömb metszetét egy ’metszet’ nevő szintén megosztott tömbbe! Mekkora legyen ezen ’metszet’ tömb mérete? 24. Programozási feladat: Készítsünk olyan eljárást. Készítsünk olyan eljárást. és elkészíti a két tömb unióját egy ’unio’ nevő szintén megosztott tömbbe! Mekkora legyen ezen ’unio’ tömb mérete? 23. amely két megosztott. amely egy megosztott tömb elemei közül meghatározza a legnagyobb elem értékét. de nem enged meg ismétlıdést (két egyenlı értékő elemet nem fogad el)! 18. Egy arra járó sétáló maximum 4 egymás melletti tócsát képes átugrani egyszerre. feltöltött tömb elemeit mint halmazokat kezeli. Az ösvényt egy tömbben írjuk le. megosztott tömb alapján meghatározza. amely egy megosztott tömb elemeit kéri be billentyőzetrıl. és ezen értéket berakja egy megosztott ’max’ nevő változóba! 20. Programozási feladat: Egy ösvényen tócsák és száraz foltok váltogatják egymást. amely egy megosztott tömb elemeit generálja 100-900 közötti véletlen számokkal (a véletlen szám generálásához a System. de csak pozitív számokat fogad el! 17. Programozási feladat: Készítsünk olyan eljárást. amely két megosztott. amely egy megosztott tömb elemei közül meghatározza a legnagyobb elem sorszámát. Programozási feladat: Készítsünk olyan eljárást. feltöltött tömb elemeit mint halmazokat kezeli. az 1 jelenti a száraz foltot. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást.

amely egy megosztott tömb elemeit végigolvasva megadja. Programozási feladat: Készítsünk olyan eljárást. amely egy ’a’ tömb elemeit 1-gyel lejjebb csúsztatja! Az ’a’ tömb régi legelsı eleme legyen most a legutolsó (ciklikus csúsztatás)! 33. amely két egyenlı hosszú ’a’ és ’b’ vektor szorzatát számítja ki ( szorzat=a[0]*b[0]+a[1]*b[1]+…+a[n]*b[n] )! 35. 27. Programozási feladat: Készítsünk olyan eljárást. mint a tömb elemszáma. amelyek párosak. Programozási feladat: Készítsünk olyan eljárást. A maradék helyeket töltsük fel 0-kal! 31. amelybıl a tömb elemek származnak! 29. hogy a tömb elemei o a: növekvı sorrendbe vannak-e rendezve. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást. amely egy ’a’ tömb páros elemeit átmásolja egy ’b’ tömb elejére. hogy tócsába kellene lépnie! 26. Programozási feladat: Készítsünk olyan eljárást. ahol a tömb elemek növekvı sorrendben vannak! 28. akkor is helyesen mőködjön a program! 34. amely egy ’a’ tömb elemeit n-nel lejjebb csúsztatják ciklikusan! Az ’n’ értékét szintén egy megosztott változóból vegye ki az eljárás (n=0 esetén az elemek helyben maradnak. bemásolja egy ’b’ tömbbe. Az x értékét 134/312 . amely egy feltöltött tömb elemeinek ismeretében megadja a leghosszabb olyan szakasz elemszámát. egész számokkal feltöltött ’a’ tömb elemei közül azokat. Programozási feladat: Készítsünk olyan eljárást. amely egy polinom helyettesítési értékét számolja ki.alapján meghatározza. amely egy ’a’ tömb elemeit fordított sorrendbe bemásolja egy ’b’ tömbbe! 30. A polinom együtthatóit egy ’a’ tömb tárolja! A polinom általános alakja a[0]*xn + a[1]*xn-1 + a[2]*xn-2 + … + a[n]. amely egy. Programozási feladat: Készítsünk olyan eljárást. n=1 esetén elızı feladat)! Ha az n értéke nagyobb. o c: rendezetlenek. Programozási feladat: Készítsünk olyan eljárást. hogy a sétáló képes-e átjutni az ösvény egyik végébıl a másikba anélkül. a maradék elemeket pedig a ’b’ tömb végére! 32. amely egy feltöltött tömb elemeinek ismeretében megadja azt a legszőkebb intervallumot. o b: csökkenı sorrendbe vannak-e rendezve. Programozási feladat: Készítsünk olyan eljárást.

A számítás gyorsítására használjuk fel a Horner elrendezés adta elınyöket! 135/312 .az eljárás az ’x’ változóban találja meg.

Programozás tankönyv XII. Fejezet Függvények írása Számold ki és ide vele… Hernyák Zoltán 136/312 .

A függvény rokon fogalom az eljárással – egy apró különbséggel. A függvény egy olyan eljárás, amely olyan részfeladatot old meg, melynek pontosan egy végeredménye is van – egy érték. Amennyiben az a részfeladat, hogy egy értékekkel már feltöltött tömb eleminek összegét kell kiszámítani, a végeredmény egyetlen számérték. Amennyiben ezt eljárás segítségével oldjuk meg, úgy a végeredményt egy megosztott változóba kell elhelyezni. Ez sokszor nem túl szerencsés megoldás, mert a függvény kötıdik ezen megosztott változó nevéhez. Amennyiben egy másik programba szeretnénk ezt függvényt áthelyezni, úgy vele együtt kell mozgatni a megosztott változót is. Az ilyen jellegő feladatokat megoldó alprogramokat függvények formájában írjuk meg. Amennyiben függvényt akarunk írni, két fontos dolgot kell szem elıtt tartanunk: - A függvényeknél rögzíteni kell, hogy milyen típusú értéket adnak majd vissza. Ezt a függvény neve elıtt kell feltüntetni (a ’void’ helyett). - A függvények ezek után kötelesek minden esetben egy ilyen típusú értéket vissza is adni! A függvény visszatérési értékét a ’return’ kulcsszó után írt kifejezésben kell feltüntetni. Pl:
static int OsszegSzamitas() { int sum=0; for(int i=0;i<tomb.Length;i++) sum = sum + tomb[i]; return sum; }

A fenti részben e függvény egy egész számot fog visszaadni, ezt jelöljük a típusnévvel: int. A függvény saját változót használ fel segédváltozóként (sum) a számítás során, majd a függvény végén a return sum–al jelöli, hogy a sum változóban szereplı értéket (ami int típusú) adja vissza, mint visszatérési értéket. A függvények meghívása hasonlóan történik, mint az eljárások hívása. Csak mivel a függvény vissza is ad egy értéket, ezért gondoskodni kell róla, hogy ezen értéket a függvényt meghívó programrész fogadja, feldolgozza.
static void Main(string[] args) { Feltoltes(); Kiiras(); int osszesen=OsszegSzamitas(); Console.WriteLine("A tomb elemek osszege={0}",osszesen); }

Itt a meghívó ponton az OsszegSzamitas() függvény által visszaadott értéket a meghívó rögtön eltárolja egy ’osszesen’ nevő változóba, melybıl késıbb ki tudja írni a képernyıre ezen értéket.

137/312

Ebben a formában a program már nem kell, hogy megosszon ’osszeg’ változót, hiszen az ’OsszegSzamitas()’ már nem ilyen módon közli az eredményt a Main() függvénnyel, hanem egyszerően visszaadja azt.
class PeldaProgram { static int[] tomb=new int[10]; //................................................................ static void Main(string[] args) { Feltoltes(); Kiiras(); int osszesen=OsszegSzamitas(); Console.WriteLine("A tomb elemek osszege={0}",osszesen); } //................................................................ static int OsszegSzamitas() { int sum=0; for(int i=0;i<tomb.Length;i++) sum = sum + tomb[i]; return sum; } //................................................................ }

A 11. fejezetben felsorolt eljárások legnagyobb részét át lehet írni függvényekre. Vegyük például a maximális elem értékének meghatározását.
static int MaximalisElemErteke() { int max=tomb[0]; for(int i=1;i<tomb.Length;i++) if (tomb[i]>max) max=tomb[i]; return max; }

E függvény a megosztott ’tomb’ elemei közül keresi ki a legnagyobb elem értékét. Meghívása az alábbi módon történhet meg:
int maxElemErteke = MaximalisElemErteke(); Console.WriteLine("A tomb legnagyobb elemének értéke={0}", maxElemErteke);

Amennyiben azt szeretnénk ellenırízni, hogy egy adott érték szerepel-e egy – értékekkel már feltöltött – tömb elemei között, akkor az alábbi függvényt írhatnánk meg:

138/312

static bool Szerepel_E() { for(int i=0;i<tomb.Length;i++) if (tomb[i]==keresett_elem) return true; return false; }

A fenti függvényben kihasználjuk azt, hogy a ’return’ kulcsszó hatására a függvény azonnal megszakítja a futását, és visszatér a hívás helyére. Amennyiben az egyenlıség teljesül, úgy a keresett érték szerepel a tömbben, ezért a ciklus további futtatása már felesleges – megvan a keresett válasz. A ’return false’ utasításra már csak akkor jut el a függvény, ha az egyenlıség egyszer sem teljesült. Ekkor a kérdésre a válasz a false érték. A fenti függvény meghívása a következı módon történhet:
bool valasz = Szerepel_E(); if (valasz) Console.WriteLine("Nem szerepel a tömbben"); else Console.WriteLine("Szerepel a tömbben");

Más módja, hogy a függvény visszatérési értékét rögtön az ’if’ feltételében használjuk fel:
if (Szerepel_E()) Console.WriteLine("Nem szerepel a tömbben"); else a tömbben"); Console.WriteLine("Szerepel

A függvények ennél bonyolultabb értékeket is visszaadhatnak:
static int[] Feltoltes() { int[] t = new int[10]; for(int i=0;i<t.Length;i++) { Console.Write("A tomb {0}. eleme=",i); string strErtek=Console.ReadLine(); t[i] = Int32.Parse( strErtek ); } return t; }

A fenti függvény létrehoz egy int-ekbıl álló, 10 elemő tömböt a memóriában, feltölti elemekkel a billentyőzetrıl, majd visszaadja a feltöltött tömböt az ıt meghívónak:
int tomb[] = Feltoltes();

139/312

Amennyiben a feltöltött tömböt egy megosztott változóba szeretnénk tárolni, akkor azt az alábbi módon kell megoldani:
class PeldaProgram { static int[] tomb; //................................................................ static void Main(string[] args) { tomb = Feltoltes(); Kiiras(); ... } ... }

Ekkor a ’tomb’ változót elıször csak deklaráltuk, megadtuk a típusát. Majd a Main() függvény belsejében, a megfelelı idıpontban meghívjuk a Feltoltes() függvényt, és az általa elkészített és feltöltött tömböt betesszük a megosztott változóba.

140/312

Feladatok:
36. Programozási feladat: Készítsünk olyan függvényt, amely egy téglalap két oldalának ismeretében kiszámítja a téglalap területét! 37. Programozási feladat: Készítsünk olyan függvényt, amely meghatározza két szám legnagyobb közös osztóját! 38. Programozási feladat: Készítsünk olyan függvényt, amely eldönti egy számról, hogy hány osztója van! 39. Programozási feladat: Készítsünk olyan függvényt, amely eldönti egy számról, hogy prímszám-e! 40. Programozási feladat: Készítsünk olyan függvényt, amely megszámolja, hogy egy adott érték hányszor szerepel egy tömbben! 41. Programozási feladat: Készítsünk olyan függvényt, amely meghatározza két megosztott tömb elemeinek ismeretében a metszetük elemszámát! 42. Programozási feladat: Készítsünk olyan függvényt, amely meghatározza két megosztott tömb elemeinek ismeretében a különbségük elemszámát (hány olyan elem van a két tömbben összesen, amelyik csak az egyik tömbben van benne)! 43. Programozási feladat: Készítsünk olyan függvényt, amely meghatározza egy tömb elemeinek átlagát! 44. Programozási feladat: Készítsünk olyan függvényt, amely meghatározza egy tömbben hány 3-al osztható, de 5-el nem osztható szám van!

141/312

Programozás tankönyv

XIII. Fejezet

Eljárások és függvények középfokon
Hernyák Zoltán

142/312

Bemenı adatokat az eljárás azonban nem csak a megosztott változókban vehet át. átadván neki a két bemenı adatot. melyeket elhelyezhet megosztott változókban. A paramétereket az eljárás fejrészében kell feltüntetni. Aktuális paraméterlistában már sosem írunk típusokat. hiszen a formális paraméterlistában lényegében típusok és nevek vannak megadva. hanem konkrét értékeket! Kiiras(12. Az eljárás ezen adatok segítségével újabb értékeket állíthat elı. E változókban az eljárás a program elızı részei által elıállított adatokat kap meg. Az eljárás törzsében a paraméterekre a formális paraméterlistában feltüntetett azonosítókkal (név) hivatkozhatunk. Amikor ezen eljárást meg akarjuk hívni. A fenti eljárás kiírja a két számot a képernyıre.a. majd utána kezdıdik az eljárástörzs utasításainak végrehajtása.Amikor eljárást (vagy függvényt) írunk. Az eljárás törzsében ezekre a paraméterekre mint adott 143/312 . Bizonyos szempontból nézve a formális paraméterlista egyúttal változódeklarációnak is minısül. b=15). A fenti kódrészlet elindítja a Kiiras eljárást.int b) { Console. az alprogram törzsében sokszor hivatkozunk ilyen megosztott (közös) változókra. Így állít elı az eljárás kimenı adatokat. } A fenti példában ezen eljárás két bemenı értéket vár.a+b).15). Pl: static void Kiiras(int a. Mindkettı ’int’ típusú. és egy azonosítót (nevet) kell adni ezen adatoknak. A hívás helyén feltüntetett paraméterlistát (mely az aktuális bemenı adatok értékét tartalmazza) aktuális paraméterlistának hívjuk. majd a két szám összegét is.WriteLine("A {0}+{1}={2}". Fel kell sorolni vesszıvel elválasztva a bemenı adatok típusát. hanem paraméterekben is. akkor ezen eljárásnak a fenti bemenı adatokat át kell adni. ahol a többi eljárás megtalálhatja ıket.b. vagyis egész számok. Ezt a listát formális paraméterlistának hívjuk. Az eljárás elindulása elıtt feltölti a paraméterváltozókat az aktuális értékekkel (a=12. vagyis bemenı adatokat fogad.

amelynek a végeredménye jelen esetben ’int’ típusú. Hibásak az alábbiak: Kiiras(12. Ezen változók kezdıértékkel rendelkeznek. …) kompatibilisek egymással. A hívás helyére írhatunk számkonstanst (literál). majd kiírja az adott szám felét. Ezt a típus-megfelelıséget a kompatibilis típusok szabályai írják le.15). melynek típusa megfelel a formális paraméterlistában leírt követelményeknek. Ennek megfelelıen az aktuális és a formális paraméterlistára szigorú szabályok vonatkoznak: az aktuális paraméterlistában pontosan annyi értéket kell felsorolni. az ’int’-ek (sbyte. illetve változót is (ekkor a változó aktuális értékét adjuk át). persze ha az aktuális érték a kívánt típusban az adott pillanatban elfér. amennyit a formális paraméterlista alapján az eljárás vár tılünk. Egyelıre annyit jegyezzünk meg. // 12. int x=8.5.15*3-12). Kiiras(12).5 nem ’int’ ! // túl kevés paraméter Kiiras(12. Pl: static void Kiiras(double a) { Console. Az OO nyelvekben a típuskompatibilitást is az OO szabályai írják le. A konstans (literál) és a változó is kifejezésnek minısül. int. csak egyszerő kifejezés. } Ezen eljárás egy tetszıleges racionális számot vár.WriteLine("A szám fele={0}". hogy az aktuális paraméterlistában olyan kifejezést kell írnunk.típusú változókra hivatkozhatunk.20). float). a kezdıértékeket az aktuális paraméterlistában adjuk meg. 144/312 . Ezért általánosan azt mondhatjuk.20). az aktuális paraméterlistában pontosan olyan típusú értékeket kell rendre megadni.15. kifejezést – melynek kiszámítása int-et eredményez.a/2). Megállapíthatjuk. Kiiras(x. Kiiras(12).15). csakúgy mint a double típusok is (double. hogy az aktuális paraméterlistában olyan értéket kell írnunk. mint amilyet a formális paraméterlista szerint az adott helyen fel kell tüntetni. hogy az ’int’ kompatibilis a ’double’-val. // túl sok paraméter Kiiras(”Hello”. // a ”Hello” nem ’int’ típusú Helyesek az alábbiak: Kiiras(12. uint. Kiiras(3*4.x+2).

Ezen példa szerint is az aktuális érték egy ’int’ típusú érték. ez általános esetben nem biztonságos. hanem egy egész számot adtunk át. Kiiras_Egesz (z).WriteLine("A szám kétszeres={0}".5. Kiiras(x). a fogadó oldal (formális paraméterlista) csak egész típusú értéket tud átvenni. A hívás helyére olyan típusú kifejezést 145/312 . } double z=12.5 értéket. Értelemszerően a küldı oldal (aktuális paraméterlista) hiába próbálná átadni a 12.Ebben az esetben az aktuális paraméterlistában nem egy tört. még akkor sem. ha … double z=12. Ekkor hiába van a ’z’ változóban olyan érték.a*2). Ezért ezt a paraméterátadást a C# fordító nem engedi. int x=12. Kiiras_Egesz (z). Ez ugyan nem pontosan ugyanolyan típusú. de az aktuális érték (12) konvertálható (kompatibilis) a kért típusra. amelyet a fogadó oldal akár át is tudna venni. de ez elfogadható. mint amit a formális paraméterlistában leírtunk. Fordítva nem igaz: static void Kiiras_Egesz(int a) { Console. ha a fogadó oldalon akár ’double’-t is képesek vagyunk fogadni.

Itt az ’x’ változó típusa ’int[]’.Write("A tomb elemei: "). hogy a típusok ennyire eltérjenek egymástól.Length. A tömb elemei ’int’ típusú értékek kell hogy legyenek. for(int i=0. 146/312 .Write("{0}. így helyes is. A hívás helyére ekkor természetesen egy ennek megfelelı értéket kell írni: int[] x = new int[10].i<tomb. Kiiras( x ). ezért a fenti eljáráshívás típusában megfelelı.kell írnunk. amely ennél több garanciát ad. Ennél persze bonyolultabb típusok is szerepelhetnek a formális paraméterlistában: static void Kiiras(int[] tomb) { Console. } A fenti példában a ’Kiiras’ eljárás egy komplett tömböt vár paraméterként. ami megfelel a fogadó oldali elvárásoknak.WriteLine(). Console. Ezért nem engedi meg a C# fordító.i++) Console. ".tomb[i]).

mindkét tömbben 3-3 szám van! A tömbök egy-egy háromszög oldalainak hosszát írják le! Adjuk vissza a nagyobb kerülető háromszög kerületének értékét! 47.Feladatok: 45. Programozási feladatok: készítsünk olyan függvényt. amely kap paraméterként két számot. int típusú tömbben a leghosszabb egyenlı elemekbıl álló szakasz hosszát! 48. és visszaadja a két szám közül a nagyobbik értékét! Amennyiben a két szám egyenlı. amely kap két int tömböt paraméterként. amely meghatározza egy paraméterben megadott. Programozási feladatok: készítsünk olyan függvényt. amely egy megosztott tömböt feltölt véletlen elemekkel egy megadott intervallum elemei közül úgy. Programozási feladatok: készítsünk olyan eljárást. hogy két egyenlı érték ne forduljon elı a tömbben! Az intervallum kezdı és végértékeit paraméterként adjuk át! 147/312 . Programozási feladatok: készítsünk olyan függvényt. úgy az elsı szám értékét kell visszaadni! 46.

Fejezet Eljárások és függvények felsıfokon Hernyák Zoltán 148/312 .Programozás tankönyv XIV.

és a fogadó oldalon szereplı ’a’ változó között minden további kapcsolat megszőnik.WriteLine("A hivas utan az x erteke x={0}". 149/312 . ha a paraméter típusa tömb. Kiiras(x. marad benne a 12.a. Console. akkor a tömbelemeken keresztül azonban igen. } Ha a fenti eljárást az alábbi módon hívjuk meg … int x=12. de utána a hívás helyén szereplı ’x’ változó.int b) { Console.: static void Kiiras(int a. A helyzet igen bonyolult mindaddig. E miatt az a=a+b értékadás eredménye is ezen a külön területen kerül tárolásra. az nem fogja befolyásolni az ’x’ értékét.b. amíg a referencia típusú változókkal alaposan meg nem ismerkedünk. Pl. Ekkor az aktuális paraméterlistában feltüntetett értéket a fogadó oldal átveszi – a nélkül. A fenti technikát érték szerinti paraméterátadásnak nevezzük. és nem zavarja. double. az ’x’ aktuális értéke (12) átmásolódik a memória külön területén helyet foglaló ’a’ változóba. string.Kérdés: tudunk-e a paraméterváltozókon keresztül értéket visszaadni? Erre sajnos a C#-ban nem egyszerő válaszolni. nem változtatja meg az ’x’ értékét. Mint az ábrán is látszik. Addig is használjuk az alábbi szabályokat: amennyiben a paraméterváltozók típusa a nyelv alaptípusai (int. hogy a kapcsolatot fenntartaná.a+b). … ekkor kiíráskor az ’x’ változó értéke még mindig 12 lesz.20).WriteLine("A {0}+{1}={2}". Az érték egyszerően átmásolódik a fogadó oldal változóiba. char. úgy nem tudunk értéket visszaadni a hívás helyére. Ezért hiába teszünk az ’a’ változóba az eljáráson belül más értéket (a+b). …) közül valamelyik. Mivel a paraméterátadás során a híváskori érték (12) átadódik az eljárás ’a’ változójába mint kezdıérték (a=12).x). a = a+b.

Egy ’int’ típusú érték tárolása csak 4 byte. ezért az eljárás lefutása után a kisTomb[0] értéke már 10 lesz. double. Egyelıre fogadjuk el szabályként. amelyek esetén a ’new’ kulcsszót kell használni az érték megadásakor (példányosítás). amikor átadjuk a ’Feltoltes’ eljárásnak. A hívás helyén szereplı kis tömb még feltöltetlen. string. tombelem={0}”. ezért nehéz felismerni. hogy azok a változók lesznek referencia típusúak. Console. kisTomb[0] ). … de a tömböknél igen: int[] tomb = new int[10]. Az elsıdleges területen ilyenkor mindig egy memóriacímet tárol a rendszer.WriteLine(”A 0. } static int[] kisTomb=new int[10]. míg a fenti tömb tárolása 40 byte. char. Ezen memóriacím a másodlagos memóriaterület helyének kezdıcíme lesz. …) értékének képzésekor nem kell a ’new’ kulcsszót használni … int a = 10. Az ilyen jellegő változókat általában az jellemzi. Az eljárás fogadja a tömböt a ’tomb’ változóban. Ezen változás azonban beleíródik a ’kisTomb’ által reprezentált tömb-be is. A referencia-típusú változóknál dupla memóriafelhasználás van. Ezen másodlagos memóriaterületet a ’new’ hozza létre. hogy viszonylag nagy memóriaigényük van. vagy egyéb jelzés. Feltoltes( kisTomb ). majd megváltoztatja a ’tomb’ elemeinek értékét. Az ilyen jellegő paraméterátadást referencia-szerinti átadásnak nevezzük! A referencia típus nem jelentkezik külön a változó deklarációja során mint külön kulcsszó. 150/312 .Amennyiben azonban a paraméterátadás-átvétel során tömböket adunk át. úgy a helyzet megváltozik: static void Feltoltes(int[] tomb) { tomb[0] = 10. Az nyelvi alaptípusok (int.

} A referencia típusú változók esetén azonban nem másolódik le az érték még egyszer a memóriában (ami a tömb esetén a tömbelemek lemásolását jelentené). ami valójában átmásolódik a ’tomb’ váltózóba. A fenti ábrán látszik. static void Kiiras(int a) { . hanem csak a szóban forgó tárterület címe (memóriacíme) adódik át. és ha beleír ebbe a memóriaterületbe. és nem ténylegesen a tömb elemei.. ez az. } static int[] kisTomb=new int[10].. Feltoltes( kisTomb ). hogy a ’kisTomb’ változónk aktuális értéke átmásolódik a ’tomb’ aktuális értékébe. Ekkor a fogadó oldal megkapja a memóriaterület címét. akkor azt a küldı oldal is észlelni fogja majd: static void Feltoltes(int[] tomb) { tomb[0] = 10. Csakhogy a ’kisTomb’ értéke egy memóriacím. Kiiras(x).Az érték szerinti paraméterátadás során az érték az átadás pillanatában két példányban létezik a memóriában – lemásolódik: int x=12. 151/312 .

Mivel a ’tomb’ változó is ismerni fogja a tömbelemek tényleges helyét a memóriában. hogy csak pozitív számot fogad el. akkor azt meg is változtathatja. melynek végeredménye egy referencia: Feltoltes( new int[20] ). hogyha a fogadó oldal megkapja a terület kezdıcímét. A referencia-szerinti paraméterátadás is érték szerinti paraméterátadás. tomb[i] = x. if (x<0) continue. Ezt a kezdıcímet általában egy megfelelı típusú változóban tároljuk el. hiszen mindkét esetben ugyanazokra a tömbelemekre hivatkozunk a memóriában. Amennyiben a fogadó oldalon referencia típusú paramétert fogadunk. 152/312 . A feltöltött tömb címét (referenciáját) visszaadja. Ez az oka annak. mint amit megkapott. ezért amennyiben megváltoztatja azokat. mely mint érték másolódik át a paraméterváltozókba.i<tomb. int x = Int32.Write("A tomb {0}. } Az elızıekben bemutatott függvény paraméterként megkapja egy int típusú tömb kezdıcímét. úgy a küldı oldalon csak olyan kifejezés szerepelhet. Mivel az eredeti változó is ugyanezen területre hivatkozik.Parse( strErtek ). a változó értéke ilyenkor egy memóriacím.i). úgy a változtatásokat a ’kisTomb’-ön keresztül is el tudjuk majd érni. úgy a memóriacímet tárolás nélkül átadhatjuk egy eljárásnak paraméterként. A new foglalja le számára a memóriát. ennek nem sok értelme látszik. eleme=". string strErtek=Console. Mivel a függvény ugyanazt a memóriacímet adja vissza.) { Console. A tömb elemeit billentyőzetrıl tölti fel oly módon. hogy a tömbelemek értékének módosítása a fogadó oldalon maradandó nyomot hagy a memóriában – amikor az eljárás már befejezte a futását. } return tomb.Length. (pl: kiolvasni) lehet.ReadLine(). Az már más kérdés. static int[] Feltoltes(int[] tomb) { for(int i=0. ezért a változásokat a küldı oldalon késıbb észlelni. majd visszaadja a terület kezdıcímét. Figyeljük meg azonban a hívás helyét: int[] ertekek = Feltoltes( new int[40] ). de amennyiben erre nincs szükség. az értékek akkor is hozzáférhetıek. i++. Az elızıekben bemutatott kifejezés létrehoz egy 20 elemő int tömböt.

a függvény feltölti ezt a tömböt elemekkel. Az átmenı paraméterek egyidıben bemenı és kimenı paraméterek. osszeg = osszeg + tomb[i]. Ugyanakkor a ’ref’ kulcsszó ennél többet jelent – a ’ref’ paraméterben értéket is adhatunk át az eljárás számára. hanem rögtön átadjuk a függvények.i++) if (tomb[i] % 2 == 0) { db++. üresen (csupa 0-val inicializálva). és összegét.i<tomb. hogy az adott paraméterben értéket is vissza szeretnénk adni.y). Console. Amennyiben a Feltoltes() csak egy eljárás lenne.x. Egy függvény csak egy értéket adhat vissza.WriteLine("A paros elemek db={0}. osszeguk={1}". úgy az alábbi módon kellene meghívni: int[] ertekek = new int[40].Length. ParosElemek(tomb. ezért nem írhatjuk meg függvényként. Mivel ez már kettı darab érték. mert egy sorban oldja meg a tömb létrehozását. feltöltését. hogy az átadott változóban kimenı adatokat várunk: int x=0. és meg is változtathatjuk. ref int osszeg) { db=0. A ’ref’ kulcsszóval kell jelölni. ref x. for(int i=0. 153/312 . Az eljárásban ezen paraméter értékét felhasználhatjuk.y=0.A hívás helyén a frissen elkészített tömb memóriacímét nem tároljuk el. úgy azt jelölni kell: static void ParosElemek(int[] tomb. ref y). Az ilyen jellegő paraméterátadást cím szerinti paraméterátadásnak nevezzük. osszeg=0. majd visszaadja az immár feltöltött tömb címét. } } A fenti eljárás két értéket is elıállít – a páros tömbelemek számát. Feltoltes( ertekek ). Ez a paraméter klasszikus átmenı paraméter. Ekkor a hívás helyén is jelölni kell. A tömb a hívás helyén készül el. Amennyiben egy alaptípusú paraméter-változón keresztül szeretnénk értéket visszaadni. ref int db. A fenti megoldás azért szép.

out int db. ’in’ módosító nincs a C#-ban.summa. osszeg = osszeg + tomb[i]. } } A hívás helyén is: int dbszam. out dbszam. és a függvényben kötelezı értéket adni ezeknek a paraméterváltozóknak a függvény visszatérési pontja (return) elıtt. ugyanis a paraméterek alapértelmezésben bemenı adatok.i<tomb. Valamint egy ’out’-os paraméterváltozót a fordító kezdıérték nélkülinek tekint.int x. } 154/312 . Az ilyen paramétereket nem a ’ref’. A probléma forrása az. hiszen a függvény db és osszeg paraméterváltozóinak kezdıértéke érdektelen. b=c.Length. A ’ref’ és az ’out’ módosítók között az egyetlen különbség. ref int b) { int c. Amennyiben a paraméterként átadott változók nem rendelkeznének értékkel a hívás pillanatában (definiálatlan változó). ref x. hogy e paraméterek csak kimenı értékeket hordoznak.y). vagyis az ’in’ módosítót ki sem kell írni. A ’ref’ esetén a függvényhívás elıtt a változóknak kötelezı értéket felvenni. ParosElemek(tomb. c=a. Aki esetleg keresné. Ez a fenti függvény esetén egyébként értelmetlen. Console. static void Csere(ref int a. for(int i=0. hogy a hívás helyén (aktuális paraméterlistában) szereplı változóknak ’out’ esetén nem kötelezı kezdıértéküknek lenniük.i++) if (tomb[i] % 2 == 0) { db++. osszeg=0. osszeguk={1}".y. a=b. ParosElemek(tomb.x.WriteLine("A paros elemek db={0}. és a függvényben nem kötelezı azt megváltoztatni. hanem az ’out’ kulcsszóval kell megjelölni! static void ParosElemek(int[] tomb. úgy a C# fordító szintaktikai hibát jelez. out int osszeg) { db=0. out summa). bemenı értékük érdektelen. ref y).

ezért a ’ref’ kulcsszót kell használni.i++) for(int j=i+1.i<tomb.Length.A fenti eljárás a paramétereként megkapott két változó tartalmát cseréli fel. Mivel ilyenkor érdekes a paraméterek aktuális értéke is.ref tomb[j]). } 155/312 .j<tomb. A fenti eljárás kitőnıen felhasználható egy rendezı eljárásban: static void Rendezes(int[] tomb) { for(int i=0.Length-1.j++) if (tomb[i]>tomb[j]) Csere(ref tomb[i].

Fejezet „WinForm” Radványi Tibor Király Roland 156/312 .Programozás tankönyv XV.

A kivétel kezelı eljárások lényege. mely eszköz segítségével a programjainkba hibakezelı (kivétel kezelı) kódrészleteket építhetünk. s=Console. try { for (i=0. melyek a try blokkban keletkeznek. Most nézzünk meg egy példát a try használatára! using System. Console.i. A catch segítségével azokat a kivételeket kaphatjuk el.i++) { Console. A try és a catch A try parancs segítségével a programok egyes részeihez hibakezelı rutinokat rendelhetünk. hogy milyen rutinok fussanak le és hogyan kezeljék a felmerülı hibákat.ReadLine(). de errıl majd bıvebben szólunk a fejezet késıbbi részeiben. s ami nagyon fontos.A Windows Formok Hibakezelés A C# nyelv a futásidejő hibák kiszőrésére alkalmas eszközt is tartalmaz.i<20.s[i]). melyek hiba esetén az általunk megírt hibakezelı eljárásokat hajtják végre.WriteLine("Kérem gépeljen be egy tetszıleges mondatot!").WriteLine("Az s string {0}. eleme = {1}". hogy elkerüljük a futás közbeni hibák esetén felbukkanó hibaüzeneteket. megakadályozzák a program leállását. és megvédjük programjainkat a váratlan leállástól. namespace ConsoleApplication6 { class Class1 { [STAThread] static void Main(string[] args) { string s. int i. Itt határozhatjuk meg. A catch segítségével különbözı hibák egyidejő kezelését is megvalósíthatjuk. } } catch 157/312 .

{ Console. namespace ConsoleApplication4 { class Class1 { [STAThread] static void Main(string[] args) { int i. i=Convert.ReadLine(). A következı programban erre láthatunk példát. try { Console.. Ebbıl a példából is jól látható milyen nagy szükség lehet a kivételkezelıre.WriteLine("Hiba a program futása során.} Console. Abban az esetben. a programunk leáll. Amennyiben az inputról nem megfelelı adatok érkeznek. mőködésbe lép a kivétel-kezelés. és a hiba kezelését a . mivel a try a catch blokkhoz irányítja a vezérlést.Message).ReadLine(). és a beolvasásnál 20 karakternél rövidebb mondatot adunk meg. Fokozottan érvényes ez azokra a programokra. A catch hibakezelı rutinjait szintén kapcsos zárójelek közé kell írni.ReadLine()). 158/312 . vagyis a képernyın megjelenik a hibaüzenet.ToInt32(Console. ahol a felhasználó adatokat visz be.NET vagy az operációs rendszer veszi át.WriteLine(e. using System.WriteLine("Az i értéke? : "). hogy hol kezdıdik és végzıdik a hibakezelés. a hibakezelı eljárás elindul. } catch(Exception e){Console. } } } Amennyiben futtatjuk a fenti programot.").. A catch blokkban definiált hibakezelı rész lefut. hogy a try után kapcsos zárójelek közt adjuk meg a hibát okozható program részletet. a catch blokkban elkapjuk a hibát és kiírjuk az okát a képernyıre. } Console. } } } A programban látható. ha nem használjuk a hibakezelı eljárásokat. ha jól mőködı programokat akarunk írni. ezzel jelezve a fordítónak.

} catch (ArithmeticException ar) { Console. ha az általános hibák elé helyezzük azokat a hibákat.ar). melyek egy bizonyos típusú hiba elfogására alkalmasak. illetve gyakran túlságosan sok. amit az e. A paraméterként megadott változó System. } A catch blokkok sorrendje sem mindegy. try { c = 10 / a + 30.: a fenti matematikai hiba.Message rutinnal kapunk meg.Message). ha megállapítjuk a hiba okát. 159/312 . melybıl kiolvashatjuk a hiba okát. Sokkal jobb megoldás.Exception e ) { Console. a hiba típusának meghatározására. A catch parancs a kivételt paraméterként is fogadhatja. és a javított hibáért a felhasználó nem is haragszik annyira… Talán még elismerıen bólint is…) Írhatunk olyan catch blokkokat is. catch ( System. double c.WriteLine(e.WriteLine("Aritmetikai hiba : {0}". A helyes megközelítés az. melyekre már eleve számítani lehet a programban. hogy a programunk használóját hosszú. Ráadásul a felhasználó nem is nagyon tudja kezelni a keletkezett hibákat. //hibák kezelése } A képernyın megjelenı hibaüzenet nem nagyon beszédes. mert így nem teszünk többet. hogy a try blokkban elıforduló bármely hiba esetén ugyanaz a hibaüzenet jelenik meg a képernyın. (Ekkor még mindig ráérünk kiírni a képernyıre. Az ilyen jellegő hibákra az elızı kód nincs felkészítve. mint az eredeti hiba-ablak.Exception típusú. nehezen érthetı információt tartalmaz. mivel nem definiáltuk a lehetséges hibákat. értelmezhetetlen üzenetekkel terheljük. A célunk sem az.A fenti példában a túlindexelés és a típus különbségek mellett elıfordulhatnak más hibák is. hogy hiba történt. melyek a program írásakor rejtve maradnak. A catch blokkban lehetıségünk van a különbözı okok miatt keletkezett hibák szétválasztására. int a=0. majd a megfelelı hibakezelés aktivizálásával meg is szüntetjük azt. Ez azt jelenti. ahogy a fenti példában láthattuk. még annak ellenére sem. mint pl. és a megfelelı hibakezelıt indíthatjuk el. hogy kiírjuk a képernyıre a hiba minden paraméterét.

Kivétel neve MemberAccesException ArgumentException ArgumentNullException ArithmeticException Leírása Tagfüggvény hozzáférési hiba Hibás tagfüggvény-paraméter Null értékő tagfüggvény paraméter Matematikai mővelet-hiba ArrayTypeMismatchException Tömbtípus hibája (érték tároláskor) DivideByZeroException FormatException IndexOutOfRangeException InvalidCastException NotFiniteNumberException NullReferenceException NotSupportedException OutOfMemoryException OverflowException StackOverflowException TypeInitializationException Nullával való osztás Hibás paraméter-formátum Tömb túl. Tipikus példa erre a fájlkezelés. vagy alulindexelése Érvénytelen típus átalakítás A keletkezet érték nem véges (hibás számalak) Null értékre való hivatkozás Nem támogatott tagfüggvény Elfogyott a memória Túlcsordulás (checked esetén) Verem túlcsordulás Hibás típus beállíás (static kontruktornál) A finally blokk Sokszor lehet szükség arra is. try { c=10/a. } 160/312 . A finally blokkban elhelyezett kód mindig lefut.WriteLine("Aritmetikai hiba : {0}". } catch (ArithmeticException ar) { Console.A System névtérben rengeteg kivétel típust definiáltak. (Nem igaz ez arra az esetre. Az ilyen típusú problémákra nyújt megoldást a finally kulcsszó. hogy egy program részlet hibás és hibátlan mőködés esetén is lefusson. ha a program végzetes hibával áll le. függetlenül az elıtte keletkezett hibáktól. A fontosabbakat az alábbi táblázatban foglaltuk össze. ahol a megnyitott fájlt hiba esetén is le kell zárni.ar).) A következı példa bemutatja. double c. hogyan alkalmazhatjuk a nyelv finally kulcsszavát: int a=0.

és egy tetszıleges catch blokkal el is kaphatjuk. A kivétel feldobását a throw végzi. throw (exception). az a Main() függvény szintjén is megjelenik. return t[vm]. Amennyiben nem kapjuk el sehol. (Ha nem kapjuk el. ezt egy kivétel dobásával jelezzük. bárhol ”dobhatjuk” a kivételt a throw segítségével. Amennyiben nincs már elem a veremben. ami legtöbbször azt jelenti. hogy a programunk leáll. } else throw new Exception(”Üres a verem”). A program bármely szintjén. A konstruktor paramétere egy string. így példányosítani kellett. A kivételek dobása a throw kulcsszóval történik. mivel a definiált kivétel is egy osztály. melynek paramétere egy exception osztály: Exception(”Hibaüzenet”).) 161/312 .WriteLine("A program ezen része mindenképpen lefut"). A kivétel dobásakor a new kulcsszót használtuk. class Verem { public Object Pop() { if (vm>0) { vm--. melyben a hibaüzenetet adhatjuk meg. ha az nem üres. throw exception. } } A példában a verem tetejérıl akarunk levenni egy elemet akkor. A következı példa bemutatja. az operációs rendszer akkor is kiírja egy hibaablakban a hibaüzenetként megadott stringet. hogyan dobhatunk saját kivételt. amit a kivétel elkapásakor kiírhatunk. végül az operációs rendszer lekezeli a saját hibakezelı rutinjával.finally { Console. } Kivételek feldobása A C# nyelv lehetıséget ad a saját magunk által definiált kivételek használatára is.

Ebben a formában csak a zárójelek közé írt kifejezésekre. mővelet. Nélküle nehéz lenne elképzelni hibátlanul mőködı programokat. mely nem fér el annak értéktartományában. hanem kimondottan egy kifejezés vagy értékadás vizsgálatánál is.. mővelet. A checked és unchecked kulcsszavak nem csak blokként használhatóak: cehecked{}. Amennyiben egy értékadáskor egy változóba olyan értéket szeretnénk elhelyezni. OverflowException hibával leáll a programunk. a változóba bekerül a csonkított érték. vagy értékadás). 162/312 . Ekkor a következı formában írhatjuk ıket: checked( kifejezés. uncehecked{}. vagy egyéb mőveletekre vonatkoznak. vagy értékadás). uncehecked(kifejezés. (Amekkora még elfér benne. sem a felhasználó életét. de talán nem állnak le végzetes hibákkal. } Az értékadás megtörténik. A fentiek ismeretében elmondhatjuk. a kivételek kezelése nagyon fontos és hasznos lehetıség a C# nyelvben. Igaz. és kivétel keletkezik a hiba miatt. Csak nagyon indokolt esetekben használjuk ki az unchecked nyújtotta lehetıségeket. Alapértelmezés szerint a checked állapot érvényesül a programokban található minden értékadásra és mőveletre. hogy a hibakezelés. mert könnyen okozhatunk végzetes hibákat a programokban. Jobb esetben az ilyen hibákat el tudjuk kapni a megfelelı catch{} blokkal. mivel ilyenkor elmarad a hibaellenırzés.) A checked alkalmazásával pontosan az elıbbi folyamat ellenkezıjét érjük el. unchecked { int a=2000000000000. nem keserítik sem a programozó. Az ellenırzés mindenképpen megtörténik. hogy a kivételkezelést alkalmazó programok sem tökéletesek.Checked és unchecked A C# nyelv tartalmaz két további kulcsszót a kivételek kezelésére és a hibák javítására. de az unchecked kulcsszó használatával megakadályozhatjuk a kivétel keletkezését is. Az egyik a checked a másik pedig az unchecked.

mely számokat olvas be a billentyőzetrıl egy string típusú változóba. A kivételek nevét egy konstans tömbben tárolja! 7. mely egy meghatározott végjelig szám párokat olvas be a billentyőzetrıl és a szám párok elsı elemét elosztja a másodikkal. mely a fejezetben felsorolt kivételek nevét kiírja a képernyıre. Az elızı programot módosítsa úgy. de csak páros számokat fogad el! 5. Nem számtípus beolvasásakor kivételekkel kezelje le az elıforduló hibákat! 8. hogy a kivételek dobáskor a hibaüzenetek megjelenjenek a képernyın! 4. Írjon programot. hogy a beolvasásnál csak 3-mal és 5-tel osztható számokat fogadjon el! 6. mely verem kezelést valósít meg egy n elemő vektorban! A program a Pop() és a Push() mőveletek hibája esetén dobjon kivételt! 3. majd tárolja egy int típusú változóban. az eredményt pedig kiírja a képernyıre! Nullával való osztás esetén a program jelezze a hibát a felhasználónak! 2. ha a felhasználó a string-ben nem számokat ad meg. Készítsen programot. Erre külön hívjuk fel a figyelmét!) 163/312 . Készítsen programot. A beolvasás és a konverzió során keletkezı hibákat kivételekkel kezelje le! (Hiba az is. Készítsen programot. Készítsen programot. majd a képernyıre írja a beolvasott számok négyzetét! A program csak számokat fogadjon el inputként. A beolvasott számot alakítsa szám típussá. Módosítsa az elızı programot úgy. mely egy n elemő tömbbe olvas be egész típusú értékeket. mely számokat olvas be a billentyőzetrıl.Programozási feladatok 1. Írjon programot.

hogy a fájlok ne keveredjenek össze. ami az indításkor megjelenik a szerkesztı részben. a kódszerkesztıbe betölti a forráskódot. Most ne a megszokott Console Application típust válasszuk. mivel lényegesen több forráskód és erıforrás szükséges a készítésükhöz. melyre a többi komponenst rakhatjuk. majd azt a könyvtárat. ahol ki kell választanunk azt a programozási nyelvet. hogy milyen típusú alkalmazást szeretnénk készíteni.NET dolgozni kezd. Az jóváhagyást követıen a .NET fejlesztıi eszközt! A File menü new menüpontjában található listából válasszuk a new project-et! Ezt megtehetjük úgy is. Az ilyen típusú programoknak rendelkezniük kell egy ablakkal. s a forráskóddal. Az alkalmazás fı része maga a Form. Jelöljük ki a C# nyelvet! Az ablak jobb oldali részében meg kell mondanunk. hanem a Windows Applicationt! Határozzuk meg a program nevét. az ablakot leíró osztállyal. elıállítja a Form-ot. Készítsük el az elsı Form-mal rendelkezı programunkat! Indítsuk el . hogy a Start Page lapon. rákattintunk a new project linkre. mint Windows alkalmazás. Generálja a programunkhoz szükséges fájlokat. 164/312 . Amikor futtatjuk a programot. ami megjelenik a képernyın.varázsló. ahova el akarjuk menteni a fájlokat! Érdemes külön könyvtárat készíteni minden programnak. ami definiálja az elıbbiek mőködését. akkor is ez a Form lesz az. mellyel dolgozni szeretnénk.Új Projekt készítése A Windows Application projektek készítése már a kezdeti lépésekben eltér a Console Application típusétól. Ekkor elindul a New Project .

de sajnos túl sokat takar a hasznos felületbıl. Itt tudjuk szerkeszteni. (A panel a többihez hasonlóan fixálható. A vezérlık mőködését más fejezetek mutatják be.) 165/312 .A forráskódot kezdetben nem is láthatjuk. elıugró panelen találjuk meg. és vezérlı elemeket is itt adhatunk hozzá. A Form-ra helyezhetı komponenseket a bal oldali. csak a Form felületét a Design ablakban. Toolbox feliratú.

és duplán kattintunk rá. a szerkesztıbe betöltıdik a Form-hoz tartozó kód. A program sorait tanulmányozva rögtön feltőnik az. A panel a projekt elemeit fa struktúrába szervezve tartalmazza.A . A panelre kattintva tudjuk megmondani a szerkesztınek. melynek a felirata Class View. hogy a using rész kibıvült a következı hivatkozásokkal: 166/312 . Ha itt kiválasztjuk a Form1 címkét.NET ablakának a jobb oldalán (nem alapértelmezés szerinti beállítások esetén máshol is lehet) találunk egy függıleges panelt. hogy mutassa meg a forráskódot.

300).Forms. System.ComponentModel. a komponensekhez és a grafikus felület programozásához szükséges hivatkozások.Collections.components = new System. this. public Form1() { InitializeComponent().using using using using using System. A forráskód tartalmazza a saját névterét is. System.Drawing. melyet tetszés szerint átnevezhetünk.Text = "Form1". } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Data.ComponentModel. } #endregion … } 167/312 . Amennyiben újabb komponenseket adunk a Form-hoz. a lista tovább bıvülhet. } } base.Windows.Windows. namespace WindowsApplication1{…} A névtérhez tartozó program részeket kapcsos zárójelei között helyezhetjük el. } #region Windows Form Designer generated code private void InitializeComponent() { this.Size(300. Itt foglal helyet a Form osztály definíciója.Dispose().Drawing.Container(). konstruktora.Size = new System. System.Dispose( disposing ).ComponentModel.Forms.Form { private System. System. this. destruktora és az inicializálásához szükséges utasítások. Az importált elemek közt helyet kapott a Windows form-okat leíró osztály. public class Form1 : System.Container components = null.

a kódszerkesztıbe ugrik a kurzor. A programozás során a két ablak közt folyamatosan váltogatni kell.NET megteszi helyettünk. összes információ szerepelni fog: forráskód példák. A Toolbox felett foglal helyet a Server Explorer. s tovább dolgozhatunk a forráskódon. mivel a következı futtatáskor úgyis újra megjelennek. A . megjelenik a Windows Task. } A Form Designer és a Form1. mely lehetıséget nyújt a számítógép erıforrásainak (adatbázisok. praktikus dolgok. A Main() függvénynek jelenleg az egyetlen utasítása az Appliaction. (Természetesen a háttérben bonyolult mőveletek hajtódnak végre. DLL fájlok. majd nyomjuk le az F1-et.Run(new Form1()). mivel a Windows Application projektek készítése a forráskód és a felület együttes szerkesztését igényli. vagy a ráhelyezett vezérlık valamelyikének a felületén duplát kattintunk. ha rákattintunk egérrel a kívánt ablak fejlécére. static void Main() { Application. stb. Ezeket be is zárhatjuk. elindul az elıfordítás.NET ellenırzi a kód helyességét. leírások. Végül a képernyı alsó részén kaptak helyet a futtatási információkat és az esetleges hibák okát feltáró Output és Debug ablakok. hogyan mőködik! Gépeljük be a szerkesztıbe az int szót. A jobb oldalon találjuk Dinamikus Help rendszert. A projekt futtatása az F5 billentyő leütésekor indul el.A Main() függvényt a lista végén. vagy rendelkezünk internet kapcsolattal.NET kezelıi felületén még számos panel található a felsoroltak mellet. Ez a Form külön alkalmazásként fut. rendelkezik saját memória területtel. 168/312 . Ha leállítjuk. mivel a rendelkezésre álló osztályok és tagfüggvények száma olyan hatalmas.) A Form megjelenik a képernyın a szerkesztı ablaka elıtt. tallózására. ami csak abban az esetben mőködik megfelelıen. Próbáljuk ki. vagyis a forráskód ablakai közt válthatunk. ha telepítettük a számítógépünkre az MSDN Library minden CD-jét.cs.listájában. melyeket a Consol Application projekteknél is megtalálhattunk. hogy senki nem tudja fejben tartani azokat. A . jelöljük ki. ezután elindítja a Programot. visszakerülünk a szerkesztıbe. Amennyiben a Form-on. optimalizálás.Run(). melyben az int típusról megtalálható. különbözı szerverek. de ebben az esetben az adott elem valamely eseményét kapjuk. service-ek) megtekintésére. A Help rendszert az F1 billentyővel is aktivizálhatjuk. A Help használata elengedhetetlen a Windows programok írásakor.. de ezt a . melynek a feladata az alkalmazás elindítása. Egy új ablak nyílik. de még a Class zárójelein belül definiálhatjuk.

Nagyobb programozói tudást igényelnek és feltételezik a magas szintő Objektum Orientált programozási ismereteket.A Consol Application projektek készítése bonyolultabb az eddig tanult alkalmazásokénál. 169/312 .

Próbálja meg értelmezni az üzeneteket! 6. majd töltse vissza azokat! 4. hogy az Output és a Debug ablakban milyen üzenetek jelennek meg! 5. 170/312 . Windows Application projektet! 2.Feladatok 1.cs állományt majd nyissa meg azt a . és vizsgálja meg. Hozzon létre egy új. Mentse el a háttértárra az aktuális alkalmazás minden adatát! 3. A létrejött állományok közül keresse meg a form1. Keresse meg az alkalmazás mentett adatait.NET fejlesztıi eszközzel! 7. A Help rendszer segítségével keresse meg a form-okról rendelkezésre álló lehetı legtöbb információt. Futtassa az alkalmazást.

vagy megszakíthat egy folyamatot. Form melyik részéhez igazítson Gomb hátterének a színe Gomb hátterének a képe Jobbgombos elıbukkanó menü Beállítja a gomb visszatérési értékét. vagy tiltja a drag and drop funkciót. Alapbeállításban tiltva van. Properties (Tulajdonságok) AllowDrop Anchor BackColor BackgroundImage ContextMenu DialogResult Dock Enabled Font ForeColor ImageList ImageIndex Location Engedélyezi. Az imagelistben megadott képnek az indexe A gomb a bal felsı saroktól való 171/312 . Például elindíthat.A látható komponensek. Beállítja a gomb helyzetét a következı pozíiókba: Top – felsı részhez Bottom – alsó részhez Left – baloldalra Right – jobboldalra Fill – kitölti az egész Form-ot Engedélyezett-e A gombon található szöveg betőtípusa A gombon található szöveg színe Összerendelés a gomb és az imagelist között. a kontrollok Button (Gomb) A nyomógomb komponens által a felhasználó mőveletet hajthat végre.

y formában Gomb lezárása A gomb hozzáférésének a lehetıségei: public. Linklabel A label szöveget jelenít meg. 172/312 . KeyDown KeyUp Leave MouseEnter MouseLeave ParentChanged távolsága x. amihez a felhasználó nem fér hozzá. private. protected internal. internal A gomb mérete Elérhetı-e tabulátorral A tabulátoros lépegetés sorrendje Gomb felirata A felirat elhelyezkedése a gombon Látható-e Gombra kattintás Gomb fókuszba kerülése Billentyő lenyomása amíg a gomb fókuszban van Billentyő elengedése amíg a gomb fókuszban van Fókuszból kikerülés Mutató a gomb fölött helyezkedik el Mutató elhagyja a gombot Szülı megváltozik Label. protected.Locked Modifiers Size TabStop TabIndex Text TextAlign Visible Események: Click Enter GotFocus Keypress.

Form melyik részéhez igazítson A címke hátterének a színe A címke hátterének a képe Engedélyezett-e A címkén található szöveg betőtípusa A szöveg színe Összerendelés a cimke és az imagelist között. 173/312 . Az imagelistben megadott kép indexe A gombnak a bal felsı saroktól mért távolsága x.Közös tulajdonságok: Name AllowDrop Anchor BackColor BackgroundImage Enabled Font ForeColor ImageList ImageIndex Location Size Text Visible Linklabel tulajdonságai: ActiveLinkColor LinkBehavior LinkColor LinkVisibled VisitedLinkColor Név Engedélyezi. vagy tiltja a drag and drop funkciót.y formában A címke mérete A címke felirata Látható-e Az aktivált link színe A link stílusa amikor a mutató fölötte van A link színe Volt-e már megnézve? Megnézett link színe Textbox A textbox egy olyan területet jelöl ki. vagy módosíthat. ahol a felhasználó általában egysoros szöveget adhat meg.

hogy egy listából válasszon. KeyDown KeyUp Leave MouseEnter MouseLeave Automatikus méret A textbox keretének a stílusa A bető métete Lower – kisbetős Upper – nagybetős Normal – vegyes Texboxban található sorok sorszámozva A texboxba írható szöveg maximális hossza Többsoros megjelenítés Az textboxban megjelenı karakter (jelszavaknál) Textboxban található szöveg Billentyő lenyomása amíg a gomb fókuszban van Billentyő elengedése amíg a gomb fókuszban van Fókuszból kikerülés Mutató a gomb fölött helyezkedik el Mutató elhagyja a gombot CheckBox Akkor használjuk. Ha három akkor mindezt a CheckState tulajdonságnál tudjuk megtenni. hogy a CheckBoxnak két vagy három állapota legyen. igen/nem választási lehetıséget szeretnénk adni a felhasználó számára. De amíg a CheckBoxnál a lista elemeinek kombinációját választhatjuk ki.Systemre van állítva. A ThreeState tulajdonság azt határozza meg. akkor a felhasználó operációs rendszerének beállításai határozza meg ezt.Systemre van állítva. addig a RadioButtonnál már csak a lista egy elemét. Ha ez FlatStyle. hogy a 174/312 . Az Appearance (megjelenés) tulajdonságnál azt állíthatjuk be. Megjegyzés: A Checked tulajdonság 3 állapotú CheckBox esetén mindig igaz értéket ad vissza A FlatStyle a CheckBox stílusát és Megjelenését határozza meg. akkor tulajdonság figyelmen kívül van hagyva. hogy a CheckBox egy általános kiválasztó négyzet legyen vagy egy nyomógomb. Megjegyzés: Mikor a FlatStyle tulajdonság FlatStyle. Ha kettı akkor a CheckBox aktuális értékét lekérdezni és beállítani a Checked tulajdonságnál tudjuk. amikor egy igaz/hamis. Ha a CheckAlign tulajdonság az egyik jobb igazításra van állítva akkor ez a vezérlı elem úgy jelenik meg. A CheckBoxnak és a RadioButtonnak a funkciója ugyanaz.MiddleRight igazítást figyelembe véve jelenik meg. Mindkettı lehetıvé teszi a felhasználó számára. . és a CheckAlign ContentAlignment.MiddleLeft vagy ContentAlignment.Tulajdonságai: AutoSize Borderstyle CharacterCasing Lines MaxLength Multiline PasswordChar Text Események: Keypress.

A GroupBoxot jellemzıen RadioButton csoportok összefogására használjuk.MiddleRight igazítást használja. ContentAlignment. akkor mindkettıben ki tudunk választani egyet-egyet. ami vezérlı csoportokat tud meghatározni.AutoCheck = false. Logikailag egységbe tartozó vezérlı elemek összefogására használjuk a formon. Controls. 175/312 . A GroupBoxhoz a Control tulajdonság Add metódusával tudunk hozzáadni vezérlıket. mindkettıben néhány RadioButton. Példa kód: // CheckBox létrehozása és inicializálása CheckBox checkBox1 = new CheckBox().Appearance = Appearance. // A CheckBox hozzáadása a formhoz.Add(checkBox1).MiddleLeft igazítás állítja be. Ha van két GroupBoxunk. A GroupBox egy konténer.ContentAlignment. különben pedig a // A megjelenés autómatikus frissítésének kikapcsolás checkBox1.Button. //CheckBox megjelenítése nyomógombként checkBox1. GroupBox A GroupBox egy terület keretét határozza meg egy vezérlı elem csoport körüli felirattal vagy felirat nélkül.

GroupBox groupBox1 = new GroupBox(). RadioButton radioButton1 = new RadioButton().Add(groupBox1). // A GroupBox hozzáadása a formhoz Controls.Add(radioButton2). hogy beillesszük a MainMenut a formba és az megjelenjen rajta össze kell egyeztetni a form Menu tulajdonságával. A MainMenu MenuItem objektumokból áll össze melyek egyedi menüutasítások a menü struktúrában. // A GroupBox FlatStyle tulajdonságának beállítása.Add(radioButton1). vagy az ıs menüelemeken. groupBox1.Példa kód: private void InitializeMyGroupBox() { //Egy GroupBox és 2 RadioButton létrehozása és inicializálása. Minden menüitemhez tartozik egy utasítás amit végrehajt az alkalmazásunkban vagy az al. RadioButton radioButton2 = new RadioButton().Controls.FlatStyle = FlatStyle. groupBox1. } MainMenu A MainMenu egy konténer a form menüstruktúrájának számıára. // A RadioButtonshozzáadása a GroupBoxhoz.System.Controls. groupBox1. Ahhoz. 176/312 .

ami a menüelem szövegét jobbról balra jeleníti meg. akkor használjuk a CloneMenu metódust. Egy formhoz lehet készíteni több MainMenut is ha több menüstruktúrát szeretnénk megvalósítani. Ha újra akarjuk használni a MinMenut egy speciális menüstruktúrában. 177/312 .Azokhoz az alkalmazásokhoz melyek több nyelvet támogatnak lehet használni a RightToLeft tulajdonságot. Amikor kész van a másolat. mint az arab nyelv írásakor. ami egy másolatot készít. akkor el lehet végezni a megfelelı módosításokat az új menüstruktúrán.

MenuItems. De amíg a CheckBoxnál a lista elemeinek kombinációját választhatjuk ki. menuItem2.Text = "File". MenuItem menuItem1 = new MenuItem(). // 2 MenuItem hozzáadása a MainMenuhöz. 178/312 . MenuItem menuItem2 = new MenuItem(). mainMenu1. } RadioButton A CheckBox és a RadioButton a funkciója ugyanaz. Menu = mainMenu1. addig a RadioButtonnál már csak a lista egy elemét.MenuItems. Mindkettı lehetıvé teszi a felhasználó számára. // A MainMenu beillesztése Form1be. MainMenu mainMenu1 = new MainMenu(). vagy egy képet. hogy egy listából válasszon.Példa kód: public void CreateMyMainMenu() { //Üres MainMenu létrehozása. vagy mindkettıt.Add(menuItem2).Add(menuItem1).Text = "Edit". menuItem1. mainMenu1. A RadioButton meg tud jeleníteni egy szöveget.

179/312 . Elsı pillantásra egy TextBox-ot láthatunk a jobb oldalán egy nyilacskával. Ezen problémák megoldására használhatjuk a combobox osztályt. Ha egy formra több csoportot akarunk rakni. egy form) egy csoportot alkot. GroupBox. Ezt az Appearance tulajdonság határozza meg. // kikapcsolás. A RadioButton úgy nézhet ki mint egy nyomógomb. radioButton1. // A RadioButton hozzádása a formhoz Controls.Add(radioButton1).AutoCheck = false.Appearance = Appearance. } A Click esemény hatására történı kinézet frissítés ComboBox A listák nagy helyet foglalnak a formokon.Amikor a felhasználó kiválaszt egy RadioButtont egy csoportból akkor a többi automatikusan üresre változik. Ez egyesíti a szerkesztı mezı (edit) és a lenyíló lista tulajdonságait. radioButton1. Példa kód: private void InitializeMyRadioButton() { // RadioButton létrehozása és inicializálása. akkor minden egyes csoportnak helyezzünk el egy konténert a formon (mint pl. A Checked tulajdonsággal tudjuk lekérdezni és beállítani a RadioButton állapotát. és az általuk felkínált elemek nem bıvíthetıek a felhasználó által. Panel). Minden RadioButton ami egy adott konténeren belül van (mint pl. vagy úgy mint egy hagyományos RadioButton. RadioButton radioButton1 = new RadioButton().Button. // RadioButton nyomógombként való megjelenítése.

hogy a vezérlı fogadhate „Fogd-és-vidd” értesítéseket helyi menü. amikor az egérkurzort fölé mozgatjuk a megjelenést és a mőködést vezérli szöveg megjelenítésére használt betőtípus elıtérszín (pl. hogy a vezérlı tartalma 180/312 DrawMode DropDownWidth Enabled IntegralHeight ItemHeight MaxDropDownItems MaxLength Sorted . ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg A ComboBox megrajzolási módját vezérli a legördülı ablak szélessége pixelben azt jelzi. ha a listarészlet csak teljes elemeket tartalmazhat. ami megjelenik a vezérlı fölött. betőszín) a vezérlıben látható szöveg DropDownStyle Font ForeColor Text Viselkedés AllowDrop ContextMenu meghatározza.Feladata: Adatok legördülı ablakban történı megjelenítése Megjelenés BackColor Cursor a ComboBox háttérszíne a kurzor típusa. hogy a ComboBox engedélyezett. vagy nem true. különben false a ComboBox egy elemének magassága pixelben A legördülı listában egyszerre látható bejegyzések maximális száma a ComboBox beviteli részébe írható karakterek maximális száma Meghatározza.

amikor egy 181/312 . hogy a ComboBox menüje legördült DropDownStyleChanged jelzi. amikor egy bizonyos elemet vagy területet meg kell rajzolni DropDown azt jelzi. ahonnan a vezérlı az elemeit veszi az adatforrás egy tulajdonsága. hogy a vezérlı átméretezhetı. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. a ComboBox elemeit tartalmazza Tetszıleges célokra használható egész értékő mezı Tervezés Name Locked Modifiers Anchor A vezérlı neve megmutatja. hogy az elem kiválasztható-e a TAB billentyő használatával a vezérlı látható vagy nem Items Tag a listát jelöli. hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát Kiválasztott elem értéke Dock Location SelectedValue Események Click DoubleClick DrawItem kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény akkor következik be. mezıje. amit a comboboxban meg kívánunk jeleníteni Collection.TabIndex TabStop Visible Adat DataSource DisplayMember rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja. hogy a DropDownStyle tulajdonság megváltozott HelpRequested A felhasználó segítséget kér a vezérlırıl MeasureItem akkor következik be. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja.

amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. Ha az indexére van szükségünk. a lista lenyitható A listához hasonlóan a comboboxban is az Items tulajdonság tárolja a lista elemeit. azaz újabb elem kerül kijelölésre jelzi. akkor a SelectedIndex tulajdonságot használjuk. Count Add Insert Remove Indexer. (alapértelmezett) Nem szerkeszthetı a mezı. Így kezelése a szokásos metódusok használatával lehetséges. ami egy objektumot ad vissza. amikor a rendszerszínek megváltoznak A következı események mindegyike egy tulajdonság megváltozását jelzi: BackColorChanged ContextMenuChanged CursorChanged DataSourceChanged DisplayMemberChanged DockChanged EnabledChanged FontChanged ForeColorChanged LocationChanged ParentChanged SelectedValueChanged SizeChanged TabIndexChanged TabStopChanged TextChanged VisibleChanged háttérszín helyzetérzékeny menü kurzor adatforrás megjelenítendı adattag-forrás igazítás engedélyezettségi állapot betőtípus elıtérszín (betőszín) helyzet (Lásd Location) szülı kiválasztott érték méret tab-sorrendbeli hely TAB-bal történı kiválaszthatóság beállítása szöveg vizuális láthatóság A kritikus tulajdonság a DropDownStyle lehetséges értékei: Simple DropDown DropDownList Szerkeszthetı mezı. az elemek számát adja vissza Új elem felvétele a listához Új elem beszúrása a listába Elem törlése A felhasználó által kiválasztott elemet a SelectedItem tulajdonságon keresztül érjük el. Ez a tulajdonság egy ObjectCollection típus. a lista mindig látszik Szerkeszthetı mezı. 182/312 . a lista lenyitható.SelectedIndexChanged StyleChanged SystemColorsChanged bizonyos elem magasságát ki kell számítani akkor következik be. ha megváltozott a vezérlı stílusa bekövetkezik.

i<10. Feladata: elemek győjteményének –különbözı nézetekben történı. A ’Törlés’ gomb mind a Items tárolót.DropDownStyle = ComboBoxStyle.Text="DropDownList". button3.Text="".Text="Simple".Items.i++) comboBox1.Items. button3.Add(i. break. } ListView Ha az elızıeknél is kifinomultabb listát szeretnénk használni.Text="DropDown". case ComboBoxStyle.Clear(). case ComboBoxStyle.Tekintsünk néhány alapmőveletet a példa segítségével: A ’Feltöltés’ gombeseménykezelıje egyszerő. break.DropDownStyle = ComboBoxStyle.DropDown: comboBox1. hogy megjelennek-e CheckBoxok az elemek 183/312 .Simple: comboBox1.DropDownList. egész számokkal tölti fel a combobox items tulajdonságát: for (int i=0.megjelenítése Megjelenés BackColor BorderStyle CheckBoxes a ListView háttérszíne A keret stílusa azt mutatja.DropDownStyle) { case ComboBoxStyle.DropDownStyle = ComboBoxStyle.DropDownList: comboBox1. button3. comboBox1.Simple. mind a text mezıt törli: comboBox1.ToString()). akkor erre lehetıséget ad a ListView osztály. break.DropDown. Egy egyszerő switch szerkezettel módosíthatjuk a stílusát a comboboxnak: switch (comboBox1.

ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg A vezérlıben megjelenı oszlopfejlécek. hogy kijelölhetı-e egy elem azáltal. hogy a combobox engedélyezett. hogy az elem kiválasztható-e a TAB billentyő használatával a vezérlı látható vagy nem SmallImageList Sorting StateImageList TabIndex TabStop Visible Adat Tag Teszıleges célokra használható egész értékő mezı 184/312 . hogy az egérkurzort fölötte hagyjuk A ListView elemei megengedi a felhasználónak. hogy a felhasználó megváltoztathatja-e az oszlopok sorrendjét jelzi. hogy a vezérlıben megjelenhetnek-e gördítısávok. amikor a vezérlı elveszíti a fókuszt megmutatja. hogy a címke szövege több sorra törhetı-e a lista ikonjai Nagy ikonok nézetben engedélyezi több elem egyszerre történı kijelölését Meghatározza. vagy nem Oszlopfejlécek stílusa azt jelöli. hogy milyen típusú mőveletre van szükség a felhasználó részérıl egy elem aktiválásához megmutatja az elemek igazítási módját a ListView-n belül jelzi.Cursor Font ForeColor FullRowSelect GridLines View Viselkedés Activation mellett a kurzor típusa.) Alignment AllowColumnReorder AllowDrop AutoArrange ContextMenu Coulumns Enabled HeaderStyle HideSelection HoverSelection ImeMode Items LabelEdit LabelWrap LargeImageList MultiSelect Scrollable meghatároza. részletek. Collection azt jelzi. lista. hogy az elemek címkéit megváltoztassák azt jelöli.. ami megjelenik a vezérlı fölött. betőszín) Megmutatja. az elemek megjelenítési módja (ikonok. hogy egy elemen történı kattintás kijelöli-e az elem összes al-elemét is rácsvonalak jelennek meg az elemek és a részelemek körül.. amennyiben nincs elég hely az ikonok számára a lista ikonjai Kis ikonok nézetben elemek rendezésének módja a lista alkalmazás által meghatározott állapotokkal kapcsolatos ImageList-je az elem helyét adja meg a TAB sorrendben megmutatja. amikor az egérkurzort fölé mozgatjuk szöveg megjelenítésére használt betőtípus elıtérszín (pl. hogy a vezérlı kijelölt elemén megmarad-e a kijelölés. hogy a vezérlı fogadhat-e „Fogd-és-vidd” értesítéseket az ikonok automatikus rendezettségét jellemzi helyi menü.

Tervezés Name Locked Modifiers Anchor Dock Location A vezérlı neve megmutatja. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. amikor a felhasználó elkezd „vonszolni”egy elemet elemcímke módosítása után következik be elemcímke módosítása elıtt jelentkzik A felhasználó segítséget kér a vezérlırıl egy elem „check” állapotának megváltozásához tartozik akkor következik be. hogy a vezérı átméretezhetı. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. ha megváltozott a vezérlı stílusa bekövetkezik. amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. azaz újabb elem kerül kijelölésre jelzi. amikor a rendszerszínek megváltoznak AfterLabelEdit AfterLabelEdit HelpRequested ItemCheck SelectedIndexChanged StyleChanged SystemColorsChanged A következı események mindegyike egy tulajdonság megváltozását jelzik: BackColorChanged ContextMenuChanged CursorChanged DockChanged EnabledChanged FontChanged ForeColorChanged LocationChanged ParentChanged SizeChanged TabIndexChanged TabStopChanged VisibleChanged háttérszín helyzetérzékeny menü kurzor igazítás engedélyezettségi állapot betőtípus elıtérszín (betőszín) helyzet (Lásd Location) szülı méret tab-sorrendbeli hely TAB-bal történı kiválaszthatóság vizuális láthatóság 185/312 . hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát Események Click ColumnClick DoubleClick ItemActivate ItemDrag kattintáshoz kötıdı esemény oszlopfejlécre történı kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény Elem aktiválása akkor következik be.

amikor az egérmutató föléjük ér az alapértelmezett képindex a csomópontok számára a vezérlı ImageList-je. amikor a vezérlı elveszíti a fókuszt megmutatja. hogy az elemek hyperlink-stílusúvá váljanak-e. vagy nem Megmutatja. hogy a vezérlı kijelölt elemén megmarad-e a kijelölés. ami megjelenik a vezérlı fölött.TreeView Ez az osztály az elemek hierarchikus rendben történı megjelenését szolgálja. amikor az egérkurzort fölé mozgatjuk szöveg megjelenítésére használt betőtípus elıtérszín (pl. hogy egy elemen történı kattintás kijelöli-e az elem összes al-elemét is azt jelöli. betőszín) a TreeView egy elemének magassága pixelben meghatározza. amelybıl a csomópontokhoz tartozó képek származnak 186/312 . hogy megjelennek-e CheckBoxok az elemek mellett a kurzor típusa. ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg azt jelzi. hogy a vezérlı fogadhat-e „Fogd-és-vidd” értesítéseket helyi menü. hogy a combobox engedélyezett. Feladata: címkézett elemek hierarchikus győjteményének megjelenítése Megjelenés BackColor BorderStyle CheckBoxes Cursor Font ForeColor ItemHeight Viselkedés AllowDrop ContextMenu Enabled FullRowSelect HideSelection HotTracking ImageIndex ImageList a ComboBox háttérszíne A keret stílusa azt mutatja.

hogy a vezérı átméretezhetı. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. hogy a vezérlıben megjelenhetnek-e gördítısávok. hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát A vezérlı mérete pixelben 187/312 . hogy az elemek címkéit megváltoztassa Gyökércsomópontok a TreeView-n belül a csomópontok teljes elérési útvonalának megadásához használt elválasztó sztring Meghatározza.Indent LabelEdit Nodes PathSeparator Scrollable SelectedImageIndex ShowLines ShowPlusMinus ShowRootLines Sorted TabIndex TabStop Visible Adat a gyermekcsomópontok behúzása pixelben megengedi a felhasználónak. hogy a vezérlı tartalma rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja. amikor a kijelölés megváltozik A vezérlı neve megmutatja. amikor a TreeNode egy CheckBox-ának értéke megváltozik Lista felgördítése után következik be Lista legördítése után következik be elemcímke módosítása után következik be akkor váltódik ki. amennyiben nincs elég hely az elemek megjelenítése számára alapértelmezett képindex a kiválasztott csomópontok számára csomópontokat összekötı vonalak megjelenítése plusz/mínusz gombok megjelenítése a szülıcsomópontok mellett vonalak megjelenítése a szülıcsomópontok mellett Meghatározza. amikor a felhasználó elkezd „vonszolni”egy elemet akkor következik be. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. hogy az elem kiválasztható-e a TAB billentyő használatával a vezérlı látható vagy nem Tag: Teszıleges célokra használható egész értékő mezı Tervezés Name Locked Modifiers Anchor Dock Location Size Események Click DoubleClick ItemDrag AfterCheck AfterCollapse AfterExpand AfterLabelEdit AfterSelect kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény akkor következik be.

amikor a rendszerszínek megváltoznak A következı események mindegyike egy tulajdonság megváltozását jelzik: BackColorChanged ContextMenuChanged CursorChanged DockChanged EnabledChanged FontChanged ForeColorChanged LocationChanged ParentChanged SizeChanged TabIndexChanged TabStopChanged VisibleChanged háttérszín helyzetérzékeny menü kurzor igazítás engedélyezettségi állapot betőtípus elıtérszín (betőszín) helyzet (Lásd Location) szülı méret tab-sorrendbeli hely TAB-bal történı kiválaszthatóság vizuális láthatóság 188/312 .BeforeCheck BeforeCollapse BeforeExpand BeforeLabelEdit BeforeSelect HelpRequested StyleChanged SystemColorsChanged kiváltódik. mielıtt a TreeNode CheckBox kijelölésre kerül Lista felgördítése után következik be Lista legördítése után következik be elemcímke módosítása elıtt jelentkzik a TreeNode kijelölse elıtt váltódik ki A felhasználó segítséget kér a vezérlırıl jelzi. ha megváltozott a vezérlı stílusa bekövetkezik.

ami megjelenik a vezérlı fölött. hogy a vezérlı fogadhat-e „Fogdés-vidd” értesítéseket megjelenési beállítások helyi menü. amikor az egérmutató föléjük ér 189/312 .TabControl Feladata: lapok összefüggı halmazát alkotja Megjelenés Cursor Font ImageList Megjelenés Alignment AllowDrop Appearance ContextMenu a kurzor típusa. amikor az egérkurzort fölé mozgatjuk szöveg megjelenítésére használt betőtípus a TabControlhoz DrawMode Enabled HotTrack megmutatja a fülek hol helyezkednek el a TabControlon belül jelzi. hogy a fejlécelemek vizuálisan megváltozzanak-e. vagy nem megmutatja. ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg A TabControl megrajzolási módját vezérli azt jelzi. hogy a TabControl engedélyezett.

hogy az elem kiválasztható-e a TAB billentyő használatával Visible a vezérlı látható vagy nem Adat Tag: Teszıleges célokra használható egész értékő mezı Tervezés Name DrawGrid GridSize Locked Modifiers SnapToGrid A vezérlı neve megmutatja. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja.mennyi extra hely legyen a vezérlı „fülei” körül ShowToolTips Meghatározza. hogy a pozícionáló rács kirajzolásra kerüljön-e meghatározza a pozícionáló rács méretét megmutatja. hogy csak egy. hogy a vezérlıknek kapcsolódnia kell-e a pozícionáló rácshoz Horgony. átmozgatható-e A vezérlı láthatósági szintjét jelöli Meghatározza. SizeMode az egyes lapok méretezési módját állítja be TabIndex az elem helyét adja meg a TAB sorrendben TabStop megmutatja. hogy látszódnak-e a lapokhoz tartozó ToolTip-ek. hogy a vezérı átméretezhetı. hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát A vezérlı mérete pixelben A lapok a TabControlban Anchor Dock Location Size TabPages Események Click DoubleClick kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény 190/312 . vagy vagy több fül is lehet a vezérlın belül Padding meghatározza. hogy .ItemSize Meghatározza a vezérlı al-ablakainak méretét MultiLine Meghatározza.

amikoregy bizonyos elemet vagy területet meg kell rajzolni A felhasználó segítséget kér a vezérlırıl akkor következik be. ha megváltozott a vezérlı stílusa bekövetkezik. amikor a rendszerszínek megváltoznak A következı események mindegyike egy tulajdonság megváltozását jelzik: BackColorChanged ContextMenuChanged CursorChanged DockChanged EnabledChanged FontChanged LocationChanged ParentChanged SizeChanged TabIndexChanged TabStopChanged VisibleChanged háttérszín helyzetérzékeny menü kurzor igazítás engedélyezettségi állapot betőtípus helyzet (Lásd Location) szülı méret tab-sorrendbeli hely TAB-bal történı kiválaszthatóság vizuális láthatóság DateTimePicker komponens A DateTimePicker komponens segítségével egyszerően kérhetünk be vagy írhatunk ki dátumot. idıt. 191/312 . amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. azaz újabb elem kerül kijelölésre jelzi. mely megegyezik a MonthCalendar komponens kinézetével és használatával. és egy lenyíló naptár. Két részbıl áll: egy szövegbeviteli doboz.DrawItem HelpRequested SelectedIndexChanged StyleChanged SystemColorsChanged akkor következik be. mely a dátumot/idıt tartalmazza szöveges formában.

A kívánt értékeket négyféle formátumban képes a komponens megjeleníteni: Hosszú dátum (év. hogy a lenyíló hónap-naptár a komponenshez hogyan legyen igazítva Left vagy Right A komponensben szereplı dátum/idı formátuma. Választhatunk a beépített formátumok közül vagy lehet egyedi Long/Short/Time/Custom A legkésıbbi beírható dátum A legkorábbi beírható dátum Meghatározza. hónap száma. ezeknél kisebb vagy nagyobb dátumot nem lehet beírni. hónap neve. Beállíthatunk két dátumot (minimum és maximum). nap) Rövid dátum (év.A lenyíló naptár helyett használhatjuk a komponenst görgetıkkel is (a lenyitó gomb helyett fel-le gombok jelennek meg) a ShowUpDown tulajdonság igazra állításával. hogy a felhasználó választott-e értéket False Egyéni formátum-string dátum és/vagy idı kiírásához Beállítja. perc. Amíg a jelölınégyzet nincs 192/312 CustomFormat DropDownAlign Format MaxDate MinDate ShowCheckBox . hogy szerepeljen-e egy jelölınégyzet a komponensen. ellenırizhetı. nap) Idı (óra. másodperc) Egyéni (custom) Tulajdonságok: CalendarFont CalendarForeColor CalendarMonthBackground CalendarTitleBackColor CalendarTitleForeColor CalendarTrailingForeColor Checked A megjelenı naptár betőtípusa ~ betőszíne ~ háttérszíne ~ címsáv háttérszín ~ címsáv betőszín ~ megelızı és követı hónap napjainak színe Ha a ShowCheckBox tulajdonság értéke true. melyek határt szabhatnak a bevitelre.

Az érték beállítható szerkesztéskor vagy futásidıben is. kiegészül egy megelızı nullával Ddd Nap neve három betős rövidítéssel Dddd Nap teljes neve Hh Kétszámjegyő óra. A komponens egy DateTime értéket ad vissza. pl. 16). Second (másodperc) és Millisecond (ezredmásodperc) tulajdonságok egész számot adnak vissza. ha a komponens értéke megváltozik A komponensben kiválasztott értéket a Value tulajdonság tartalmazza.Value = new DateTime(2004. 12 órás ábrázolás 193/312 . Alapértelmezésben ez az érték az aktuális dátumot/idıt tartalmazza. A formátum-stringben az alábbiak használhatók: D Egy vagy kétjegyő nap száma Dd Kétjegyő nap. … .Text = DateTimePicker1. a komponenst tartalmazó form megjelenítésekor.ToString(). Tulajdonságok dátumban: Year (év). Egyéni formátum-string: Állítsuk a Format tulajdonságot Custom-ra. 9. Minute (perc). DayOfWeek tulajdonság a hét egy napjának nevét adja vissza (Monday.lblDatum. Sunday) Tulajdonságok idıben: Hour (óra). Érték kiolvasása: this. Értékadás: DateTimePicker1. ha a felhasználó a lenyíló naptárból kiválasztott egy dátumot Bekövetkezik. vagy kaphat. addig nem volt érték kiválasztva. ha a naptár lenyílik Bekövetkezik. Ha csak egyjegyő. Day (nap) tulajdonságok egész számokat adnak vissza. False A lenyíló naptár helyett a kiválasztott dátumot/idıt egy fel-le görgetıvel változtathatjuk (spinner) False Az aktuális dátum/idı Bekövetkezik. Month (hónap).ShowUpDown Value Események: CloseUp DropDown ValueChanged Érték beírása és kiolvasása kijelölve.Value.

pl.:hh:mm 11:23 hh’d’mm 11d23 Angol stílusú dátum-formátum: public void EgyeniDatumFormatum() { dateTimePicker1. ebben a komponensben több dátumot is kijelölhetünk. akkor csak be kell írni. Ellentétben a hasonló DateTimePicker komponenssel. Ha csak egyjegyő. } A DateTimePicker becsukott állapotban: MonthCalendar komponens A MonthCalendar komponens egy grafikus felületet nyújt a felhasználóknak.CustomFormat = "MMMM dd. yyyy . nullás kiegészítés Hónap neve három betős rövidítéssel Hónap teljes neve Egy vagy kétszámjegyő másodperc Kétszámjegyő másodperc. akkor két aposztróf közé kell írni. Lehet a dátumok között lépkedni . A komponens egy naptárat jelenít meg. betők. akár szöveg is. 24 órás ábrázolás Kétszámjegyő óra. 194/312 . Ha nem szerepeltetünk benne a fenti karakterekbıl. dateTimePicker1.Format = DateTimePickerFormat.dddd". hogy lekérdezzék és módosítsák a dátumot.hónapos lépésekben . kiegészül egy megelızı nullával Egy vagy kétszámjegyő hónap Kétszámjegyő hónap. 24 órás ábrázolás Egy vagy kétszámjegyő perc Kétjegyő perc. Egy rácsháló tartalmazza a hónap számozott napjait. oszloponként rendezve a hét napjaihoz (hétfı-vasárnap). A komponensen kijelölhetünk több dátumot is (megadható számú).a komponens címsávjában szereplı bal vagy jobb nyílra kattintva.H HH M Mm M MM MMM MMMM S Ss T Tt Y Yy Yyyy Egy vagy kétszámjegyő óra. Ha a fenti betők valamelyikét szeretnénk. nullás kiegészítés Egy betős AM/PM kijelzés (délelıtt/délután) Két betős AM/PM kijelzés Egy számjegyő év (2001 megjelenítése: ”1”) Két számjegyő év (2001 megjelenítése: ”01”) Teljes év kiírása (2001 megjelenítése: ”2001”) A formátum-stringben szerepelhetnek még saját jelek.Custom.

Ezek lehetnek egyedi dátumok. Alapértelmezés szerint az aktuális nap a naptárban pirossal be van karikázva. Height=1 A hét kezdı napja Alapértelmezés: Default. és fel van tüntetve a rács alatt is. …) Itt állítjuk be az elérhetı legkésıbbi dátumot a naptárban Alapértelmezés: 9998.01. kiemelve ıket a többi közül (fontos dátumok). ilyenkor a rendszertıl kérdezi le a területi beállításokat Értéknek adhatjuk neki a hét napjainak nevét angolul (Monday.01. nálunk hétfıvel. A rács mellett megjeleníthetjük a hetek számait is.12. évenkénti vagy havi dátumok. Bizonyos dátumokat megjelölhetünk félkövér írásmóddal.31. A naptárban kijelölhetı napok maximális száma Alapértelmezés: 7 Itt állítjuk be az elérhetı legkorábbi dátumot a naptárban Alapértelmezés: 1753.A komponens kinézete változtatható. A hét kezdı napja is megváltoztatható: Angliában a hét vasárnappal kezdıdik. Tulajdonságok (properties): AnnuallyBoldedDates BoldedDates CalendarDimensions Tartalma az évenként elıforduló fontos dátumok DateTime[] tömb Tartalma az egyedi fontos dátumok DateTime[] tömb A naptárak száma a komponensen belül (oszlop és sor) Alapértelmezés: Width=1. Egy tulajdonság megváltoztatásával akár több naptár is lehet egymás mellett vagy alatt. Tartalma a havonta elıforduló fontos dátumok FirstDayOfWeek MaxDate MaxSelectionCount MinDate MonthlyBoldedDates 195/312 .

AnnuallyBoldedDates és MonthlyBoldedDates) tárolhatja ezeket az egyedi. 1). Három tulajdonság (BoldedDates. 9. hogy a komponens bekarikázza-e az aktuális napot a naptárban Alapértelmezés: True Beállítja. Beállítja a naptárban megjelenı elızı és következı hónapból belógó napok színét Alapértelmezés: Szürke Események (events) DateChanged Akkor következik be. ha a felhasználó kijelöl egy vagy több dátumot DateSelected Kiemelt dátumok kezelése Fontosabb dátumokat félkövér betőtípussal. DateTime NyariSzunetVege = new DateTime(2004. Ezek a tulajdonságok tartalmaznak egy tömböt. ha megváltozik a kijelölt dátumok intervalluma vagy elızı/következı hónapra mozdul a naptár Akkor következik be. hogy a komponensen a napok sorai elıtt látszik-e a hét sorszáma (1-52) Alapértelmezés: False A komponens címsávjának háttérszíne Alapértelmezés: Kék A komponens címsávján megjelenı betők színe Alapértelmezés: Fehér Az aktuális dátum Pl. 13).: 2004. hogy látható-e az aktuális dátum a komponens alján Alapértelmezés: True Beállítja. Hozzunk létre DateTime objektumot: DateTime NyariSzunetKezdete = new DateTime(2004. mely DateTime objektumokból áll. hogy a komponens elıre és vissza gombjaival hány hónapot lépjen a naptár Alapértelmezés: 0 (a következı/elızı hónapra léptet) A komponensben kijelölt napok intervalluma Alapértelmezés: mindkét érték az aktuális dátumot tartalmazza Beállítja. 7.05.ScrollChange SelectionRange ShowToday ShowTodayCircle ShowWeekNumbers TitleBackColor TitleForeColor TodayDate TrailingForeColor DateTime[] tömb Ez a változó állítja be. 196/312 . Hogyan lehet hozzáadni vagy elvenni ezek közül? Dátum hozzáadás: 1. havonta vagy évente elıforduló dátumokat.06. kiemelten szerepeltethetünk a naptárban.

monthCalendar1. beépített görgetık.RemoveAllMonthlyBoldedDates(). HorizontalScrollBar és VerticalScrollBar komponensek A ScrollBar komponensek segítenek sok elemen át vagy nagy mennyiségő információban keresni vízszintes vagy függıleges görgetéssel. AddMonthlyBoldedDate) monthCalendar1. hogy hol helyezkedik el a görgetıdoboz (pozíciójelzı). (Használható még a RemoveMonthlyBoldedDate és RemoveAnnuallyBoldedDate parancs is) Az összes kiemelt dátum törlése: monthCalendar1. A dátum kiemelése a komponenshez (komponens példányhoz) hozzáadással: (Három parancs: AddBoldedDate. A ScrollBar komponensek nem ugyanazok.RemoveAllAnnuallyBoldedDates().RemoveAllBoldedDates().RemoveBoldedDate(NyariSzunetKezdete).AddBoldedDate(NyariSzunetVege).BoldedDates = Vakaciok. Dátumok visszaállítása (félkövér szedés megszüntetése): monthCalendar1. monthCalendar1. monthCalendar1. 197/312 . NyariSzunetVege}. A komponensek Value értéke tárolja. mint az egyéb komponensekben (textbox. stb. vagy Eszerre több fontos dátum létrehozása és komponenshez társítása: DateTime[] Vakaciok = {NyariSzunetKezdete.) lévı. AddAnnuallyBoldedDate.2. monthCalendar1.AddBoldedDate(NyariSzunetKezdete).

hanem a pozíciójelzı más helyre húzásával is történhet. A pozíciójelzı mozgatása nemcsak az irányokra kattintással lehetséges. Ennek a segítségével folyamatosan kérhetı le a komponens Value értéke. miközben a pozíciójelzıt mozgatjuk. és meghatározza a pozíciójelzı elhelyezkedését a görgetıcsúszkán. vagy a görgetı iránygombjainak megnyomásakor a Value érték a SmallChange érték szerint változik. ha a Value a minimális és maximális értékek számtani közepe. akkor a pozíciójelzı a csúszka bal szélén (vízszintes görgetı) vagy tetején (függıleges görgetı) van. A Value értéke csak a Minimum és Maximum által megadott intervallumban lehet. amikor a felhasználó az alsó-felsı vagy bal-jobb gombok valamelyikére kattint. Hasonlóan. 198/312 . akkor jobb szélen ill. mely kezdetben 0. vagy megnyomja a PgUp/PgDn gombok valamelyikét Alap: 10 A pozíciójelzı maximális helye Alap: 100 A pozíciójelzı minimális helye Alap: 0 A pozíciójelzı elmozdulása. Tulajdonságok: LargeChange Maximum Minimum SmallChange Value A gırgetı értékének változása. SmallChange A nyílbillentyők megnyomásakor.A ScrollBar komponensek a Scroll eseményt használják a pozíciójelzı mozgásának figyelésére. vagy a görgetısávon kattint a pozíciójelzı valamelyik oldalán. akkor a csúszka közepén van. ha az állapotjelzı elmozdul A Value értéke egész szám. ha maximális. LargeChange Ha a felhasználó lenyomja a PageUp vagy PageDown gombok valamelyikét. amikor a görgetıcsúszkán kattint a felhasználó. alul van. úgy a Value érték a LargeChange érték szerint változik. vagy a nyílbillentyőket megnyomja Alap: 1 A pozíciójelzı helye Alap: 0 Események: Scroll Bekövetkezik. Ha minimális az érték.

a megfelelı beállításokkal. hScrollBar1.Dock = DockStyle. HScrollBar hScrollBar1 = new HScrollBar().One: egyszerre egy adatot választhatok ki a ListBoxból.None: . ha az egérrel a ListBoxra kattintok vagy kijelölhetek a fel-.Bottom. // A görgetıt a form aljához igazítjuk. this. 199/312 . SelectionMode: a ListBox adatait jelölheti ki a felhasználó.Példa: vízszintes ScrollBar létrehozása és formhoz rendelése: private void InitializeMyScrollBar() { // HScrollBar létrehozása és alapállapotba állítása. // A görgetı hozzáadása a form vezérlıihez. ha az egérrel a ListBox elemeire kattintok illetve ha a Space billentyőt nyomva tartjuk.Controls. .MultiSimple: itt több adatot is kiválaszthatunk egyszerre.és jobbra-nyíl billentyőkkel. akár egyszerre több adatot is. Négy lehetséges beállítás létezik: . balra.Add(hScrollBar1). le-. } Listbox Egy listablak lehetıvé teszi a felhasználó által megadott adatok kiválasztását a listából. A One beállítás az alapértelmezett.

ha false akkor nem látszanak. HorizontalScrollBar: a görgetıket adhatjuk meg. másolás.). A komponensek csoportba foglalásához elıször adjuk az alkalmazásunk Formjához a Panelt. 200/312 . A Panel komponenshez az elemeket a tervezési idı alatt adjuk hozzá (pédául megtervezünk egy eszközsort). Ha a ListBox magassága nagyobb vagy egyenlı mint a ListBox adatainak magassága. akkor nem látszik a görgetı. Panel. a false az alapértelmezett beállítás. és a fentebb említett billentyőkkel le-föl mozgunk. amelyek képesek más komponensek tárolására. ha a HorizontalScrollBar értéke true akkor látszanak a görgetık. akkor létrejön egy új szülı-gyermek kapcsolat a komponens és a Panel között. Ilyenkor a menüelem szürke színnel kerül kijelzésre és nem választható ki. Enadbled: Ha a Panel Enabled property-je false-ra. inaktívra van állítva akkor a Panel komponensei is inaktívak lesznek.- MultiExtended: több adatot is kiválaszthatok ha a Shift billentyőt nyomva tartom illetve az egér gomját lenyomva tartom. A Panel komponens kijelölése után a szokásos módon elhelyezhetjük benne a komponenseket. Amikor egy komponenst elhelyezünk a Panelen. hiába true a HorizontalScrollBar értéke. akkor az érinti a tárolt komponenseket is. Ha a tervezési idı alatt valamilyen mőveletet végzünk a Panellel (mozgatás. Panel Vannak olyan komponensek.Enabled=false. törlés stb. Ilyen tulajdonsággal rendelkezı komponens a Panel.

Button. mint a betöltött kép pictureBox1. illetve érhetjük el Image típusként. Sizemode: A PictureBoxSizeMode típusú Sizemode property-n keresztül szabályozhatjuk. az Image property-jére kattintva kiválaszthatunk egy Bmp.SizeMode = PictureBoxSizeMode. Ico.Windows. .AutoSize.AutoSize: a komponens mérete akkora lesz. mint amekkora a komponens 201/312 . melyet betölthetünk. Gif.StretchImage: a kép mérete akkora lesz.BorderStyle = System. .None: a Panel nem különböztethetı meg a Formtól. így programunk szállításakor elegendı azt vinni. hogy miként jelenjen meg a betöltött kép. A PictureBoxSizeMode felsorolt típus a következı elemeket tartalmazza: .BorderStyle = System. ez az alapbeálítás (a default) is. Jpg.BorderStyle.Forms.FixedSingle. Fontos tudnunk.Enabled=false. hogy az így betöltött kép bekerül a készítendı EXE állományba.Image = (Image) MyImage .Például ha egy gomb Enabled tulajdonságát inaktívra állítjuk akkor nem tudunk a gombra kattintani. Emf vagy Wmf formátumú képet. PictureBox Ha képeket szeretnénk megjeleníteni alkalmazásunk Form-ján. Miután feltettük a Form-ra a PictureBox komponenst. megjeleníthetünk a PictureBox területén. BorderStyle: A Panel BorderSytle property-nél három beállítás közül válaszhatunk: .FixedSingle: a Panel körül jól látható keretet kapunk panel1. akkor ennek legegyszerőbb módja a PictureBox komponens használata.Windows.Fixed3D. .Fixed3d: a Panel jól elkülöníthetı a Formtól panel1.BoderStyle. pictureBox1. a kép állományt nem kell. MyImage = new Bitmap(fileToDisplay). Image: Az Image property-n keresztül rendelhetünk képet a kontrolhoz.Forms.

SizeModeChanged: Amikor a SizeMode property értéke megváltozik. . Tulajdonságok: (Name) Enabled Interval Események: Tick A timer neve A timer engedélyezve van-e Alapértelmezés: False Események idızítése ezredmásodpercben megadva Alapértelmezés: 100 A megadott idıintervallum elteltével következik be 202/312 .Height property-kel adhatjuk meg a kép szélességét és magasságát. . Nincs lehetıség a timer szüneteltetésére.Normal: alaphelyzet. ySize). Timer komponens A timer komponens egy eseményt idéz elı rendszeres idıközönként.SizeMode = PictureBoxSizeMode. Az idıtartam az Interval tulajdonságban van megadva ezredmásodpercben.CenterImage. Ha megszakítjuk.CenterImage: a betöltött kép a komponens területének közepére igazodva jelenik meg pictureBox1.pictureBox1.SizeMode = PictureBoxSizeMode. Ha a timer engedélyezve van.SizeMode = PictureBoxSizeMode.Normal. ilyenkor a kép a komponens bal felsı sarkához lesz igazítva pictureBox1. ClientSize: A betöltött kép méreteit állíthatjuk be. a Size. A timer-t elindíthatjuk vagy leállíthatjuk.ClientSize = New Size(xSize. visszaáll alaphelyzetbe. a Tick esemény minden egyes alkalommal bekövetkezik.Width és Size. akkor kerül aktivizálásra a SizeModeChanged esemény.StretchImage. pictureBox1. ha eltelt a megadott intervallum.

Text = Convert. dátummal: //this.még akkor is. System.Now.Minute)+ ":"+Convert.lblOra.DateTime. tehát a leghosszabb intervallum is alig hosszabb egy percnél.ToString(System.Now.Second).ToString(System. hogy a megadott intervallum pontosan telik el.DateTime.Now. NumericUpDown Megjegyzés A NumericUpDown ellenırzés egyetlen numerikus értéket tartalmaz. A használó be is léphet egy értékbe. Az idınként kívánt eseményeket a Tick eseménybe kell beleírni.ToString( System. 203/312 .Hour)+ ":"+Convert.a leggyorsabb ütemezés csak a másodperc 18-ad része lehet.Például egy egyszerő óra Label komponensbıl: private void timer1_Tick(object sender. Hogy a pontosságot biztosítsuk. vagy más módon. Az Interval határai: A változó értéke 1 és 64767 közé eshet. amely növelhetı vagy csökkenthetı az ellenırzés fel vagy le billentyőjére való kattintásával. Itt állhat többsornyi programkód vagy egy egyszerő metódushívás is.A rendszer 18 óraütést generál másodpercenként.Now ).DateTime.Text = "Idı:"+ Convert.Stop(). de csak akkor. a timer-nek idınként ellenıriznie kell a rendszerórát.lblOra. Így .EventArgs e) { this.Nincs garantálva.ToString(System. timer1. ha a ReadOnly tulajdonság igazra van állítva.Start(). //egyszerőbben. ha az Interval tulajdonság ezredmásodpercben számolandó .DateTime.Timer kezelése Lehetıség van a timer leállítására és elindítására az alábbi két paranccsal: timer1. az Enabled tulajdonság igazra/hamisra állításával.

True. hogy meghatározza a Value tulajdonság csökkenı vagy növekvı értékét. Az értéket leellenırzi. Pontosabban meghatározva a decimal symbol után bemutatott számok mennyiségét állítsa be a DecimalPlaces tulajdonságot a decimális helyek számához. Kivétel Kivételes típus ArgumentException Feltétel A kijelölt érték nem pozitív. állítsa be a ThousandsSeperator tulajdonságot true-ra. a használó megváltoztatta a Text tulajdonságot. és az ellenırzés felülíródik az új érték megfelelı formátumával. állítsa be a Minimum és Maximum tulajdonságokat. hogy Minimum és Maximum értékek között legyen.A numerikus kijelzı alakítható a DecimalPlaces. ThousandsSeperator bemutatásakor decimális számokban. majd meghívja az UpdateEditText metódust. állítsa a Hexadecimal tulajdonságot true-ra. amikor rákattintunk a fel vagy le nyilakra a fel-le ellenırzésnél. Az ellenırzésben történı hexadecimális értékek beállításakor. Részletezve a megengedett értékek sorát az ellenırzés miatt. amikor lehetséges. Amikor meghívja az UpButton vagy DownButton metódusokat kóddal vagy a fel vagy le gombra kattintással. A hiányérték 1. amikor a felhasználó a fel vagy le nyílra kattint. 204/312 . ha UserEdit true-ra van állítva. akkor meghívja az UpdateEditText metódust. Hexadecimal vagy a ThousandsSeperator tulajdonságok beállításával. ParseEditText-et elızıleg meghívja az érték felülírása és jóváhagyása érdekében. Ha a Text tulajdonság be van állítva. míg a UserEdit tulajdonság true-ra van állítva. Különösen. A Value tulajdonság növelése vagy csökkentése akkor történik. másfelıl false. az új értéket jóváhagyja. Állítsa be az Increment értéket. Ha a Text tulajdonság be van állítva.

ha az értéket csak egyszer vagy kétszer kell beállítani. amikor egy egyszerő végösszeget mutat a Minimum és a Maximum között. ez egy könnyő módja a megoldásnak. mely a kéznél levı feladattól. akkor a ValidateEditText metódust hívja meg. ahol ismeri a kimért adatok egészét. ha szükséges csökkenteni a ProgressBar által megadott értéket. mintha lemezt olvasna egy adatforrásról. Ezt megteheti tervezett vagy szokásos idıben is. vagy a fájlok számát. Növelje a ProgressBar mutatót egy meghatározott értékkel. Végül. A ProgressBar értékének közvetlen beállítása 205/312 . Közvetlenül állítsa be a ProgressBar Control értékét. Közelebb visz a döntéshez. Ráadásul. az érték tulajdonságának a beállítása. amikor a megadott értéket különbözı összegekben ki kell cserélni. használja ezt az eljárást. Ez a megközelítés hasznos azokhoz a feladatokhoz.míg a UserEdit tulajdonság false-ra van állítva. Ez a megközelítés akkor hasznos. Növelje a ProgressBar mutatót egy értékkel. úgy. illetve a megoldandó problémától függ. ProgressBar A Value Displayed beállítása a Windows Forms ProgressBar Control által A NET Framework számos különbözı módot nyújt bemutatni egy adott értéket a ProgressBar Control-on belül. mint az eltelt idıt. amely változik. A ProgressBar értékének közvetlen beállítása A legközvetlenebb út a bemutatott érték beállítására a ProgressBar által. amelyet már feldolgozott egy ismert végösszegbıl. Ez a megközelítés hasznos.

hogy megváltoztassa a bemutatott értéket a Step tulajdonságban beállított mennyiségnek megfelelıen. Hívja meg a PerformStep metódust. 2. az ellenırzés kiad egy ArqumentException kivételt. Az értékek ebben a sorrendben logical units-ként fordulnak elı. akár billentyőzetet használva. hogy megváltoztassa az egész által meghatározott értéket. 206/312 . Ha beállította az érték tulajdonságát a Minimum és a Maximum által meghatározott határokon belül. amelyet már megadott. TrackBar ellenırzés A TrackBar egy ablak. Állítsa be a ProgressBar ellenırzését Minimum és Maximum értékre. Ez hasznos az idızítık és más szövegkönyvek számára. a TrackBar üzenetekben közli a változást. amikor a felhasználó állítja be azt. Például. Tipikusan minden egyes pozíciót ezek közül egy jellel azonosít. A ProgressBar értékének növelése egy kijelölt intervallum által Ha haladást mutat. hogy minden egyes növelés páratlan értékő legyen. hogy a felhasználó rangsorolja döntését egyedi érték vagy egymást követı értékek választása között.1. állítsa be az ellenırzés kódjának tulajdonságát egy integerre a Minimum és a Maximum értékek között. A slider egy TrackBar-ban akkor nı a meghatározott mértékben. 1. Állítsa be a ProgressBar ellenırzését Minimum és Maximum értékre. Hívja meg az Increment metódust. amikor betartja a páratlan mőveletek sorozatának útvonalát úgy. hogy a logical units-nak kell. A ProgressBar növelése egy dinamikai érték segítségével 1. Állítsa be az ellenırzés Step tulajdonságát egy egészre. amely növeli a ProgressBar Control értékét az intervallum által. Állítsa be ProgressBar ellenırzését Minimum és Maximum értékre. A ProgressBar értékének növelése változó mennyiséggel Végül növelheti a ProgressBar által bemutatott értéket úgy. beállíthatja az értéket. ábrázolva ezzel a ProgressBar bemutatott értékének növekedését. ha pontosítja. ahol a haladást nem az egész százalékaként mérik. Ez hasznos. hogy legyen 0-5 terjedı sorrendje. annak érdekében. A TrackBar akkor hasznos. Például. mint különbözı mérető fájlok írásakor a merevlemezre vagy a haladás az egész százalékaként való mérésekor. aztán meghív egy metódust. amely egy slider-t és tetszıleges mértékő jeleket tartalmaz. 3. akár egeret. hogy a slider-t egy megadott jelhez mozgatja. amikor azt szeretnénk. 2. 2. A kódban. Amikor a felhasználó mozgatja a slider-t. akkor a slider csak hat pozíciót foglalhat el: egy pozíció a TrackBar bal oldalán és egy pozíció minden egyes növekvésre sorrendben. amely egy meghatározott intervallumból ered. használhatja a TrackBar-t megengedve a felhasználónak a billentyőzet ismétlésének fokának beállítását azáltal.

Használhatjuk ezt az ellenırzést numerikus adat betöltésekor a Value tulajdonságon keresztül. A változások. Alakíthatjuk a sorrendet a Minimum tulajdonság beállításával a sorrend alacsonyabb végének pontosításával és a Maximum tulajdonságot a sorrend magasabb végének pontosításával. hogy hozzáadjunk egy jellegzetes Help stringet a komponenshez. be kell állítani a HelpNamespace tulajdonságot. Ez megtartja a távolságot. Miután létrehoztuk a TrackBar-t. amikor következıre kattint a slider egyik oldalán. Bejátszhatjuk ezt az adatot egy ellenırzésben vagy kód használatával. LargeChange tulajdonság Adjon meg vagy állítson be egy értéket hozzáadva vagy kivonva a Value tulajdonságból. hogy összekapcsoljuk a Help fájlt a HelpProvider objektummal. hogy a TrackBar megfelelıen változzon méretéhez képest. Figyelembe kell venni a LargeChange tulajdonság beállítását a magasság vagy a szélesség értékek százalékaként. pontosítva a TrackBar Class ablak osztályt. amelyeket beállítottunk okozott tartalmazzák a Minimum és Maximum pozíciók beállítását a slider számára. használjuk a SetHelpString metódust. használhatjuk TrackBar üzeneteket beállítani és helyrehozni néhány tulajdonságot. HelpProvider HelpProvider minden kérelme karbantartja a hozzákapcsolódó komponensek referenciáit. a Value tulajdonság a LargeChange tulajdonságban beállított érték szerint változik. Ez a string ettıl kezdıdıen egy pop-up menüben fog 207/312 . A TrackBar egy kacskaringó ellenırzés a ScrollBar ellenırzéshez hasonlóan. Ahhoz.Létrehozhatunk egy TrackBar-t a CreateWindowEx funkció használatával. amikor a scroll boksz nagyobb távolságban mozdul el. Ekkor meghatározunk egy típust. Kivételes típus Exception Feltétel A megjelölt érték kevesebb. beállítva a választások sorrendjét és újrapozícionálja a slider-t. vagy a TrackBar-ra kattint a slider egyik oldalán. jeleket rajzolva. A TrackBar bemutatható vízszintesen és függılegesen is. Ahhoz. A LargeChange tulajdonság definiálja a növekedést hozzáadva vagy kivonva a Value tulajdonságból. Hozzáadhatunk egy kulcsszót a segítséghez a SetHelpKeyword-el. mint nulla Amikor a felhasználó a PAGE UP vagy PAGE DOWN gombokat használja. amit SetHelpNavigator-nak neveznek és hozzáadjuk a HelpNavigator értéket a specifikált komponenshez.

A HelpProvider. Minta példa A bemutatandó példa demonstrálja.TextBox addressTextBox.chm-re van beállítva.Label().Run(new Form1()).Label label3. Ha a HelpNamespace nincs még beállítva. hogy a Help tartalom elérhetı.Label helpLabel. hogy Help szöveget adhassunk.TextBox zipTextBox.Label label2.label2 = new System. akkor a Help HelpNamespace-ben van és elsıbséggel rebdelkezik. Amikor a fókusz valamelyik cím mezın van és megnyomjuk az F1 billentyőt. Ha már beállítottad a HelpNamespace-t és a Help string-et. private System.Windows. persze csak akkor.Forms.Form { private System. private System. private System.HelpProvider helpProvider1.Windows. mert a HelpNamespace tulajdonság az mspaint.Windows.Windows. private System.chm Help fájl kiíródik.helpLabel = new System. akkor a ToolTip szöveg megjeleníti a hozzá főzött szöveget. Amikor a context-sensitive Help gombot (vagyis a kis kérdıjelet a jobb felsı sarokban) használjuk és ráklikkeljük a Help kurzort a cím mezıre.TextBox cityTextBox. hogy beállítsa a segítségnyujtó ToolTip szöveget.Windows.Windows.Forms.Label(). akkor a SetHelpString-et kell hsználnod. this. hogyan jeleníti meg a context-sensitive segítséget a formon.Windows. 208/312 . hogy a HelpProvider osztály.Forms. ha a fókuszt az a komponens birtokolja amelyikrıl segítséget akar kapni a felhasználó.Windows. this.Forms. akkor az mspaint.addressTextBox = new System. amikor a felhasználó rákattint az F1 billentyőre.TextBox().Forms.Forms.Forms.Forms. using System.Forms.TextBox stateTextBox.Windows.Windows.Windows.Forms. using System.Windows.Forms. A példa a SetHelpString-et használja.Forms.Windows. private System.Forms. public class Form1 : System. private System. private System. } public Form1() { this. SetShowHelp metódusa minden cím komponenshez hozzá van rendelve. using System.Drawing. [STAThread] static void Main() { Application.felvillanni. ami négy cím mezıt tartalmaz. hogy azonosítsa.

Drawing.this. "Enter the Click on a control and = 209/312 . // Address Label this.Text = "Click the Help button in the title bar.Location = new System.HelpProvider().Point(16.Point(8.helpProvider1.helpProvider1 = new System. "Enter the city here. // Comma Label this.Drawing.Size(272.helpLabel. this.Location = new System.SetShowHelp(this.Size = new System.Windows.SetHelpString(this. this. this.helpLabel.helpProvider1. this.cityTextBox.label2.SetHelpString(this. 16)."). this.label2. this.cityTextBox.". // Help Label this. 72).addressTextBox.helpProvider1.SetShowHelp(this.Drawing. // Tell the HelpProvider what controls to provide help for.label3 = new System. // Create the HelpProvider.Size(16.BorderStyle.cityTextBox = new System.Text = ". this.Fixed3D.helpProvider1.stateTextBox. this.helpLabel.").Windows. then click a control " + "to see a Help tooltip for the control.Text = "Address:".Size(100.TextBox().Windows. true).helpLabel.addressTextBox. and // what the help string is.Drawing.Forms. 8). press F1 to invoke " + "the Help system with a sample Help file.label3.Point(136.Forms.Drawing.". 16).TextBox(). this.label3.BorderStyle System.Location = new System. this.Windows.Label(). this.TextBox(). 80).Forms. this.Drawing. true).Size = new System.Windows.label3. this.Forms. 56). street address in this text box.helpProvider1.Size = new System. this.zipTextBox = new System. this.Forms.Windows.stateTextBox = new System.label2. true).SetShowHelp(this. this.Forms.

20). 20).helpProvider1. this.Drawing.Point(16.Location = new System.Drawing.zipTextBox.this. "Enter the "Enter the zip // Set what the Help file will be for the HelpProvider.zipTextBox. 24).SetHelpString(this.Windows. 48).Size(88.stateTextBox.Text = "". // Address TextBox this.Drawing.Size = new System.Size(264. 20).helpProvider1. // State TextBox this. 20). this.Size(120.cityTextBox.Size = new System. // City TextBox this. this. this. this.Point(152.Drawing.Point(16. // Zip TextBox this.stateTextBox.Drawing.addressTextBox.helpProvider1. true).TabIndex = 5. this.zipTextBox.cityTextBox. this.").addressTextBox. this. this. 48).cityTextBox.Text = "".addressTextBox.chm".stateTextBox.stateTextBox.label3. 48).Size = new System.Controls. this. 210/312 .Size = new System.TabIndex = 0.MaxLength = 2. this. this.Text = "".helpProvider1.Text = "". this. this.Drawing.stateTextBox.TabIndex = 3. this.zipTextBox.zipTextBox.HelpNamespace = "mspaint.stateTextBox. this. this.TabIndex = 6. // Add the controls to the form.Location = new System.cityTextBox. this. code here.Drawing.Size(32. this.Location = new System.zipTextBox.Point(192.Location = new System.SetHelpString(this.stateTextBox.Forms. state in this text box.cityTextBox. // Sets properties for the different address fields.AddRange(new System.SetShowHelp(this. this.Drawing.Control[] { this.").addressTextBox.zipTextBox.

Text = "Help Provider Demonstration". nem hajtódnak végre. amíg bizonyos mőveletek.FormBorderStyle System. using System. namespace myImageRotator { using System. vagy meta fájlokat. using System.MaximizeBox = false. és azután megjeleníti.this. this. this.Size(292.HelpButton = true.FormBorderStyle. this.label2. // Set the form to look like a dialog. using System. Ez az osztály nem örökölhetı. this.ComponentModel.addressTextBox}). mint például az ImageList feltöltése képekkel. és a különbözı komponensek használhatják azokat.Drawing. Példa A következı példa megmutatja a kijelölt képeket. ikonokat. ImageListhez adhatunk bitmaps. 160). TreeView. and show the HelpButton. Észrevételek ImageList-et tipikusan például ListView. megváltoztatja. this. ha igényük van rá.ClientSize = new System.helpLabel. vagy ToolBar-nál szokás használni. this.Windows. 211/312 .Drawing.Windows.MinimizeBox = false.FixedDialog. } } = ImageList Függvényeket biztosít az Image objektumok győjteményének irányításához. this. this. Ez a fogantyú „Handle” mindaddig nem jön létre. ImageList használ egy fogantyút a képek listájának irányítására.Forms.Forms.

protected Label label2.Forms. protected OpenFileDialog openFileDialog1. protected Label label5. // Assigns the graphics object to use in the draw options.Dispose(). protected Button button3. protected Graphics myGraphics.Handle). protected ListBox listBox1. protected Button button1. protected Button button2. imageList1 = new ImageList () .FromHwnd(panel1.Windows. imageList1.public class Form1 : System.TransparentColor = Color. myGraphics = Graphics. imageList1. } } 212/312 .255).Form { protected Container components. protected PictureBox pictureBox1. protected Label label3. which sets up a larger // image size. } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components. public Form1() { InitializeComponent(). private int currentImage = 0. protected Button button4.White.ImageSize = new Size(255. protected ImageList imageList1. // The default image size is 16 x 16. protected Panel panel1.

} protected void button3_Click (object sender. panel1. button4. } protected void button1_Click (object sender. label2. System. i < openFileDialog1.SelectedIndex). label1.FileNames. button3. } private void InitializeComponent() { // kezıérték beállítás a listBox1.Dispose( disposing ). } protected void button4_Click (object sender.Clear(). System.EventArgs e) { displayNextImage(). } protected void button2_Click (object sender.Images.Images.Length . } } else addImage(openFileDialog1. és imageList1-nek.ShowDialog() == DialogResult.EventArgs e) { imageList1. 213/312 .base.RemoveAt(listBox1.EventArgs e) { imageList1.FileName).Multiselect = true . System. pictureBox1. if(openFileDialog1. System.EventArgs e) { openFileDialog1. // button2.FileNames[i]). i++ ) { addImage(openFileDialog1. listBox1. // button1.Remove(listBox1.SelectedIndex). openFileDialog1.OK) { if (openFileDialog1.Items.FileNames != null) { for(int i =0 .

EndUpdate().Count-1 > currentImage) { currentImage++.Images[currentImage].Text = "Current image is " + currentImage . imageList1.Items. listBox1. listBox1.Text . label5.Text = "Image is " + listBox1.Images.Images.Add(imageToLoad). } } void displayNextImage() { if(imageList1. panel1.Refresh().SelectedIndex = currentImage.Run(new Form1()).10.FromFile(imageToLoad)).Images. pictureBox1. listBox1. } } } 214/312 .Image = imageList1. listBox1.Empty != true) { if(imageList1.Draw(myGraphics. } } public static void Main(string[] args) { Application. label3.Add(Image.currentImage). } else currentImage=0.BeginUpdate().} } private void addImage(string imageToLoad) { if (imageToLoad != "") { imageList1.10.

A szöveget kijelölhetjük közvetlenül a komponensben. Észerevételek: A RichTextBox komponens megengedi a felhasználónak. ami mellett még több. Itt lehet a képeket az ImageListhez főzni Képméret beállítása Beállíthatjuk a fogantyút az ImageListStreamerhez összekapcsolva az aktuális kép listával Beállítja az Isitetot a komponenshez Szináttetszıség beállítása Site TransparentColor RichTextBox Reprezentál egy Windows rich text box komponenst. vagy egy egyszerő text fájlból. 215/312 .Tulajdonságok ColorDepth Contanier Handle HandleCreated Images ImagesSize ImageStream Beállítja a kép lista képeinek szín telítettségét Beállítja az IContaniert amit a komponens tartalmaz Beállítja a kép lista objektum bizonyos fogantyúját Beállítja az értéket ha Win32-es fogantyút készítettünk. egymástól különbözı formátumot is engedélyez. hogy belépjen és szerkessze a szöveget. vagy be tölthetjük egy Rich Text Format (RTF) fájlból. A komponensen belüli szöveg lehet egyszerő karakteres vagy paragraph formátumú. mint egy mezei TextBox komponens.

hogy adatot tároljon a memóriában.Fill. A LoadFile metódus megengedi. a szövegen. hogy megfelelıen jelenjen meg a link a komponens szövegében. Még arra is használhatjuk. majd ezekkel a változtatásokkal visszamenti az eredeti fájlba. Gyorslista készítéséhez. hogy stringeket keressünk a szövegben. Ezután a program megváltoztatja a kijelölt szövegrész bető típusát. hogy megfelelı RTF vagy ASCII szöveget. annak bármelyik részén. használjuk a SelectionBullet tulajdonságot. A SelectionFont tulajdonság lehetıséget biztosít számunkra. hogy a szöveg a komponensen belül védve legyen a felhasználók manipulációival szemben. hogy ez a szövegrész számára nem módosítható. richTextBox1. A Find metódus is arra is lehetıséget biztosít. amiket már más megnyitott velünk egy idıben. ahol a "Text" kifelyezés jelen van. hogy megváltoztassuk a szöveg formátumát. hogy hasonló stringeket keress a szövegben. ha módosítani akarja. A SaveFile metódus megengedi. 216/312 . hivatkozhatunk a Protected eventre. A SelectionProtected tulajdonsággal engedélyezhetjük azt. hogy megfelelı RTF vagy ASCII fájl formátumban mentsünk el szövegeket. Ezután a LinkClicked eventtel elérhetjük. Ahhoz. elıször ki kell jelölni. amivel közölhetjük a mezei felhasználóval.rtf"). a SaveFile metódust is tudjuk arra használni. SelectionRightIndent. mint a LoadFile metódus. Hasonló módon. hogy alkalmazhassunk egy formátumot. tartalmazó fájlokat nyissunk meg a komponensbe. Végezetül a megoldásban hozzáadja a Form felületéhez a RichTextBoxot. A RichTextBox komponens olyan metódusokat is ad amelyek funkcióival tudsz megnyithatunk vagy menthetünk fájlokat. színét. majd megkeresi az elsı helyet. hogy egy megnyitott fájlba menthetünk. méretét. A RichTextBox komponens olyan lehetıséget is ad. Ezen felül még olyan fájlokat is meg tudsz nyitni. hogy a szöveg bold vagy italic legyen. beállíthatjuk a paragraph formátumot a SelectionIndent. Az is megvalósítható. Ezzel a levédett szöveggel a komponensen belül. public void CreateMyRichTextBox() { RichTextBox richTextBox1 = new RichTextBox(). mondjuk egy web sitera.MatchCase).LoadFile("C:\\MyDocument. amit fel tudsz használni a komponensen belül. akkor használhassuk a DetectUrls tulajdonságot. richTextBox1. ami beolvas egy RTF fájlt. Alkalmazásokat. RichTextBoxFinds. SelectionColor tulajdonsággal a szöveg színe állítható be. Ha a komponensen belüli szöveg tartalmaz egy linket. hogy ez mőködjön is. Csak a kijelölt szövegben tudjuk megváltoztatni a karakter és paragraph formátumot. Példa: A bemutatandó példában készítünk egy RichTextBox komponenst.A RichTextBox komponens ad egy számot a tulajdonságairól. hogy meghatározzuk a méretét vagy a betőképet. richTextBox1. amelyeket már a TextBox komponens is használ. könnyen bele lehet építeni a RichTextBox komponensbe. és SelectionHangingIndent tulajdonságokkal. azonban a RichTextBox komponens nem tartalmazza a TextBox 64k karakter kapacitás limitjét.Dock = DockStyle.Find("Text".

hogy lehet e módosítani a tartalmát Háttérkép Háttér szín Nem kliens tartalmának a mérete Annak a téglalapnak a tulajdonságait lehet beállítani. RichTextBoxStreamType.rtf". this.SelectionFont = new Font("Verdana". 217/312 .richTextBox1.RichText).SaveFile("C:\\MyDocument. } Néhány fontosabb Tulajdonság: Dock AutoSize Enabled BackGroundImage BackColor Bounds ClientRectangle ClientSize Hogy hol helyeszkedjen el a formon belül Automatikusan beállítja a komponens méretét font változtatás után Meghatározza. amit a kliens használ A felhasználó által használható terület hosszúságát és szélességét lehet beállítani Beállítja a komponens gyorsindító menüjét Tartalmazza a komponensen belül használható komponenseket Az egér mutató kinézete amíg a komponens felett van Beállítja a komponenst ha több gyermek származik belıle Magasság Szélesség Balról behúzás Jobbról behúzás Felülrıl Alulról Méret …… ContextMenu Controls Cursor HasChildren Height Width Left Right Top Bottom Size Stb….Controls.Add(richTextBox1).Red. richTextBox1. richTextBox1.Bold).SelectionColor = Color. FontStyle. 12.

ha rápozícionálnak az egérrel egy komponensre. használjuk a ToolTip komponens konstruktorát. hozzá rendelhetünk egy TextBox komponenshez egy ToolTip szöveget. A SetToolTip függvény több mint egyszer tudja utasítani a különbözı komponenseknek. hogy kiírja a képernyıre a kapcsolat aktuális sebességét is vagy az egér fókuszát. ami megadhatja a TextBox nevét és típusát. hogy specifikáljuk egy konténert. amire az egérrel rápozícionálunk. Ahhoz. amivel össze vannak kötve. A ToolTip osztályt valamennyi tárolóban használhatjuk. Észrevételek: A ToolTip osztály lehetıséget ad. Például.ToolTip Reprezentál egy kis téglalap alakú. Ha azt akarjuk. amit oda be lehet írni. A ToolTip osztályt tipikusan arra használják. mikor a felhasználó azt a PictureBox felett mozgatja. Hogy egy ToolTip szöveg kiírodjon amikor a felhasználó egy komponens fölé pozícionál az egérrel. A ToolTip szöveg a komponens összekapcsolására használd a SetToolTip függvényt. Összegezve a segítségen felül a ToolTp osztály futásközbeni információadásra is nagyon jól használható. hogy változtassák meg a szövegüket. felbukkanó ablakot. hogy felhívják a felhasználók figyelmét a kontrol használatáról. 218/312 . hogy segítsünk a felhasználóknak. hogy a szöveg össze legyen kötve a komponenssel. a ToolTip szövegnek össze kell lennie kapcsolva a komponenssel egy kérelem formájában a ToolTip osztályban. ami tömör szövegben kijelzi annak a dolognak a tulajdonságát vagy használatát. Például arra is használhatjuk.

és ReshowDelay-el. private void Form1_Load(object sender. "My checkBox1"). ToolTip toolTip1 = new ToolTip(). toolTip1. ami nincs engedélyezve.EventArgs e) { // Create the ToolTip and associate with the Form container.A ShowAlways tulajdonság igazra állításával tudjuk beállítani.ReshowDelay = 500. "My button1"). egy Button-al és egy CheckBox-al.SetToolTip(this. amíg a Form fut.AutoPopDelay = 5000.button1. A kód ezután initalizál késleltetı tulajdonságokat az AutoPopDelay. mikor egyik komponensrıl a másikra megyünk át Szövegkijelzés beállítása ha a form nem aktív ISite Component InitalDelay ReshowDelay ShowAllways Site 219/312 .checkBox1.InitialDelay = 1000. a példabeli megoldás összeköti a ToolTip szöveget két komponenssel a Formon.használjuk a GetToolTip függvényt. toolTip1. amikor rá pozícionálunk Az az idı amíg vár mielıtt megjelenik a szöveg Annak az idınek a hosszát lehet beállítani. InitialDelay. toolTip1. toolTip1. amíg várnia kell a szöveg felvillantásakor. Ha törölni akarjuk az összes ToolTip szöveget. a RemoveAll függvényt használjuk. System. Automatikus késleltetés beállítása Itt állíthatjuk be azt az idıt amíg a szöveg jelen legyen. amíg a Tooltip aktív. Példa: A követendı példa készít egy hivatkozást és összeköti azt a Formmal egy beépített kérelemmel. Megjegyzés: A ToolTip szöveg olyan komponens fölé nem íródik ki. toolTip1. toolTip1. // Set up the delays for the ToolTip.SetToolTip(this. Végezetül.ShowAlways = true. } Tulajdonságok: Active AutomaticDelay AutoPopDelay Megadja vagy beállítja a kijelezendı értéket. hogy a ToolTip szövegek mindaddig megjelenjenek.

hogy egyenlık –e. Ezt a menüt általában arra használjuk. Visszaadja a MeniItem objektumokat. törölhetjük stb… A ContextMenü részei: Publikus konstruktor ContextMenu konstruktor A ContextMenu osztály példányát inicializálja.ContextMenu A ContextMenu-rıl általában: A ContextMenu osztály egy menüt szolgáltat. Visszaadja . 220/312 . hogy a MainMenu elemeit összeválogatva. egy új Publikus propertik Container MenuItems SourceControl Visszaadja azt az Icontainer-t ami tartalmazza a komponenst. hogy melyik kontrol jeleníti meg a menüt. így segítve a felhasználót. Például a TextBox-hoz rendelhetünk egy contextmenüt. az egyes területekhez rendeljük ıket. amik a menüben vannak. amit egy kontrol vagy a form fölött az egér jobb gombjának lenyomásával érhetünk el. Publikus metódusok Equals Eldönti két objektum példányról. melynek segítségével beállítható a TextBox szövegének betütípusa vagy a vágólapra másolhatjuk.

hogy a komponens design módban van –e. Bekövetkezik mielıtt megjelenítésre kerül. Events Protected metódusok CloneMenu Dispose Finalize Paraméterként lemásolja a menüt az aktuális menübe. A Toolbox-ban kattintsunk kettıt a ContextMenu komponensre. A komponenshez tartozó eseménykezelık listáját adja vissza. Visszaadja a MainMenu-t. Egyesíti egy menü MenuItem objektumait az aktuális menüével. tartalmazza ezt a menüt. ami ami Visszadaja az aktuális példány típusát.GetContextMenu GetMainMenu GetType MergeMenu Show ToString Visszaadja a ContextMenu-t. ami ekkor a komponens tálcához adódik. Felszabadítja a nem ezközöket forrásokat a collection elıtt. ami figyeli a komponens Disposed eseményét. A menüt egy megadott pozícióban jeleníti meg. Az objektumot String formára alakítja. ami mutatja . a menü Protected property-k DesignMode Egy értéket ad vissza. Elengedi a komponens által használt forrásokat. 221/312 . Public események Disposed Popup Egy esemnykezelıt ad. tartalmazza ezt a menüt. használt garbage ContextMenu hozzáadása a Windows Formhoz: Nyíssuk meg a Windows Form Designerben azt a formot amihez hozzá akarjuk adni a ContextMenu-t.

Public Property-k Container ContextMenu Icon Text Visszaadja az Icontainer-t tartalmazza a komponenst. Beállítható vagy lekérdezhetı a tooltip szövege. a hangerıszabályzó stb… Ezeken az ikonokon keresztől férhetünk ezen programok felhasználói interfészéhez. Azt. hogy milyen felugró menü tartozzon hozzá. ha az egérmutatót a system trayen lévı ikon fölé helyezzük. lekérdezése. 222/312 . ami ContextMenu beállítása. a ContextMenu property segítségével állíthajuk be. Ilyenek például a különbözı virusírtó programok. NotifyIcon NotifyIcon-ról általában: A System tray-en látható ikonok. Az Icon property definiálja.és bekapcsolása. NotifyIcon részei: Public Konstruktor NotifyIcon Constructor A NotifyIcon ısosztály egy új példányát initializálja. Ikon beállitása. milyen programok futnak a háttérben. mutatják. lekérdezése. NotifyIcon láthatóságának ki. Visible Public Események Click Akkor következik be ha az ikonra kattintunk a system tray-en.A ContextMenu-t a formhoz vagy kontrollokhoz rendelhetjük a Properties ablakban az objektumok ContextMenu property-jének beállításával. A Text tulajdonság pedig akkor jelenik meg ha az egér mutatóját az ikon fölött idıztetjük. ami akkor jelenik meg. A NotifyIcon osztály ezt a funkcionalitást kínálja a programok számára. hogy milyen ikon jelenjen meg a System tray-en.

A StatusBar-on helyet kap még a SizingGrip. ami figyeli a komponens Disposed eseményét. 223/312 . vagy újra megnyomjuk a jobb gombját. Ezeken a paneleken szövegek és/vagy ikonok találhatóak. MouseMove MouseUp StatusBar StatusBar-ról általában: A StatusBar kontrol StatusBarPanel objektumokat tartalmaz. A StatusBar kontrol tipikusan arra szolgál. amelynek segítségével a form méreteit állíthatjuk be. Akkor következik be ha a system trayen az ikon fölött lenyomjuk az egér gombját. Akkor következik be ha a system trayen az ikon fölött elengedjük az egér balgomját.Disposed DoubleClick MouseDown Egy eseménykezelıt ad. Akkor következik be ha a system trayen az ikon fölött mozgatjuk az egér mutatóját. hogy a formon található objektumokról információt szolgáltasson. StatusBar részei: Public Konstruktor StatusBar Constructor A StatusBar osztály egy új példányát inicializálja. Akkor következik be ha az ikonra duplán kattintunk a system tray-en.

Beállítható. bekapcsolása a StatusBar méreteinek beállítása. be ContextMenu Cursor Enabled Font Location Panels ShowPanels Size SizingGrip Betőtipus beállítása. Text Visible Public Események Click DragDrop PanelClick Mikor a kontrolra kattintunk. A SizingGrip ki-. A pozíció beállítása. amit a felhasználó rádobott. a StatusBar-t ki. A StatusBarPanelok collection-ja amiket a StatusBar tartalmaz. StatusBar-on.Public Property-k Name AllowDrop Az objektum neve. esemény Amikor valamelyik panelra kattintunk. lekérdezése. 224/312 . hogy az egérmutató milyen legyen amikor a ToolBar felé ér. lekérdezhetı az értéke annak. ill. A panelok ki-. ContextMenu beállítása. Drag-and-drop bekövetkezésekor. Beállítható. hogy a kontrol elfogadja –e az adatot. ki-. bekapcsolása (melynek segítségével a form méretei állíthatóak) A StatusBar-on látható szöveg StatusBar láthatóságának bekapcsolása. Ezzel lehet kapcsolni.

amik standard. A gombokra képeket rakhatunk és különbözı stílusúra állithatjuk ıket. toggle. A ToolBar-t úgy 225/312 .ToolBar A ToolBar-ról általában: A ToolBar kotrollokat arra használjuk. hogy ToolBarButton-okat jelenítsünk meg a képernyın. illetve drop-down stílusú gombok lehetnek.

mint egy menüt. lekérdezhetı az értéke annak. A ToolBar poziciójának beállítása. hogy a ToolBar hol Appearance AutoSize BorderStyle Buttons ButtonSize ContextMenu Cursor Dock Enabled Font ImageList Location Name Size Ezzel lehet a ToolBar-t ki. A ToolBaron lévı gombok méretének beállítása. Automatikus méretezés beállítása és lekérdezése.használjuk. lekérdezése. A Toolbar neve. így gyorsítva a munkát. hogy a kontrol elfogadja –e az adatot. Beállítható. A Toolbar méretének beállítása. A gombok menüpontoknak felelnek meg. Betőtipus beállítása. A ToolBar kontrol és a gombjai megjelenítésének beállítása és lekérdezése. ContextMenu beállítása. A Toolbar részei: Public konstruktor ToolBar Constructor A ToolBar osztály egy új példányát inicializálja. csak mindig szem elıtt vannak. Beálliható. dokkoljon. amit a felhasználó rádobott. Szegély stílusának beállítása. Beállítható. be kapcsolni. 226/312 . Public Property-k AllowDrop Beállítható. hogy az egérmutató milyen legyen amikor a ToolBar felé ér. A ToolBar-on megjelenı ToolBarButtonok gyüjteménye. hogy a gombok képei melyik ImageList-bıl legyenek elérhetıek. lekérdezése. ill.

Public események ButtonClick ButtonDropDown Akkor következik be ha a ToolBaron egy ToolBarButton-ra kattintunk. Drag-and-drop esemény bekövetkezésekor. nem látható. DragDrop 227/312 .Visible Látható. Public metódusok DoDragDrop FindForm Drag-and-drop mővelet engedélyezése. Akkor következik be ha egy drop-down stílusú gombra vagy a nyilára kattintunk. Visszadja a formot. amin a kontrol rajta van.

) A form és a formon lévı kontrollok default fontbeállítása A form keretének stílusa: default: sizable None. minnél kisebb a %. } BackColor BackgroundImage Font FormBorderStyle Háttérszín Háttérkép. Ez tartalmazhat szöveget. png. annál jobban átlátható a form Default: true. és képi szimbólumot. SizableToolWindow A formra elhelyezett gombok alapértelmezett jelentése lehet Buttons: AcceptButton. akkor a visszatérési értéke egy DialogResult osztály példánya. height) StartPosition Text WindowState MainMenu obj. ha az értéke false. static void Main() { Application. nyomógombokat. CancelButton. akkor nem jelenik meg a taskbaron a program. hogy a felhasználó mely nyomógombra való kattintással zárta az üzenetablakot.Formok használata. A form mérete pixelben A form megjelenéskor hol helyezkedjen el: WindowsDefaultLocation Manual CenterScreen CenterParent WindowsDefaultBounds (nem ajánlott) A form fejlécében megjelenı szöveg Form állapota Normal. kiválasztható (jpg. Fixed3D. 100% az átlátszatlan. Minimized. 228/312 . Átlátszóság. melynek paraméterei határozzák meg a megjelenést. formok típusai Formok jellemzıi: (Name) A form azonosítója. bmp .Run(new frmMain()). Ne felejtsük módosítani a forráskódban is! Nem automatikus. maximized A rendszer által biztosított üzenetablakok használata A MessageBox osztály segítségével tudunk egy üzenetablakot megjeleníteni a képernyın. melynek a segítségével meghatározhatjuk. HelpButton Menu Opacity ShowInTaskbar Size (width. FixedToolWindow. a programon belül hivatkozhatunk a formra ezzel. Az üzenetablak megjelenítését a Show metódus végzi. FixedSingle. Ha nyomógombokat is tartalmaz. FixedDialog.…. Neve.

Show("ez az üzenet jelenik meg az ablakban".A példában a Show metódusnál kihasználtuk ezeket a paramétereket. Az elsı sorban létrehozunk a DialogResult osztályból egy példányt. string konstans. vagy string típusú változó. hogy milyen nyomógombok jelenjenek meg a formon. Az elsı paramétere a megjelenítendı szöveg. MessageBoxIcon. A harmadik paraméter határozza meg. dr = MessageBox. A példaprogram Üzenet gombja bemutatja az alkalmazás módját. Majd a MessageBox. A MessageBoxIcon segítségével az alábbi képecskéket választhatjuk: Asterisk Error Exclamation 229/312 . Ennek a neve dr. "Ez a form fejlece". A második paramétere szintén string. MessageBoxButtons.Question). de lehetıségünk van elhagyni is belıle. melynek a lehetséges értékei: AbortRetryIgnore Ok OKCancel RetryCancel YesNo YesNoCancel Ezek közül választhatunk a gombok kiválasztásánál. A megjelenítése: DialogResult dr = new DialogResult().YesNoCancel. ez lesz a megjelenı form fejlécének felirata. A MessageBoxButtons egy felsorolt típus. A negyedik paraméter a képi szimbólumot határozza meg.Show metódushívással megjelenítjük az üzenetablakot.

MessageBoxButtons. } case DialogResult. break. hogy a felhasználó melyik nyomógombot választotta. } } 230/312 .OK). break.No: { MessageBox."fejléc".Yes: { MessageBox. break.Hand Information None Question Stop Warning Ezek után az üzenetablak így jelenik meg: Ezután egy egyszerő switch szerkezettel el lehet dönteni."fejléc". switch (dr) { case DialogResult.MessageBoxButtons.Show("CANCEL".OK)."fejléc".Cancel: { MessageBox.Show("NO".OK).Show("YES". } case DialogResult.MessageBoxButtons.

Erre látunk egy példát az következı képen.Ebben a példában látható. akár a hívó form újra aktivizálható. azaz elhagyható az icon meghatározás. hanem akár más form. 231/312 . Így ha nem ellenırizzük programból. akár több ugyanolyan form is megjeleníthetı. a visible tulajdonságának true-ra állításával. Modális és nem modális formok A saját formok megjelenítésénél két lehetıség között választhatunk. hogy a MessageBox-nak lehetséges 3 paramétere is. de nem birtokolja a fokuszt kizárólagosan. A Show() metódus megjeleníti a formot. A form megjelenik.

Ekkor a formunk egy dialógus boxként jelenik meg. 232/312 . frmK.Show(). Példányosítás után megjelenítjük a formunkat. akkor a ShowModal() metódust kell használnunk.A példaprogramban a ’Nem modális’ gombra kattintva érhetjük ezt el. amelyik kizárolagosan birtokolja a fókuszt. frmKetto frmK = new frmKetto(). Ha a másik lehetıséget választjuk.

frmKetto frmK = new frmKetto(). A megjelenítésre példa. dr = frmK.ShowDialog(this).OK). frmK. ami egy DialogResult példány. DialogResult dr = new DialogResult(). és látható formot sem. else if (dr == DialogResult.Show("Mégse gombbal zártad" . frmKetto frmK = new frmKetto(). Ennek a metódusnak van visszatérési értéke."fejléc". Ha szeretnénk használni a kiértékelés adta lehetıséget is. ha a ’Modális’ gombra kattintunk. majd a hívó helyen a megjelenítés köré szervezzünk egy vizsgálatot.OK).Cancel) MessageBox."fejléc" . akkor a megjelenı formon lévı gombok tulajdonságai közül a DialogResult értéket állítsuk be a nekünk megfelelıre. a programohoz tartozó. Ennek felhasználásával kiértékelhetjük.MessageBoxButtons.ShowDialog(). 233/312 . hogy melyik nyomógomb segítségével zárta be az ablakot a felhasználó. vagy más. if (dr == DialogResult.OK) MessageBox.MessageBoxButtons.Nem aktiválhatjuk az ıt hívó formot.Show("Rendben gombbal zártad".

} Az eljárás hatására a listBox-ban tárolt szöveg fontja a fontDialog-ban kiválasztott font tulajdonságait kapja meg. de elı lehet állítani ıket dinamikusan. paramétereket kérni tıle. majd a megfelelı komponens fontkészletéhez hozzárendelhetjük a felhasználó választásának eredményét. melyen a felhasználói beállítások elvégezhetıek.ShowDialog().Dialógusok A különbözı párbeszéd ablakoknak. A dialógusok megtalálhatóak a komponens palettán. hibaüzeneteket generálni. helyezzünk a Form-ra egy listBox-ot. System. egy fontDialog-ot és egy nyomógombot (button)! 234/312 . valamely megfelelı osztályból történı származtatással is. listBox1.EventArgs e) { fontDialog1. vagyis a kívánt font típust.Font=fontDialog1. mivel segítségükkel tudunk a felhasználóval kommunikálni.Font. A fontDialog A FontDialog elindítása és a fontkészlet kiválasztása a következı módon történik: a fontDialog ShowDialog() eseményével tudjuk aktivizálni azt a párbeszéd panelt. Amennyiben programot szeretnénk készíteni a fontDialog komponens kipróbálására. vagy beállításokat. private void button1_Click(object sender. dialógusoknak fontos szerepe van a Windows alatt futó programok készítésénél.

A listBox Items tulajdonságánál gépeljünk tetszıleges szöveget a listBox-ba.NET elhelyezi a kódban!) A futtatáskor a következı kimenet látható: Az C# nyelv vizuális részében található többi dialógus is hasonló módon mőködik. a nyomógomb eseménykezelıjébe pedig a fenti programrészletet írjuk! (Csak a függvényben lévı utasításokat gépeljük be. mivel a nyomógombhoz tartozó függvényt a . Az alábbi táblázatban összefoglaltuk a fontosabbakat. Színek kiválasztása Font megváltoztatása colorDialog fontDialog Nyomtatási kép printDialog Fájl megnyitása openFileDialog 235/312 .

Fájl mentése saveFileDialog ColorDialog Ez a komponens alkalmas a különbözı hátterek. ez a komponens is hasonlóan mőködik. csak míg az a fontok. System. Amennyiben ki akarjuk próbálni ezt a komponenst is. ez a színek kiválasztására alkalmas. a FontDialog.ShowDialog(). mint az elızı. a programunkat az elızı példa alapján építsük fel! Az így megírt program kimenete a következı: 236/312 . felületek színének kiválasztására. (Természetesen a kiválasztott színt végül nekünk kell hozzárendelni az adott komponenshez.) A következı forráskód megmutatja a colorDialog használatát: private void button2_Click(object sender.EventArgs e) { colorDialog1. } Mint láthatjuk.

: a Word ”nyomtatási kép” ablakához. } A nyomtatás kezelése igényel még néhány sornyi forráskódot. 237/312 . hogy a programjainkból nyomtatóra szeretnénk küldeni bizonyos adatokat. s a felhasználónak megmutatni a tényleges nyomtatás elıtt. mely hasonló pl. A nyomtatási kép megjelenítéséhez a printPreviewDialog komponenst használhatjuk. Ilyen esetekben a nyomtatási képet nem árt megvizsgálni. de a megírása nem tartozik szorosan a fejezethez.PrintPreviewDialog Sokszor elıfordul. ahogyan az elızıeket: private void button2_Click(object sender.EventArgs e) { printPreviewDialog1. System. A párbeszéd ablakot úgy aktivizáltuk.ShowDialog().

238/312 . hogy meghívjuk a showDialog() függvényüket. s támogatják a fájlkezeléshez szükséges metódusokkal. majd a kiválasztott fájlt (fájlokat) a megfelelı metódusok segítségével elmentjük. Csak annyi a dolgunk velük. Ez a két komponens is könnyen használható. vagy éppen betöltjük. segítve ezzel a kommunikációt a felhasználóval.Show("Üzenetablak komponens futás közben"). A következı forráskód részlet bemutatja a MsgBox használatát: MessageBox. MessageBox Fontos még megemlíteni a MessageBox osztályt is. mivel a Windows-ban megszokott fájltallózó ablakokat aktivizálják.Fájl megnyitása és mentése Az openFileDialog és a saveFileDialog a fájlok megnyitását és kimentését teszik egyszerővé. melynek metódusaival különbözı párbeszéd paneleket tudunk megjeleníteni a képernyın.

az alábbi kimenethez jutunk: Feladatok 1. Készítsünk programot. hogy egy listBox-ba írt szöveg betőtípusát és a listBox háttérszínét a felhasználó meg tudja változtatni. majd futtatjuk.A MesageBox osztály Show() metódusában tudjuk elhelyezni azt az üzenetet. Használjuk a fontDialog és a colorDialog komponenseket! 2. mely a printPreviewDialog ablakot aktivizálja! 239/312 . Készítsünk programot. Ha a fenti kódrészletet egy nyomógomb eseménykezelıjében helyezzük el. amelyet meg szeretnénk jeleníteni. melyben a Form háttérszínét dialógus segítségével meg lehet változtatni! 3. Készítsünk programot. amely lehetıvé teszi.

A több szálat használó alkalmazások fejlesztésének lehetısége nem a . viszont több processzor esetén a futási idı radikálisan csökkenhet. vagy egy program több szála fut egy idıben. eszközzel kommunikál.NET” címő könyvben publikált Párhuzamos Kódokat bemutató fejezetébıl vettük az alapötletet. használja a különbözı erıforrásokat és verseng a processzoridıért.NET a szálkezelınek átadott szálakat ütemezi. A futó alkalmazásunk is egy programszál. Természetesen az egyes szálakat valamilyen algoritmus ütemezi. Elıfordulhat. A szálakat természetesen magunk is elindíthatjuk. majd ezt fejlesztettük tovább és írtuk át C# nyelvre. hogy a szálkezelı elindítsa és vezérelje a szálakat. vagy többszálú programok fogalma megtévesztı lehet. több processzoros rendszerek programozására. és a szálak külön – külön sem futnak rövidebb ideig. hogy több program. A . Amennyiben tudatosan hozunk létre többszálú programokat gondoskodni kell arról. (Az következıekben ismertetett programhoz a Microsoft által kiadott ”David S Platt: Bemutatkozik a Microsoft . nagyban segítve ezzel a programozó dolgát. és megpróbálja a számukat is optimalizálni. amikor egyszerő programokat írunk. s mialatt az egyik szál adatokra vár. A párhuzamos.NET újítása. segítségével lehetıség nyílik a processzor hatékonyabb kihasználására.Többszálú programozás A többszálú programozás viszonylag új technika. de mindenképpen jobb ezt a rendszerre bízni. s azok szeletei egymás után futnak és nem egy idıben. A . de hatékony támogatást ad azok készítéséhez. a többi szál használhatja az értékes processzoridıt. ami egymagában fut.NET rendszerben akkor is szálkezelést valósítunk meg. mert talán így tudjuk a legegyszerőbben bemutatni a több szálú 240/312 . Egy processzor esetén nem fejezik be futásukat hamarabb. Egy processzoros rendszerekben is elınyt jelenthet a többszálú programok írása. vagy éppen egy lassabb perifériával. futtatása. még a számukat is megadhatjuk.

de a processzor egy idıben csak eggyel foglalkozik.QueueUserWorkItem() metódusnak. Hozzáadjuk a soron következı elemet a listView komponenshez. A programban egy idıben több szál is fut. Az egyszerőség kedvéért a program célfüggvénye csak a szál ikonját és feliratát cserélgeti. A nyomógomb eseménykezelıjében. public String s = ”Szál”. mely feldolgozza ezeket.programokat. a FOR ciklusban példányosítjuk a Parameterek osztályt (minden szálhoz egyet): Parameterek P = new Parameterek(). } A program indulása után a Form. class Parameterek { public int i = 0.ThreadPool. hogy egy valós. A programban szerepel egy célfüggvény. a szálakat egy ImageList-ben tárolt képsorozat elemeivel szimbolizálja. párhuzamos program ezen részében adatfeldolgozás. melyben paramétereket közölünk vele. mely a szálakhoz rendelt eseményt hajtja végre.NET rendszer használatát és finomságait teljes mértékben meg akarja ismerni!) A példaprogram egy listView komponens segítségével bemutatja. majd átadjuk a célfüggvényt a System. Az említett könyv olvasása javasolt annak. és a már nem futó szálakat szimbolizálják. ezzel jelezve. hanem a . A célfüggvény mellett adhatunk a metódusnak egy tetszıleges objektumot. Induláskor közöljük a programmal a futtatni kívánt szálak számát.ra helyezett nyomógomb indítja el a szálkezelést. beállítjuk az elem ikonját és feliratát: 241/312 . aki a . A Piros ikonok az aktív szakaszt mutatják. hogyan futnak egymás mellett a szálak. vagy egyéb fontos esemény történik. a sárgák az aktív szakasz utáni alvó periódust. a kék ikonok pedig a még feldolgozásra váró. viszont cserélgeti a futó szálakat. melyben az adott elem sorszámát közöljük a célfüggvénnyel. A példában az egy mezıt tartalmazó Parameterek osztályt adunk át a paraméter listában.Threading. ami átadja ezeket a célfüggvénynek. Az egyszerre futó szálak számát nem a programozó határozza meg.NET keretrendszer az erıforrások függvényében.

Items[atadot.i]. (Az ikonokat egy imageList. vagy négy szál is futhat.Items[atadot.i=i.i].P).Thread.Thread. a feliratát pedig „Alvó szál” .Text="Alvó szál". de lassabb gépeken ezek a számok növekedhetnek.ra: listView1. A szál ismét várakozik.Threading.Sleep(1000). Végül átadjuk a példányt a célfüggvénnyel együtt a szálkezelınek. és mellettük néhány szál éppen alszik. System.Threading.Sleep(1000).ImageIndex=2.ImageIndex=0. viszont azt.Thread.i].Items[atadot. Ütemezi. A System. 242/312 . a program annyi szálat hoz létre. 3. futtatja. 2. majd az ikonja az eredetire vált: listView1. „futó” ikonra. mely gondoskodik a szál sorsáról. azután átírja az ikon feliratát: listView1.Threading. listView1. „alvó” ikonra.Items.Text="Futó szál". System. Mivel a szálak létrehozását ciklusba szerveztük. ezzel átadva az adott szál sorszámát a szálkezelınek.i]. hogy egyszerre hány szál fut. System. System.Threading. Beállítja a szál ikonját a piros.QueueUserWorkItem(CF . hogy egyszerre akár három.Add(Convert.ThreadPool. listView1.Text="Vége”). Értékül adjuk a ciklus változóját az osztály i változójának.i]. mint a ciklus lépésszáma.WaitCallback CF = new System.ImageIndex=1.Items[atadot.Items[atadot. A célfüggvény a következı dolgokat végzi el.Sleep(1000) metódussal a szálkezelı várakoztatja a szálat.2). majd leállítja azt.Threading.Items[atadot.ToString(i)+"Szál". szimulálva egy valós program-szál mőködését: 1.Threading.i]. s közvetett úton a célfüggvénynek: P.listView1. majd átállítja a szálhoz tartozó ikont a sárga.WaitCallback(CelF). a szálkezelı dönti el. A listView ablakában látszik. listView1.bıl veszi).

melynek grafikus felületén két progressBar komponens két futó programszál állapotát szimbolizálja! A Form-on egy nyomógomb segítségével lehessen elindítani a szimulációt. Növeljük a lépésszámot. Feladatok 1. Bonyolultabb alkalmazások esetén egy probléma mindenképpen felvetıdik. vagyis biztonságosan kell futniuk egymás mellett. 2. A progressBar állapota mutassa az aktuális szál feldolgozottságát! 243/312 . és a lehetséges hibákkal is. A grafikus felületnek tartalmaznia kell a következı komponenseket: listView. de csak akkor használjuk fel a lehetıségeiket. A futó szálak nem használják egy idıben ugyanazt az erıforrást.az ikonok rajzával (ezeket a Paint programmal rajzolja meg). amit szeretnénk. A rosszul megírt párhuzamos mőködéső programokkal éppen az ellenkezıjét érjük el annak. a memória foglaltságát és a programok hatékonyságát. imageList .Sajnos a többszálú programozás közel sem ilyen egyszerő. ha tisztában vagyunk a használatukban rejlı elınyökkel. Készítsen programot. és egy nyomógombot a folyamat elindításához. A jól megírt többszálú programok optimálisan használják fel az osztott erıforrásokat. A fejezetben szereplı forráskódok és azok magyarázata alapján állítsa elı a tárgyalt programot.

Programozás tankönyv XVI. Fejezet „Grafikai alapok!” Dr. Kovács Emıd 244/312 .

Mintafelismerés: Képekbıl meghatározott információk kiolvasása.A grafikus szoftver A számítógépi grafika (Computer Graphics) természetesen képekkel foglalkozik. Síkbeli és térbeli objektumok modellezése. hanem számtalan alkalmazási területe van a grafikus adatok feldolgozásának is. Computer Aided Manufactoring (CAM) Bemutató és üzleti grafika (Presentation and Business Graphics) Tudományos és mőszaki szemléltetés és szimuláció (Scientific Visualization and Simulation) Képelemzés és feldolgozás (Image analysis and processing) Grafikus kezelı felületek (Graphics User Interfaces. Grafikus képek tárolása a számítógépen és adathordozókon kódolt formában. képek elıállítása. Képfeldolgozás: képek javítása átalakítása a késıbbi feldolgozás érdekében. Feladata a grafikus adatok feldolgozása amely négy. manipulálása és rajzolása leírások alapján. hogy az alkalmazások milyen feladatcsoportot ölelnek fel és a használt módszerekben milyen összefüggések találhatók. • • • A számítógépi grafika feladatai A számítógépi grafika önmagában nem csak a képekkel foglalkozik. A csoportosításnál az volt a szempontunk. A következı felsorolásban kísérletet teszünk arra. • • • • • • • • • Mővészet és animáció (Art and Animation) Számítógéppel segített tervezés és gyártás: Computer Aided Design (CAD). nem teljesen elkülönülı fıterületet ölel fel: • Generatív grafikus adatfeldolgozás: képek és grafikus adatok bevitele. hogy a számítógépi grafika témakörébe tartozó alkalmazásokat csoportosítsuk. leírások és adtok elıállítása. GUI) Virtuális valóság (Virtual Reality) Multimédia alkalmazások (Multimedia Application) Számítógépes játékok (Computer Games) 245/312 .

Számos grafikus könyvtár létezik. amelyek egy része az operációs rendszerhez kötött. más része független.A Microsoft Paint programablakja Játékra fel! Egy komputergrafikai program a grafikus hardver szolgáltatásait grafikus könyvtárak segítségével éri el. A továbbiakban a C#-hoz kapcsolódó Ms-Windows GDI+ lehetıségeit tárgyaljuk 246/312 .

hogy a GDI+ API (Application Programming Interface) rugalmasabb és teljesebb mint a GDI. feltéve. A GDI egy program fájl. Device Context: alapvetı eszköz. A GDI+ –szemben a GDI-vel– egy jóval magasabb szintő programozást tesz lehetıvé. a programozóknak már nem kell semmit sem tudniuk a hardver eszközökrıl.NET rendszer GDI változata a GDI+. ha erre a GDI közvetlenül nem képes. GDI+ osztály és interfész a . amely valójában egy olyan belsı struktúra. Amellett. Például a Form–okhoz kapcsolódó osztályok a Windows. amely biztosítja a kapcsolatot a különbözı hardver eszközök és az alkalmazások között. Ez a struktúra megszabadítja a programozót a különbözı hardver eszközök közvetlen programozásának fáradságos munkájától. A . s az ablak alapú (Windows) alkalmazás/környezet tölti be a memóriába. A könyvünknek nem célja további részletességgel tárgyalni a GDI+ technikai leírását.Forms névtérbe ágyazták be. namespaces A Microsoft . hogy kezelje az output eszközt.Drawing. nagyon sok újdonságot is megvalósítottak benne. Az így elkészült programok például képesek futni különbözı képernyı felbontásokban.dll tartalmaz. legyen az mátrix vagy lézer nyomtató. GDI: C++ osztályok halmaza. csak a benne rejlı lehetıségek izgalmasak számunkra. A Windows betölti a szükséges eszközkezelı programot (Device Driver) is. amelyek biztosítják a grafikus adatok eljuttatását a programokból a hardverek felé a Device Driver segítségével.GDI+ A GDI (Graphics Device Interface) biztosítja az ablakos felületet használó grafikus alkalmazásoknak az eszköz független elkészítését. 247/312 . amely elvégzi a grafikus parancs konvertálását a hardver eszköz számára érhetı formába. Hasonlóan a GDI+ osztályok hat névtérbe vannak beágyazva.NET könyvtárban minden osztályt névterekben (namespasce) csoportosítottak. A GDI réteg alkalmazására tekintsük meg a következı ábrát: A GDI alkalmazása A fenti ábrán jól látható hogy a GDI egy olyan réteg. amit a számítógépen tárolunk. A GDI+ egy új fejlıdési pontja a GDI változatoknak.NET-ben Névterek. használni tudnak különbözı nyomtatókat. amelyet a Windows arra használ. amelyeket a System. Anamespace nem más mint az osztályhoz hasonló kategória. amikor egy grafikus output miatt szükség van rá.

Imaging. height).Text.Drawing Namespace biztosítja az alapvetı GDI+ funkciókat. System.Drawing névtér osztályai és struktúrái A System. • • • • • • System.Drawing. System. Bitmap. mivel tartalmazza a megjelenítı eszköz (display device) rajzoló metódusait. Font. Olyan alapvetı osztályokat tartalmaz.) A GDI+ grafikus felületének a megadása.Design.Drawing. A következı listában felsoroltunk néhány alapvetı System. A System. PointF Rectangle. típus stb. System. A Graphics osztály alapvetı fontosságú a GDI+ban. 248/312 . Osztályok és leírásuk: Bitmap. Graphics. Téglalap definiálása a bal felsı sarok koordinátáinak szélesség és magasság adatainak a left and width.Printing. Sruktúrák és leírásuk: Color Point.poligonok kitöltésekhez) A szövegek formáinak a meghatározása (méret. A toll definiálása szakaszok (lines) és görbék rajzolására. Size Szín definiálása Síkbeli pont megadása x.Drawing. FontFamily stílus.(top. Méret megadása téglalap alakú régiók esetében Grafikus képek osztályai Ecset pl. az ellipszisek. RectangleF és a megadásával. mint a Brush..Drawing. Graphics Pen (curves) SolidBrush számára. Brushes. y egész és valós koordinátákkal.Drawing osztályt és struktúrát. Pen.Drawing. System. System. A felület megadására két lehetıségünk adódik. Font stb.GDI+ Namespaces: GDI+ a Drawing névtérben és a Drawing névtér öt alterében van definiálva. Egyszinő kitöltési minta definiálása az ecset A Graphics osztály A Graphics osztály a legfontosabb a GDI+ osztályai közül. Image Brush. Ezen osztály metódusaival tudunk rajzolni a megjelenítı eszközünk felületére.Drawing2D.Drawing.

Grafikus objektum sorozat (Path) Körcikk rajzolása. Szöveg kiírása.Windows. Téglalap kontúrjának a megrajzolása.Red.Forms. 100). 1. Pen myPen = new Pen(Color. 20. Kitöltött téglalap rajzolása. Kitöltött körcikk rajzolása.PaintEventArgs pae) { Graphics myGraphics = pae.Red. 3). 30. Az OnPaint metódus paramétere PaintEventArgs típusú lesz.Windows. 300. 100). System. Szakaszrajzoló metódus. módszer: . Kitöltött ellipszis rajzolása. DrawArc DrawBezier.PaintEventArgs e) { Graphics myGraphics= e.Graphics. vagy felülírjuk a form OnPaint() metódusát. Path belsı területének a kitöltése. 20. DrawClosedCurve rajzolása. DrawPie DrawPolygon DrawRectangle DrawString FillEllipse FillPath FillPie FillPolygon FillRectangle FillRectangles FillRegion Ellipszis ív rajzolása. } A könyvünkhöz mellékelt Videó fájlok bemutatják az alábbi rajzoló metódusok használatát.Forms. 30.DrawLine(myPen. Téglalapok sorozatának kitöltése. } 2. 3). DrawEllipse DrawImage DrawLine DrawPath elıállítása. Poligon rajzolása. Pen myPen = new Pen(Color.DrawLine(myPen. Bézier-görbék rajzolása. DrawBeziers DrawCurve. 300.private void Form1_Paint(object sender. myGraphics.Vagy rajzoljuk a Form Paint eseményének segítségével.módszer: protected override void OnPaint(System. Kitöltött poligon rajzolása. Régió belsı területének a kitöltése 249/312 . Kép megjelenítése.Graphics. Nyílt és zárt interpoláló görbe Ellipszis rajzolása. myGraphics.

ForwardDiagonal).LinearGradientBrush( ClientRectangle.Drawing2D. a lépcsıhatás.Drawing2D.Drawing.Color.azaz.FillEllipse(myBrush.Forms. Például lehetıség van egy téglalap vagy ellipszis lépcsızetes kitöltésre: Gradient brush hatása Program részlet: private void Form1_Paint(object sender. Antialiasing használatával és nélküle 250/312 .300. System. lépcsızetes színátmenet.A GDI+ újdonságai Gazdagabb színkezelés és színátmenetek lehetısége Gradient Brushes. g. } Antialising támogatás A GDI+ lehetıséget biztosít a szépséghibák javítása.150).Drawing.LinearGradientMode.Color.Drawing.Drawing2D.Red.Blue. System.PaintEventArgs e) { Graphics g= e. mint pl.Graphics.10. System.Windows.LinearGradientBrush myBrush = new System. 10.

DrawEllipse(new Pen(Color. 7 pontra illeszkedı nyilt és zárt interpoláló görbék 251/312 . 150. myGraphics.Purple.Programrészlet: private void Form1_Paint(object sender.5). 120.AntiAlias. myGraphics.Default.PaintEventArgs e) { Graphics myGraphics=e. 10. myGraphics. A spline-t egy ponttömb (PointF[] myPoints ={…}) segítségével tudjuk egyértelmően meghatározni. 120. } Cardinal Spline-ok A GDI+-ban lehetıségünk van a DrawCurve és a DrawClosedCurve metódusok segítségével interpoláló Cardinal spline-ok elıállítására. A témáról részletesen leírást találunk az Interpoláció és appoximáció fejezetben.5). 80). System. A ponttömb pontjait kontrollpontoknak.Purple. az általuk meghatározott poligont kontrollpoligonnak nevezzük.SmoothingMode = SmoothingMode.DrawEllipse(new Pen(Color.Graphics. 10.SmoothingMode = SmoothingMode. 10. 80).Forms. myGraphics.Windows.

2). rugalmasan kezelhetjük. Rotate. 0. amelyek végrehajtási sorrendjét változtathatjuk. 0. 0).1).DrawImage(myMetafile.ScaleTransform(0. Metafile myMetafile = new Metafile("hilbert2.TranslateTransform(100. myGraphics. A ponttranszformációkat transzformációs mátrixokkal írhatjuk le. e.Graphics.Graphics.emf").Graphics. 0). Skálázható régiók (Scalable Regions) Elforgatott és kicsinyített input kép public void Example_Scale_Rotate(object sender.7F. Az átlátszóság mértékét a blending technikában az alfa értéke adja meg.DrawImage(myMetafile.100. Elıre definiált metódusok között válogathatunk (Translate. Shear) vagy az általános affinitás mátrixát (Matrix object) is megadhatjuk.Red. myGraphics. mintha pl. hogy különbözı képek egymás elıtt jelenjenek meg. e.50. 50).RotateTransform(30. egy objektumot ablaküvegen keresztül vagy víz alatt látnánk.0F). egymás utáni végrehajtására. így keltve olyan érzetet.7F). Ez az érték 252/312 . PaintEventArgs e) { Graphics myGraphics=e. myGraphics.Mátrix transzformációk A GDI+-ban széles lehetıségünk van síkbeli ponttranszformációk megadására. } Alpha Blending A GDI+-ban az alfa-csatorna (Alpha Channel) értékének változtatásával lehetıvé válik.0. Scale. myGraphics. A téma részletes kifejtését a Ponttranszformációk fejezetben találjuk meg.DrawEllipse(new Pen(Color.2.

0.300.Forms.Windows. myGraphics.50. myGraphics. System.100).Drawing. szinte teljesen átlátszik a kék négyzet Sokkféle grafikus fájl formátum támogatása (Support for Multiple-Image Formats): GDI+ lehetıséget ad raszteres (Image).SolidBrush myBrush3 = new SolidBrush(Color. //félig látszik át System.SolidBrush myBrush2 = new SolidBrush(Color. 255)). myGraphics. A következı formátumokat támogatja: Raszteres formátumok: • BMP Bitmap • GIF (Graphics Interchange Format) • JPEG (Joint Photographic Experts Group) • EXIF (Exchangeable Image File) 253/312 .300.Drawing.jpg").FillRectangle(myBrush3. akkor beszélünk alfa-csatornáról.50. félig látszik át.Drawing.100.Drawing.TextureBrush myBrush0 = new TextureBrush(myBitmap).PaintEventArgs e) { Graphics myGraphics= e. és két kép keverésének arányát határozza meg.0.Graphics.FillRectangle(myBrush1.100. Ha egy kép minden pixeléhez rendeltek alfa-értéket.50. 255)).100).általában 0 és 1 között van. } Nem látszik át. Tekintsünk egy példát: private void Form1_Paint(object sender.50.10. // nem látszik át System.100).FromArgb(32. 0.FillRectangle(myBrush2.155. myGraphics.50.100.150).FromArgb(128.SolidBrush myBrush1 = new SolidBrush(Color.FillEllipse( myBrush0. 255)).FromArgb(255. //Szinte teljesen átlátszik System. 0. System. 0. 0. Bitmap myBitmap = new Bitmap("navaho. bittérképes (Bitmap) és metafile-ok kezelésére.

20) pozícióból a (300. Az OnPaint metódus paramétere PaintEventArgs típusú lesz. Metafile myMetafile = new Metafile("meta_kep. A GDI+-ban csak a Graphics és a Pen objektumokra lesz szükségünk. myGraphics. 10). GDI+ és/vagy GDI rekordokkal Példa program: private void Form1_Paint(object sender. vektoros file formátumok: • WMF (Windows Metafile).emf"). 500. Vagy megrajzoljuk a vonalat a Form Paint eseményének segítségével.Windows. Két lehetıségünk van a rajzolásra.jpg"). Bitmap myBitmap = new Bitmap("image_kep.100) pozícióba vonalat rajzolunk.Graphics.DrawImage(myBitmap. hogy a (30.Forms. • EMF (Enhanced Metafile) • EMF+ Bıvített metafile. } Metafájl és raszteres kép beillesztése Néhány változás a GDI+ porgramozásban Vonal rajzolás GDI+ használatával Legyen feladatunk. myGraphics.• • PNG (Portable Network Graphics) TIFF (Tag Image File Format) Metafile-ok.PaintEventArgs e) { Graphics myGraphics = e. vagy felülírjuk a form OnPaint() metódusát. 10).DrawImage(myMetafile. System. csak megjeleníti lehet menteni nem. 10. 254/312 .

DrawLine(myPen. 20. amelynek 12 változata van (System.módszer: protected override void OnPaint(System.Windows. hogy a a DrawLine összes változatában meg kell adni a kezdı és a vég pozíciót.Windows. myGraphics. float x1. int x1.PaintEventArgs pae) { Graphics myGraphics = pae. float y1. int x2.Forms. Pen myPen = new Pen(Color. System. 300. számtalan metódus ugyanazon név alatt. 3). Most nézzük meg a két megvalósítást: 1. Pen myPen = new Pen(Color. 30. 300.Bitmap) Például a DrawLine metódus a következı négy formában: void DrawLine( Pen pen. 20. float y2) {} void DrawLine( Pen pen.PaintEventArgs e) { Graphics myGraphics= e. 255/312 . myGraphics.Red.Graphics.DrawLine(myPen. 30. } Metódusok felülbírálása (Method Overloading) Nagyon sok GDI+ metódus felülbírált. float x2. Linerel. Hasonlóan Lineto. 100). A DrawLine elsı paramétere a Pen objektum. } 2.Forms.Red. PointF pt2) {} void DrawLine( Pen pen. int y1. 100). PointF pt1.Szakasz rajzoló eljárásunk meghívja a Garphics osztály DrawLine metódusát. Moverel jellegő utasítások sincsenek.Drawing. Van olyan methodus. de különbözı paraméter listával. Point pt2) {} Többé nincs a grafikus kurzornak aktuális poziciója (Current Position) Tehát nem használhatunk moveto jellegő parancsokat. azaz. mert például az elızı részben láttuk. int y2) {} void DrawLine( Pen pen. 3). módszer: private void Form1_Paint(object sender.Graphics. Point pt1.

FromArgb(255. 0). float width = 2*a. Color. // Átalakítás a GDI+ szerint float left = x-a.0F. 255)). } Mintával kitöltött és körvonalával megrajzolt téglalapok A FillRectangle és DrawRectangle metódusoknak a GDI+ használatakor az elsı paraméter mellett még meg kell adnunk a téglalap bal felsı sarkának a koordinátáit. float height = 2*b.y-b).0F. float a = 200. 255. és tengelyei float x = 300. 50. valamint a kis és nagy tengelyével megadni: Ellipse(x. 100. HatchBrush myHatchBrush = new HatchBrush( HatchStyle. A DrawRectangle metódus a Pen objektummal. height).Cross. 3). 3).b).0F. 0).Windows. Teljesen hasonlóan járunk el az DrawEllipse és a FillEllipse metódusok használatakor is. 0. System. 30).left. width és height). 0.a. Tekintsünk egy példát: private void myFillexample(PaintEventArgs e) { Graphics myGraphics=e. Pen myPen = new Pen(Color. Pen redPen= new Pen(Color.x. e.FromArgb(255.0F. float y = 150. 256/312 . width.PaintEventArgs e) { Pen blackPen= new Pen(Color.Forms. 100. Color.Black. 30). ugyanez a GDI+ -ban: private void Form1_Paint(object sender. 50. 255. myGraphics. a FillRectangle metódus pedig a Brush objektummal használhatjuk.FromArgb(255. e. s a téglalap szélességét. 1). Más programozási nyelvek grafikus könyvtáraiban szokás az ellipszist középpontjával.y.Graphics.Graphics. 0. //Az ellipszis középpontja. 250.x.DrawEllipse(redPen. myGraphics.y. top. float b = 100. 0.DrawLine(blackPen.FillRectangle(myHatchBrush. 100.Graphics.top. és hosszúságát (left.Szétválasztott metódus a rajzolásra (Draw) és a kitöltésre (Fill) GDI+-nak különbözı metódusai vannak pl egy téglalap körvonalának megrajzolása és belsı területének a kitöltésére. float top = y-b.Red.DrawRectangle(myPen.

Drawing. A Region osztály Union és Intersect metódusaival egyesíthetünk két régiót ill.DrawString(at. e. Az utolsó három a szokásos RGB összetevık: piros (red). drawFont. ax.Graphics. vagy egyéb grafikus alakzatra van szükségünk a régiók létrehozásánál. Emellett Xor.DrawLine(blackPen.Drawing. float ax = x+a/2. majd átadnunk a Region konstruktornak. Tekintsünk egy példát: 257/312 . System. ay). e.y). Exclude és Complement metódusokat is használhatunk. bx. drawBrush.SolidBrush(System.Drawing.Graphics. s ezzel transzparenssé tehetjük ábráinkat Regiók létrehozása A GDI+-ban könnyedén formázhatunk régiókat téglalapokból (Rectangle object) és grafikus objektumok sorozatából (GraphicsPath object) Ha tehát ellipszisre vagy kerekített téglalapra.Drawing. meghatározhatjuk a régiók metszetét.Graphics. zöld (green) és a kék (blue). by). akkor ezeket az alakzatokat elıször a GraphicsPath objektum segítségével kell létrehoznunk. float ay = y-22. drawFont.Font("Arial". float by = y-b/2. //A feliratok megjelenítése string at = "a". drawBrush.SolidBrush drawBrush = new System.Color. 16). Az elsı paraméter az Alpha Blending értéke.DrawString(bt.y.x.Drawing.e. System. float bx = x. string bt = "b". // A szöveg bal felsı sarkának a pozíciója.Black). amely a rajzoló szín és a háttér szín keverésének a mértékét határozza meg.Font drawFont = new System. } Ellipszis két tengelyével A Color osztálynak négy paramétere van.x+a.

20. 110).Intersect(path). // Az ellipszis létrehozása GraphicsPath objektumként.Black). 100. path. amelynek pontjai mindkét régióhoz tartoznak (régiók metszete).AddEllipse(90. // Színezzük ki a metszetet! SolidBrush myBrush = new SolidBrush(Color.Black.Intersect(path).Union(path).Graphics. //myRegion2. Az Intersect metódus két régió esetén olyan régiót ad.Xor(path). 100). e. // Az második régió megkonstruálása.Graphics.FillRegion(myBrush.Blue). } Futási képek: Metszet: myRegion2. path). Rectangle regionRect = new Rectangle(20. // Határozzuk meg a második régió metszetét az elsıvel! myRegion2. //myRegion2.Graphics.DrawPath(new Pen(Color. e. Region myRegion2 = new Region(regionRect). regionRect). 258/312 .public void myRegionExamples(PaintEventArgs e) { // Az elsı téglalap létrehozása.Exclude(path).Union(path). //myRegion2. //myRegion2. GraphicsPath path=new GraphicsPath()..Complement(path). 100. // Az elsı régió megkonstruálása. Region myregion1=new Region(path). 30. e. myRegion2).DrawRectangle(Pens. Unió: myRegion2.

Kizáró vagy: myRegion2. amely nincs benne a második régióban (különbség képzés). amely az elsı régió minden olyan pontját tartalmazza. Az Exculde metódus két régió esetén olyan régiót ad. 259/312 . amelynek pontjai vagy az elsı vagy a második régióhoz tartoznak (régiók uniója).Az Union metódus két régió esetén olyan régiót ad. Komplementer: myRegion2. amelynek pontjai vagy az elsı vagy a második régióhoz tartoznak. Különbség: myRegion2.Exclude(path). Az Xor metódus két régió esetén olyan régiót ad.Complement(path). de nem mindkettıhöz (Kizáró vagy).Xor(path).

amely nincs benne az elsı régióban (komplementer képzés).A Complement metódus két régió esetén olyan régiót ad. amely a második régió minden olyan pontját tartalmazza. 260/312 .

Ezeket visszahelyettesítve és átrendezve kapjuk: Az egyenletben szereplı együttható polinomokat Hermite-polinomoknak nevezzük. Keresünk egy olyan harmadfokú polinommal megadott görbét amelyre teljesül. Az egyenletrendszer megoldása után polinom-együtthatókat kapjuk. mint a kontrolladatok (a p0 és p1 pont. valamint a t0 és t1 érintı vektor. valamint a t0 és t1) súlyozott összege. Adott a p0 és p1 pont. Ezek alapján az egyenletrendszer felírása és megoldása következik. ahol a felsı pont a derivált jele.Interpoláció és approximáció Ebben a fejezetben a C# . Hermit-görbe A harmadfokú Hermit-görbe kezdı és végpontjával és a kezdı és végpontban megadott érintıjével adott.NET GDI+ által nyújtott interpolációs és approximációs lehetıségek mellett a téma matematikai hátterét is megvilágítjuk. Az egységesebb szemléletmód miatt felírhatjuk a görbét mátrix alakban is: 261/312 . s ezzel lehetıséget adunk az általánosításra. és a következıképpen jelöljük: Ekkor a görbe felírható a Hermit-alappolinomok segítségével: . Az elıbbi összefüggést alapján az Hermit-görbét tekinthetjük úgy.

Bézier-görbe Keressünk olyan görbét. Ezeket késıbb kontrollpontoknak. Legyen A második egyenlet a jól ismert. azaz átmetszheti önmagát.1] ... amely a megadott pontokat közelíti (approximálja) az elıre megadott sorrendben és nem halad át (nem interpolálja) rajtuk. akkor kialakulhat hurok a görbén. n Most már elvégezhetı a szerkesztés. de Casteljau-algoritmus Adottak a sík vagy a tér b 0 ... vagy legalábbis nem mindegyeiken. b n pontjai és u ∈ [0.. Ha a végpontbeli érintıket egyre nagyobb mértékben növeljük. paraméterhez tartozó algoritmussal Bézier-görbepont szerkesztése de Casteljau- 262/312 . hiszen a szakasz osztópont meghatározása szolgál. az általuk meghatározott poligont kontrollpoligonnak nevezzük. ahol az így meghatározott b 0 (u ) pont a Béziergörbe u paraméterhez tarozó pontja lesz.

A Bézier-görbe elıállítása Bernstein-polinommal
a Bézier-görbe u paraméterhez tartozó pontja, ahol a a Bernstein polinom. Az összefüggést a binominális tétel segítségével nyerjük. Láthatjuk, hogy a Hermit-görbéhez hasonlóan a kontrolladatok, jelen esetben a kontrollpontok, súlyozott összegérıl van szó.

Bézier-görbe néhány tulajdonságai
• A Bézier-görbe a kontrollpontjai affin transzformációjával szemben invariáns. Ez következik a de Casteljau-féle elıállításból. Ezen tulajdonságot kihasználva, a görbe affin transzformációja (Pl.:eltolás, elforgatás, tükrözés, skálázás, párhuzamos vetítés) esetén elég a kontrollpontokra végrehajtani a transzformációt, mivel a transzformált pontok által meghatározott Bézier-görbe megegyezik az eredeti görbe transzformáltjával. De centrális vetítésre nézve nem invariáns. Ha u ∈[0,1] , akkor a Bezier görbe kontrollpontjainak konvex burkán belül van.

A Bézier-görbe kontrollpontjainak konvex burkán belül marad • • • A Bézier-görbe az elsı és utolsó kontrollponton áthalad. A Bézier-görbe „szimmetrikus”, azaz a ugyanazt a görbét állítják elı. Ha és a pontok

akkor a Bézier-görbe kezdı- és végérintıje:
.

Tehát a kezdı és a végpontban az érintık tartó egyenese a kontrollpoligon oldalai.

263/312

A Bézier-görbe és érintıi n = 3 esetén az érintıvektorok harmadát felmérve

A görbe globálisan változtatható, azaz, ha megváltoztatjuk egy kontrolpontjának a helyzetét, akkor az egész görbe alakváltozáson megy keresztül. Bebizonyítható a Bernstein-polinomok tulajdonsága alapján, i hogy a b i kontrollpontnak a u = paraméterértéknél van legnagyobb n hatása a görbe alakjára. Ez utóbbi tulajdonságot nevezik úgy, hogy a görbe pszeudolokálisan változtatható. Tehát a Bézier-görbe alakváltozása jól prognosztizálható. A polinominális elıállításból jól látható, hogy b 0 ,..., b n pontot, azaz n+1 pontot n-edfokú görbével approximál, azaz a kontrollpontok számának növekedésével nı a poligon fokszáma is.

Harmadfoú Bézier-görbék
n = 3 esetén a görbe Bernstein-polinom alakja:

A görbe érintıje: Ezután könnyedén megtalálhatjuk az Hermit-görbe és a Bézier-görbe közötti kapcsolatot. Ha az Hermit-görbe a p0 és p1 pontok, és a t0 és t1 érintıkkel van

264/312

meghatározva, akkor a kezdı és végpontbeli érintıknek meg kell egyezniük a Béziergörbe érintıivel, azaz egybeesnek. , továbbá a kezdı és végpontok is

Tehát az Hermit-göbével megegyezı Bézier-görbe kontrollpontjai:

A harmadfokú Beziér-görbék (s természetesen az Hermit-görbék is) változatos képet mutathatnak.

Harmadfokú Bézier-görbék Ha a harmadfokú Bézier-görbe kontrollpontjait nincsenek egy síkban, akkor a Béziergörbe térgörbe lesz, azaz nem találunk olyan síkot amelyre a görbe minden pontja illeszkedne. A három kontrollpont esetén a másodfokú Bézier-görbe már egy jól ismert síkgörbe, parabola lesz.

Kapcsolódó Bézier-görbék
Az elızı fejezetben láttuk, hogyan milyen kapcsolat van az Hermit-görbe és a Bézier-görbe között. Ha több mint két pontot szeretnénk összekötni interpoláló görbével, akkor kézenfekvı megoldás a kapcsolódó harmadfokú Bézier-görbék alkalmazása, amelyek természetesen Hermit-görbék is lehetnek. Kapcsolódó görbeívek használata igen gyakori a modellezésben. Ilyen esetekben a csatlakozásnál megadjuk a folytonosság mértékét. Ha az és b0,b1,b2,b3. A kapcsolódásnál megkövetelhetünk nulladrendő C0, elsırendő C1, illetve másodrendő C2 folytonosságot. Általánosságban azt mondhatjuk, hogy két csatlakozógörbe kapcsolódása Cn folytonos, ha az egyik görbe deriváltjai a végpontjában megegyeznek a másik görbe deriváltjaival a kezdıpontban, az n. deriváltig bezárólag. A matematikai folytonosság vagy parametrikus folytonosság mellett létezik geometriai folytonosság is. Pl. G0 megegyezik C0-lal, és G1 folytonosan kapcsolódik két görbe, ha az érintık a kapcsolódási pontban egy irányba néznek, de
265/312

és

két csatlakozó görbe amely négy négy kontrollponttal adott: a0,a1,a2,a3

a hosszuk nem feltétlenül egyezik meg, azaz egyik érintı skalárszorosa a másiknak:

A nulladrendő folytonossághoz elegendı, ha a csatlakozáskor keletkezı görbe megrajzolható anélkül, hogy a ceruzánkat felemelnénk. A mi esetünkben ez akkor teljesül, ha az elsı görbe végpontja megegyezik a második görbe kezdıpontjával, azaz: és mivel ezen görbepontok megegyeznek a megfelelı kontrollpontokkal, hiszen a Bézier-görbe a végpontokat interpolálja, ezért a3 = b0 kell, hogy teljesüljön. Az elsırendő, C1 folytonossághoz az érintıknek kell megegyezniük, azaz kell, hogy teljesüljön. Ez a kontrollpontokra az (a3 - a2) = (b1 - b0) feltételt jelenti, azaz, amellett, hogy a két szegmens kezdı- és végpontja megegyezik, az a2, a3=b0, b1 pontoknak egy egyenesre kell illeszkedniük és az a3 pontnak feleznie kell az a2b1 szakaszt. A másodrendben folytonos kapcsolódáshoz a fenti feltételeken kívül a következınek kell teljesülnie: Ez a kontrollpontokra nézve a következıt jelenti:
((a3 - a2) - (a2 - a1)) = ((b2 - b1) - (b1 - b0))

ami geometriai szempontból azt jelenti, hogy az a1a2 egyenes és a b1b2 egyenes m metszéspontjára teljesül, hogy a2 felezi az a1m szakaszt, b1 pedig felezi az mb2 szakaszt. A gyakorlatban C2 folytonosságú kapcsolat elégséges, pl. animáció esetén a mozgó kamera által készített felvétel akkor lesz valósághő, ha a második derivált is megegyezik. Gondoljunk arra, hogy az út/idı függvény második deriváltja a gyorsulást adja, tehát ha a kapcsolódási pontban megváltozik a gyorsulás, akkor szaggatott felvételt kapunk.

266/312

C0, C1 és C2 folytonosan kapcsolódó Bézier-görbék

Cardinal spline
A cardinal spline egy a kontrollpontokat interpoláló, azaz az elıre megadott pontokon adott sorrendben áthaladó görbe, tulajdonképpen elsırendben folytonosan csatlakozó harmadfokú (kubikus) Hermit-görbék sorozata. Mivel az elızı fejezetben már kimutattuk a Hermit- és a Bézier-görbe közötti kapcsolatot, ezért a cardinal spline megadhatjuk harmadfokú C1 folytonosan kapcsolódó Bézier-görbék sorozataként is. Járjunk el az utóbbi módon!

267/312

3 pontot interpoláló C1 folytonosan csatlakozó Bézier-görbék Az i. Bézier szegmens kezdı és végpontja a szomszédos a pi és pi+1 pontok. A görbe deriváltja egy közbülsı pi pontban párhuzamos pi-1 pi+1 egyenessel, azaz

Ne felejtsük el, hogy a harmadrendő Bézier-görbe négy pontjával (négy vektorral) adott, pl. négy kontrollpont, vagy ha Hermit-görbeként adjuk meg, akkor a kezdı és a vég pont, valamint a kezdı és a végpontban az érintık. Az i. Bézier szegmens kezdı és végpontja Mivel a görbe érintıje:

ezért minden kontrollpont minden szegmens esetén most már meghatározható. Az érintık meghatározásánál használhatunk egy t >= 0 tenziós értéket, amely az érintık nagyságát befolyásolja. Ha t = 0.5 akkor a Catmul-Rom spline-t, ha t = 0 akkor a kontrollpontokat összekötı poligont kapjuk meg.

268/312

Zárt görbék különbözı t értékeknél 269/312 .A t tenziós érték hatása a görbe alakjára Zárt görbe estén az érintı a kezdı és a végpontban is az általános képlettel határozható meg.

Az elıbbi képeket elıállító program részlet: private void Form1_Paint(object sender. curvePoints. PointF[] curvePoints ={ point1. } } Ahogy a fenti programrészletbıl láthattuk.5F) { float tension = i*1. PointF point3 = new PointF(430. 350.Graphics.0F).DrawClosedCurve(new Pen(Color.Forms. // Zárt görbe elıállítása: e.Graphics.DrawCurve(new Pen(myColor.0F.tension). curvePoints.0F. point4. míg a DrawBeziers pedig C0 folytonosan kapcsolódó Bézier-görbéket rajzol. i+=0. myColor=Color. 170. 7 pont esetén a DrawBeziers metódus futási eredménye 270/312 .Red.0F.0F).0F. // Pontok megadása PointF point1 = new PointF(100.0F).Windows. hogy GDI+ segítségével lehetıségünk van cardinal spline elıállítására DrawCurve metódussal. A DrawBezier négy kontroll pontra illeszt közelítı görbét. ezért szükség van egy Béziergörbét elıállító metódusra is.(int)(i*63.0F).0F) ).FromArgb((int)(i*63.0F).2). 400. // Cardinal-spline kirajzolása változó tenziós értékkel: for (float i = 0.Graphics. PointF point4 = new PointF(550.(int)(i*63. point2. }. curvePoints). 4).0F.Red.0F. 150. point3.myFill).DrawLines(redPen. hogy a cardinal spline csatlakozó Bézier-görbékbıl áll. i <= 2.tension.0F).PaintEventArgs e) { Pen redPen = new Pen(Color. PointF point2 = new PointF(250. Mivel a GDI+ kihasználja. e. // Kontrolpoligon megrajzolása: e.2). System. FillMode myFill=new FillMode(). Color myColor = new Color().

A definíció értelmezése: • • Rendezett számhármas: [x1. hogy valójában az x= x1/x3 és az y= x2/x3 megfeleltetést használtuk. mert az általunk használt ponttranszformációk esetében nem fordul elı. amely esetekben a harmadik koordináta egy lesz. Általánosan ha egy pont homogén koordinátája [x1. 4]. mint a [2. Homogén koordináták A sík pontjait olyan rendezett számhármasokkal reprezentáljuk.Pontranszformációk A GDI+ . Pl: [1. és mind a három koordináta egyszerre nem lehet nulla. 1]. y]. x3] Arányosság: az [x1. egy tetszıleges nem nulla számmal. a homogén koordinátás alak [x. A fenti mátrixegyenlet kifejtve: 271/312 . x2. ωx3]. 2] ugyanaz a pontot jelöli. ezzel az esettel nem foglakozunk.NET-ben síkbeli. M pedig a transzformációt megadó 3×3-as mátrix és|M|≠0.x3] ugyanazt a pontot jelöli. mint a [ωx1. és x3 nem nulla. ezért a visszatérésnél egyszerően elhagyjuk. ezért most már szorozhatjuk a koordinátákat. amelyek arányosság erejéig vannak meghatározva. Mivel a homogén koordináták csak arányosság erejéig vannak meghatározva. Ponttranszformációk A homogén koordináták felhasználásával most már egyszerően megadhatjuk a ponttranszformációkat általános alakját p’= p·M ahol p illetve p’ a transzformálandó pont illetve a transzformált helyvektora. x3=1 megfeleltetést használtunk. • Áttérés hagyományos Descartes koordinátákról homogén koordinátákra: Legyen egy síkbeli pont hagyományos valós koordinátája [x. ahol ω egy 0-tól különbözı valós szám. amit az egységes mátrix reprezentáció érdekében teszünk. 0] homogén koordinátájú pont nem létezik. Ebben az esetben láthatjuk. 0. -2. x2/x3. -4. akkor nincs hagyományos valós megfelelıje a pontnak. x2. A ponttranszformációk leírásánál homogén koordinátákat használunk. Tehát x1=x. kölcsönösen egyértelmő ponttranszformációkat lehet könnyedén megvalósítani. x2=y. y. ωx2.x2. Ha x3= 0 . Visszatérés homogén koordinátákról Descartes koordinátákra: A GDI+ esetében csak olyan transzformációkat fogunk használni. 1] lesz. [0. akkor az elsı két koordinátát eloszthatjuk a definícióban foglalt arányossági tulajdonság miatt a harmadik koordinátával: [x1/x3. x3].

Forms. 110).Windows. 110).Graphics. Mivel a GDI+ csak olyan esetekkel foglakozik. 60). new Point(120.NET-ben az általános affinitás mátrixának megadása: Matrix myMatrix = new Matrix(m11. Pen myPen2 = new Pen(Color.0). new Point(120.Cos(alpha). GDI+ . amikor a harmadik koordináta 1 marad. System.Cos(alpha).m12. myArray). new Point(220. //Az elforgatott téglalap megrajzolása piros tollal e.m21.PaintEventArgs e) { Pen myPen = new Pen(Color.m31.Sin(alpha).Math.m32). private void Form1_Paint(object sender.Graphics. 60). //A transzformáció végrehajtása myMatrix. 1). myArray).DrawLines(myPen2.m22.(float) -Math. // A kék téglalap a transzformáció elıtt e. // téglalap pontjai Point[] myArray = { new Point(120.Sin(alpha). new Point(220.Blue. 1)..TransformPoints(myArray).Red.TransformPoints(myArray) myMatrix által definiált ponttranszformációt a metódussal hajtjuk végre a myArray ponttömbön. // a forgatás szöge radiánban double alpha=30*System.DrawLines(myPen. Elsı példa: A következı példában a myMatrix. ezért a következı alakra egyszerősödik a helyzet: . } 272/312 . Ha elvégezzük a mátrix szorzást akkor a következı egyenletrendszerhez jutunk: A kapott egyenletrendszer az általános síkbeli affinitást írja le.0.60) }.(float) Math.(float) Math. Matrix myMatrix = new Matrix((float) Math.PI/180.

Transform metódussal végrehajtjuk a transzformációt a Graphics objektumain. 0.0f.Sin(alpha). 1.Sin(alpha).(float)Math.0f.Blue.Ponttömb transzformációja Második példa: A következı példában három myMatrix által definiált ponttranszformációk szorzatát állítjuk elı a myMatrix.(float)Math. Pen myPen2 = new Pen(Color.0f. 273/312 .0f.0f). 0.Red. double alpha=30*Math. // Mátrixok inicializálása: // Skálázás. majd a Graphics. 0.Cos(alpha). egy téglalapot érintı ellipszisen. // Eltolás. 0.PI/180. 1).Multiply metódussal. 0.0f. Matrix myMatrix1 = new Matrix(2.0f. amelynek lehetséges értékei: • • Append: az új transzformációt a régi után kell végrehajtani Prepend: az új transzformációt a régi elıtt kell végrehajtani Formális leírása a transzformációnak { Pen myPen = new Pen(Color. A Multiply metódus MatrixOrder paramétere határozza meg a mátrix szorzás sorrendjét. 1). (float)-Math.0f). Matrix myMatrix2 = new Matrix( (float)Math.Cos(alpha). // Elforgatás 30 fokkal. 0.

100). myMatrix1. Tekintsük sorban a transzformációs mátrixokat.Multiply(myMatrix2.Graphics.Transform = myMatrix1. // Matrix1 és Matrix2 összeszorzása. 1. A Graphics osztály számtalan metódust biztosít a különbözı pontranszformációk használatára. s az azoknak megfelelı Graphics vagy Drawing2D. 0. // Érintı ellipszis megrajzolása a transzformáció után: e.DrawRectangle(myPen2. 0.Graphics.Drawing2D. 50.Append). mint a transzformációk szorzása. hogy az általános affinitást megadó Matrix osztályt alkalmazzuk. 0. 0.0f. 100. 0.Graphics. MatrixOrder.//Graphics using System. 150.DrawRectangle(myPen. MatrixOrder.Multiply(myMatrix3. 0.DrawEllipse(myPen.//Matrix 274/312 . Az elsı lehetıség. // Érintı ellipszis rajzolása: e.Graphics.Drawing. 100). 0. A másik lehetıség. hiszen a transzformációs mátrixokat kell egymásután összeszorozni.0f. 0. 100.0f.0f. Ezen metódusok egymás utáni végrehajtása nem más. Az alkalmazott névterek (Namespace): using System.0f). // A szozat transzformáció végrehajtása a Graphics objektumain: e.DrawEllipse(myPen.Matrix osztálybeli metódusokat.Graphics. 100.0f. myMatrix1. 0. hogy használjuk a GDI+ transzformációs metódusait.Append). // A szorzat mátrix szorzása Matrix3-mal. 100. 100).Drawing. } Skálázott. e. 0.Matrix myMatrix3 = new Matrix(1. 100). e. eltolt és elforgatott érintı ellipszis GDI+ transzformációs metódusai GDI+ két lehetıséget biztosít a ponttranszformációk végrehajtására.

Graphics.Rotate(alfa). ezért nekünk kell elkészíteni a szükséges mátrixokat. Erre nincs metódus a GDI+-ban. Pozitív irányú forgatás a GDI+ ban. Tükrözés: Koordináta tengelyekre tükrözünk.RotateTransform(alfa).RotateAt(alfa. az óramutató járásával megegyezı irányt tekintjük pozitívnak. A forgatás mátrixa: • • • e. myMatrix. Elforgatás az origó körül alfa szöggel pozitív irányba: Az y tengely állása miatt a szokásos pozitív iránnyal ellentétesen. s nem radiánban myMatrix.dy). myMatrix.Translate(dx.Eltolás: • • Graphics. • x tengelyre való tükrözésnél minden y koordináta az ellenkezıjére változik: 275/312 .dy). //az alfát fokban kell megadni.TranslateTransform(dx.centerpont). Matrix myMatrix = new Matrix().

0. • y tengelyre való tükrözésnél minden x koordináta az ellenkezıjére változik: Matrix myMatrix = new Matrix(-1.1.0. amivel az egybevágó alakzatok egymással fedésbe hozhatóak.0).Scale(sx. azaz.0). ha 1<sx.0. ahol a csúsztatás mértéke (k) arányos a t egyenestıl való távolsággal (d). illetve 0<sy valós számokkal történı skálázás Graphics.0. ugyanis ilyen esetben van olyan síkbeli mozgás. Matrix myMatrix = new Matrix(). 276/312 .sy) Ha sx=sy akkor skálázás hasonlóság.-1.Matrix myMatrix = new Matrix(1.0.: • • kicsinyítés ha 0<sx<1 nagyítás. myMatrix. Az eltolást és az elforgatást összefoglalóan mozgásnak szokás nevezni. A nyírás a sík pontjainak a t egyenessel párhuzamos elcsúsztatása. Nyírás: Tekintsünk egy pontonként fix t egyenest.0.sy). Skálázás: Az x illetve az y tengely mentén 0<sx .ScaleTransform(sx.

hogy x vagy y tengely irányában nyírunk.Shear(k. • Nyírás az y tengely irányában: 277/312 . Az x tengely irányú ShearX=k mértékő nyírás • Nyírás az x tengely irányában: myMatrix. myMatrix. attól függıen.0).ShearY).Shear(ShearX. A Shear metódus két paramétere közül érdemes az egyiket nullának választani. különben elıre nehezen meghatározható hatást érünk el.Egy k mértékő nyírás a t pontonként fix tengellyel párhuzamosan A GDI+-ban a koordináta tengelyek mentén vett nyírásokkal foglalkozunk.

myGraphics. AddBezier. AddBeziers. myStringFormat). a Pen és a GraphPath objektumokra. 230). AddEllipse.StartFigure(). Bézier-görbe. StringFormat myStringFormat = new StringFormat(). AddPolygon. azaz. 230). Ellipszis. myGraphicsPath. Összefőzött grafikus objektumok. AddCurve. 20. 3. //Új figura kezdése myGraphicsPath. myGraphicsPath. 10). myFontFamily.Green. -60. PointF myPointF = new PointF(50. Körcikk. Poligon. Point[] myPointArray = { new Point(40. A GraphicsPath objektum lehetıséget nyújt a grafikus elemek egyetlen blokként való kezelésére. AddRectangles. Téglalap. myGraphicsPath). AddLine. 0.myMatrix. AddPie. 20. AddString.AddCurve(myPointArray).AddArc(0.1).DrawPath(new Pen(Color. 30. AddLines. myGraphicsPath.AddString("Hello!". 20). AddArc. AddPath. FontFamily myFontFamily = new FontFamily("Times New Roman"). AddClosedCurve. myPointF. AddRectangle. 24. -60.Graphics. amelynek elemeit felsoroljuk. new Point(180.Shear(0. 50). Szöveg. 30) }. 0. myGraphicsPath. } 278/312 . A koordináta rendszer transzformálása és a Path használata A GDI+-ban lehetıségünk van grafikus objektumok összefőzésére. Ellipszis ív. A Garphics osztály DrawPath metódusának hívásával rajzolhatjuk meg a GarphicsPath szekvenciát. GraphicsPath myGraphicsPath = new GraphicsPath(). Tehát a path megrajzolásához szükségünk van a Graphics. Cardinal spline.k). path létrehozására. Lássunk egy példát: { Graphics myGraphics= e. 30. new Point(50. a felfőzéshez szükséges metódusokkal: • • • • • • • • • • Szakasz.AddPie(190.

Gray).Graphics.BeginContainer().RotateTransform(45.100) pontba kerül myGraphics. SolidBrush myBrush=new SolidBrush(Color. A GDI+ a konténerek használatával lehetıvé teszi. // Forgatás -30 fokkal a konténeren belül myGraphicsContainer = myGraphics. myGraphics. 0. DrawHello(myGraphics). // új origónk a (100.RotateTransform(-30). } 279/312 . MatrixOrder. myGraphics. hogy átmenetileg megváltoztassuk egy grafikus objektum állapotát.Nem szükséges. // Hello!-t újból kiírjuk. myGraphics. A következı példában különbözı helyekre tesszük ki a téglalapba írt szöveget. // Forgatás 45 fokkal és skálázás a konténeren belül myGraphicsContainer = myGraphics. Figyeljük meg a vonatkoztatási pont. A BeginContainer és az EndContainer metódusok között bármilyen változtatást hajtunk végre a grafikus objektumon. DrawHello(myGraphics). myGraphics. myGraphics.BeginContainer(). de elıszır eltoljuk x irányba myGraphics.DrawString( "Hello!". myStringFormat). private void DrawHello(Graphics myGraphics) { GraphicsContainer myContainer.TranslateTransform(100. myBrush.50).Append).EndContainer(myGraphicsContainer).EndContainer(myContainer). de elıszır tovább toljuk x irányba myGraphics.BeginContainer(). myGraphics. Font myFont = new Font("Times New Roman".EndContainer(myGraphicsContainer). // Hello!-t újból kiírjuk.DrawRectangle(myPen. MatrixOrder.Append). DrawHello(myGraphics). } private void myExampleContainers(PaintEventArgs e) { Graphics myGraphics= e. az nem befolyásolja az objektum konténeren kívüli állapotát. // Hello! kiiratása az új origóba. 0. Pen myPen= new Pen(myBrush.5f). myFont.Append).100.0. DrawHello(myGraphics).TranslateTransform(100.0. myGraphics. myContainer = myGraphics. az origó eltolását.TranslateTransform(100. hogy a Path objektumai össze legyenek kötve Grafikus konténerek Garfikus állapotot a Garphics objektumban tároljuk. MatrixOrder. myGraphics. 100).2).26). 1.ScaleTransform(2. StringFormat myStringFormat = new StringFormat().0. GraphicsContainer myGraphicsContainer. 0.

Példa a konténerek használatára 280/312 .

NET Radványi Tibor 281/312 . Fejezet „Adatok kezelése!” Az ADO.Programozás tankönyv XVII.

a szerver már nem fog látszani a Felügyeleti Eszközökben. Batch-eket. Amelyik gépen Windows 2000 fut. • Egyedi szervereket is bejegyezhetünk egy csoportba. Az SQL Server Enterprise Manager elindításához válasszuk ki az Enterprise Manager ikont a Microsoft SQL Server programcsoportban. • Szerkeszthetünk és tesztelhetünk SQL utasításokat.NET Adatkezelés C#-ban SQL Server Enterprise Manager Az SQL Server és az MMC SQL Server Enterprise Manager a fı adminisztrációs eszköz a Microsoft® SQL Server™ 2000-hez. Megjegyzés Ha bejegyzünk egy új SQL szervert a Felügyeleti Eszközökben. azáltal az MMC felhasználók egy felhasználói felület segítségével menedzselhetik a server alkalmazást. melyet az MMC használ. mely egy általános felületet biztosít különbözı szerver alkalmazások menedzselésére egy Microsoft Windows® hálózatban. ott ugyanúgy indíthatjuk az SQL Server Enterprise Managert a Felügyeleti Eszközökben a Vezérlıpultban. hogy: • Meghatározhatunk szervercsoportokat a futó SQL Serveren. és biztosítja az Microsoft Management Console (MMC)–t. • Az összes bejegyzett SQL server konfigurálása. login-okat. • Meghatározhatunk és elvégezhetünk minden SQL Server adminisztrációs feladatot minden bejegyzett szerveren. • Létrehozhatunk és adminisztrálhatunk minden SQL Server adatbázisokat. • Segíségül hívhatjuk a sok elıre elkészített varázslót az SQL Serverhez. Ez az opció csak az SQL Server Enterprise Manager hasunálatához kell. Az MMC beillesztések is a Felügyeleti Eszközökbıl indíthatók. és utána vagy bezérjuk a Felügyeleti Eszközöket. és szkripteket interaktívan az SQL Query Analyzer segítségével. egy jól használható felhasználi felületet. mely a felhasználó számára lehetıvé teszi.. vagy egy másik számítógéphe csatakozunk. objektumokat.Az ADO. felhasználókat és engedélyezéseket minden bejegyzett szerverre. Server alkalmazások létrehoznak egy komponenst. A bejegyzett szerver a SQL Server Enterprise Managerben fog látszódni 282/312 . Ehhez nem kell alapbeállításként engedélyeznünk gyerekablak nyitásának lehetıségét. MMC egy olyan eszköz. SQL Server Enterprise Manager a Microsoft SQL Server 2000 MMC komponense.

Az egyes szervereket lenyitva kapjuk meg azok beállítási. azok tipusait. az elénk táruló kép hasonló más adatbázis menedzselı programokhoz.Új elemek létrehozása Feltelepítés után. létrejön az adatbázis struktúra is. Bezáráskor menhetjük a táblát és adhatunk neki nevet. Az egyes elemekre jobb gombot nyomva kapjuk meg azt a pop-up ablakot melybıl kiválaszthatjuk az új alelem létrehozását vagy tulajdonságainak beállítását. A Databases/New DataBase-re kattntva létrehozhatunk egy új adatbázist. láthatjuk a szervercsoportjainkat. hogy egy mezı egyedi legyen-e. Megadhatjuk. már létezı táblákat akarjuk szerkeszteni. lehetıségeit. és kiválaszthatjuk az adattárolás könyvtárát is illetve a merevlemez szabad és adatméret kezelésének módját is. azon belül a hozzáadott szervereinket. Mikor létrehoztuk az adatbázist. hogy az adatbázis szerver hova mentse a napló fájlokat. Megadjuk a mezıneveket. alapértelmezett értéket. Ezeknek a méretét maximálhatjuk. mely tartalmazza Táblákat. ha elindítjuk az Enterprise Managert. Ha a listában lévı. Ezeken kívül megadhatunk még az egyes mezıkrıl leírást. Felhasználókat. illetve jellemzıinek leírását. A kulcsok kiválasztásánál az adott mezın jobb gombot kell nyomnunk és ott a Set Primary Key opcióval elsıdleges kulcsnak választjuk az elemet. Formulát és karakterkészletet. A tábla létrehozása úgy történik mint minden hasonló rendszerben. 283/312 . akkor azt az adott táblán jobb gombot nyomba a Design Table menüpontban tehetjük meg. Tárolt eljárásokat. Itt meg kell adnunk annak nevét. Itt találhatók az adatbázisok is. Megadhatjuk. Nézeteket. A bal oldali panel treeview-ját ha lenyitjuk. hoszukat és hogy engedélyezzük-e a NULL értéket.

A megjelenı tábláknál. hogy akár csak a kulcsokat lássuk. Például. hogy a kapcsolódó táblákatt automatikusan a listába rakja-e. akkor megjelenik a kapcsolatokat létrehozó form kitöltve a megfelelı adatokkal. 284/312 . Beállíthatjuk. ha a már Access-ben megszokott egyik elemtıl a másikig húzzuk lenyomva az egeret. Ez arra szolgál. Ezt az eszköztáron található Manage Relationshipel tehetjük meg. a sok és sokelemő tábláknál nyújthat nagy segítséget a tervezésben. illetve megjelenítésére. Az adatbázis elemei között található a Diagram is.Kapcsolatokat ugyanolyan tipusú mezık közt hozhatunk létre. A táblán jobb hombra kattintva sok beállítási lehetıséget kapunk annak szerkesztésére. vagy csak a tábla neveit. A kapcsolatot jelzı összekötı szakaszt is tesreszabhatjuk. Amikor ebbıl újat hozunk létre egy varázsló segít összeállítani a megjelenítendı táblákat. feliratozhatjuk. Ez a nagyobb projecteknél. hogy látbányosan szerkeszthessük a tábláinkat és a köztük lévı kapcsolatot.

- Columns: Itt az egyes mezıket szabhatjuk testre. Az említett beállításokon kívül még be lehet állítani. egyedi mezıje és a tábla leírása. Majdnem minden olyan beállítást elvégezhetünk mint amit a Design table alatt. A table name mellé kattintva kapunk egy ComboBox-ot melybıl kiválaszthatjuk. Itt a táblák teljes testreszabását elvégezhetjük . - Relation: A kapcsolatok. 285/312 .A elsı fül a Table: Itt az egyes táblák általános beállításai végezhetjük el. hogy melyik táblát akarjuk módosítani.Nézzük meg jobbazt azt a formot. hogy hogyan módosuljon a gyerek tábla törléskor és módosításkor. A Column name-el pedig az adott mezıt választhatjuk ki. ahol a kapcsolatokat állítottuk be. tulajdonosa. Mint például a tábla neve.

286/312 .

287/312 .- Indexes/Keys: Itt hozhatunk létre új indexeket és a létezıket testre szabhatjuk. hogy növekvı vagy csökkenı indexet szeretnénk hozzárendelni. A kiválsztott mezdı mellett meg kell adnunk.

mely kapcsolatot kezeli bármely adattárolóhoz. Connection String Minden kapcsolódási objektum nagyjából ugyanazon tagokkal rendelkeznek. mely egy string-bıl áll. Egy connection string-ben szerepelhet e helyett egy felhasználónév és jelszó. mely kezeli az SQL Server-hez a kapcsolatot. A Close metódus lebontja a kapcsolatot.0 vagy újabb verzióhoz való használatra. Az Open metódus a ConnectionString-ben lévı információt használja az adatforrás eléréséhez és egy kapcsolat kiépítéséhez. mely OLE DB-n keresztül elérhetı. hogy a kapcsolat a Windows beépített védelmét használja (NT hitelesítés). Optimizálva van SQL Server 7. Bevezetés az ADO.NET használata. mely kapcsolatot kezel egy adatforráshoz. Kapcsolat létrehozása és megszüntetése Két elsıdleges metódus van kapcsolatokhoz: Open és Close. OdbcConnection – egy objektum. Data Source=MySQLServer. Integrated Security=SSPI” Ez a connetion string részlet megadja. A kapcsolat 288/312 . az OLE DB réteget megkerülve. ezért nem biztonságos. ez az információ szükséges egy adatbázisba bejelentkezéshez. OracleConnection – egy objektum. mert ezek az értékek a programban lesznek eltárolva (fordításkor). melyet vagy kapcsolat stringgel (connection string) vagy ODBC adatforrás névvel hoztak létre.1.NET kapcsolódási eszközeihez Egy alkalmazás és egy adatbázis közti adatcseréhez elıször egy kapcsolat kell az adatbázishoz. OleDbConnection – egy objektum. Egy tipikus ConnectionString hasonlóképpen néz ki: ”Provider=SQLOLEDB. ADO. mely Oracle adatbázisokkal való kapcsolatot kezeli. Initial Catalog=NORTHWIND. de nem javasolt.NET-ben kapcsolódásokat létrehozni és kezelni kapcsolódási objektumokkal lehet: SQLConnection – egy objektum. SQLConnection osztály a formon dinamikusan. és kevés programozással. Az elsıdleges tulajdonság egy kapcsolat-objektumnak a ConnectionString. A string-ben mezı--érték párokat találunk.MS SQL szerver elérése C#-ból Az ADO. és egy meghatározott adatbázis eléréséhez.

összeadja (pool) a kapcsolatot az adatforráshoz. saját kező kiépítésére és bontására. melyek engedik végrehajtani vagy visszavonni a tranzakciót. Ehelyett használhatunk egy kapcsolatot. ha több adatillesztınk osztozik egy kapcsolaton. ASP. minden illesztıhöz meghívhatjuk a Fill metódust.bontása lényeges. Például. hogy ugyanazt az adatot kapják. Ez lehetıséget nyújt adatparancsok flexibilis. Tranzakciók A kapcsolat objektumok támogatják a tranzakciókat. és a kiépített kapcsolatok értékes erıforrásokat foglalnak. Ezt használhatjuk. ha minden adatillesztı külön épít ki és bont kapcsolatot. Ebben az esetben nem hatékony. a metódus ellenırzi. A kapcsolat beállításait ezért gyakran dinamikus tulajdonságként kezeljük. stb. az adatillesztı Fill vagy Update metódusa). nem kell állandóan magunknak kiépíteni és bontani a kapcsolatot. majd végezetül bonthatjuk a kapcsolatot.NET Web alkalmazásokban sok felhasználó kérdezhet le ugyanattól az adatbázistól. SqlConnection osztály használatakor a kapcsolatok megosztása automatikusan kezelve van. de nem bontják le. A felhasználónak ilyenkor valamilyen módot kell nyújtani (Windows 289/312 . Ha van kiépített kapcsolat. Beállítható kapcsolat tulajdonságok A legtöbb alkalmazásban a kapcsolat információi nem határozhatók meg tervezési idıben. az illesztı kiépíti a kapcsolatot. Ezekben az esetekben az alkalmazások teljesítménye növelhetı. majd bontja a kapcsolatot. nem adhatjuk meg a kapcsolatra vonatkozó adatokat tervezéskor – mint a szerver neve. de rendelkezésre állnak lehetıségek. végrehajtja a feladatát. A metódusok – mint a Fill – csak akkor építik ki és bontják a kapcsolatot automatikusan. a metódusok felhasználják. Ha nincs. mivel a legtöbb adatforrás csak korlátozott számú kiépített kapcsolatot enged. Mivel a dinamikus tulajdonságok egy konfigurációs fájlban tárolódnak (és nem fordítódnak az alkalmazás bináris fájljaiba). hogy a megosztást magunk kezeljük. Tipikus módszer a kapcsolat tulajdonságainak dinamikus adatokként való létrehozása. hogy a kapcsolat már ki van-e építve. akik azonos típusú adatbázis elérést végeznek. melyet több vásárló is használni fog. ha meghívja a Fill metódusát. Például egy olyan alkalmazásban. A tranzakciókat kódban kezeljük. egy SqlTransaction objektum). Ha adatillesztıkkel vagy adatparancsokkal dolgozunk. ha még nincs kiépítve. ha az alkalmazás megosztja. tetszılegesen változtathatóak. a BeginTransaction metódussal egy tranzakció-objektum jön létre (pl. Ha a fenti objektumok egy metódusát hívjuk meg (pl. Összetett kapcsolatok (Pooling Connections) Az alkalmazásoknak gyakran vannak különbözı felhasználói. A tranzakció objektum pedig rendelkezik metódusokkal.

Integrated Security=SSPI. A Data Provider for SQL Server hasonló formátumú kapcsolat stringet támogat. az eszközök kérni fogják a kapcsolat adatait (azaz a connection string információkat) és automatikusan létrehoznak kapcsolat objektumokat a Form-on vagy komponensen. amit az alkalmazáshoz adunk. A . és beállíthatjuk azok tulajdonságait.Open(). Mindamellett. Ez hasznos. Ezért miután már létrehoztunk egy kapcsolatot tervezéskor. mindig látható lesz a Visual Studioban (mindaddig. hogy a fontos adatokat meghatározza. melyre a kapcsolat mutat). hogy adatforrásokhoz kapcsolatot létrehozzunk. hogyan építhetünk ki kapcsolatot egy SQL Server adatbázishoz: SqlConnection kapcsolat = new SqlConnection(”Data Source=localhost. majd frissítse a konfigurációs fájlt. mint a Data Adapter varázsló. hogy tulajdonságokat állítsunk be egy új kapcsolat objektumhoz. megjeleníthetünk információkat a táblákról. és frissíti a fájlt.NET Framework beépített Data Provider for SQL Server (adatszolgáltató SQL szerverhez) SqlConnection objektummal elérést nyújt Microsoft SQL Server 7. ha akarjuk. Általában.0 vagy újabb változatához. Az alábbi kód szemlélteti.NET használatával A . ha nem adatillesztıkkel dolgozunk. amikor a tulajdonság kiolvasódik. oszlopokról. Ha olyan eszközöket használunk. a tervezés közben létrehozott kapcsolat információit arra használjuk. Létrehozhatunk kapcsolat objektumokat. függetlenül egy meghatározott projekttıl vagy Solution-tıl. hanem csak adatokat olvasunk ki. magunk is hozzáadhatunk kapcsolat objektumokat a Formhoz vagy komponenshez. ha tranzakciókat akarunk használni. Initial Catalog=adattabla”). az meg fog jelenni a Server Explorer ablakban amikor egy alkalmazáson dolgozunk. mint az OLE DB (ADO) kapcsolat string formátuma. A tervezési idıbe létrehozott kapcsolatokról az információkat a saját gépünkön tároljuk. létrehozhatunk és szerkeszthetünk adatbázis elemeket. amiket tartalmaz.Form vagy Web Form). és egyéb elemekrıl. amíg a szerver elérhetı. Kapcsolat tervezési eszközök Visual Studio-ban Általában nincs szükség közvetlenül létrehozni és kezelni kapcsolat objektumokat Visual Studio-ban. 290/312 . Kapcsolatok tervezéskor a Server Explorer-ben A Server Explorer lehetıséget ad tervezéskor. Kapcsolat létrehozása SQL Server-hez ADO.NET Framework-be épített dinamikus tulajdonság szerkezet automatikusan megkapja az értékeket a konfigurációs fájlból. Az alkalmazásunk nem közvetlenül használja az ez úton létrehozott kapcsolatokat. ha az érték változik. kapcsolat. amin dolgozunk. Tallózhatunk a meglévı adatforrások között.

stb. Átnevezhetjük a kapcsolat objektumot a Name tulajdonság változtatásával. 2. 3. • Húzzunk egy táblát. Külön tulajdonságait állíthatjuk (DataSource. Ezen elemek Formra áthúzásakor létrejön egy adatillesztı és egy kapcsolat is.). Kapcsolat létrehozása 1. 7. Ez a megoldás akkor hasznos. nem juthatnak osztott kapcsolathoz. 4. vagy ha egyszerően a tulajdonságokat magunk szeretnénk beállítani a Properties ablakban. Database. Ha külön állítjuk a tulajdonságokat. • Hozzunk létre egy különálló kapcsolatot. Lehetıségeink: Az alábbi eszközökbıl használhatjuk valamelyiket. a kapcsolat string létrejön automatikusan. UserName. • Hozzunk létre kapcsolatot kóddal. ADO. Ehhez a kapcsolat objektumnak vagy a Close vagy a Dispose metódusát kell meghívni. Vagy 5. Ez a lehetıség létrehoz egy kapcsolat objektumot a Form-on vagy komponensen. kijelölt oszlopokat vagy tárolt eljárást a Form-ra a Server Explorer-bıl. Azok a kapcsolatok. meg kell határozni a kapcsolat tulajdonságait. mely a feladata részeként kapcsolat objektumot hoz létre: • Data Adapter Configuration Wizard – ez a varázsló információkat kér a kapcsolatról. általában nem szükséges magunknak létrehoznunk a kapcsolat objektumokat a Form-on vagy komponensen. az alkalmazás újrafordítása nélkül. Válasszuk ki a kapcsolatot a tervezıben és használjuk a Properties ablakot a connection string beállításához. mely egy adatillesztıhöz lesz kapcsolva. • Data Form Wizard – a varázsló kapcsolat objektumot hoz létre a Form részeként. melyeket nem zárunk be saját kezőleg. ha befejeztük a használatát. ha a kapcsolat tulajdonságait futási idıben szándékozzuk beállítani.Kapcsolat bontása Javasolt mindig a kapcsolat bontása. Beállíthatjuk a ConnectionString-et egy egységként. melynek a tulajdonságait magunknak kell beállítanunk. 6. Azonban néhány esetben alkalmasnak találhatjuk egy kapcsolat saját létrehozását. 291/312 .NET kapcsolat objektumok létrehozása Ha adatelérés tervezı eszközöket használunk Visual Studio-ban. Ha futási idıben szeretnénk a tulajdonságokat beállítani. melyet konfigurál. A Toolbox ablak Data csoportjából húzzunk egy kapcsolat objektumot a Form-ra vagy komponensre.

Kattintsunk az OK gombra. Válasszuk ki az elérni kívánt adatbázist a lenyíló listából. A Server Explorer-ben kattintsunk jobb egérgombbal a Data Connections-re. Válasszunk ki egy meglévı kapcsolatot a lenyíló listából vagy kattintsunk a New Connection-re. 3. 6. Egy SqlConnection objektum jelenik meg a komponens-tálcán. A kapcsolat kiépítése után az adatbázist kezelı eljárásokat kell létrehozni.Kapcsolat létrehozása SQL Server-hez Ha SQL Server-hez kapcsolódunk. Egy SqlConnection objektum jeleni meg a komponens-tálcán. és állítsuk be a kapcsolatot. ahol az elérni kívánt adatbázis található. Kapcsolódás SQL Server-hez az alkalmazásunkból Kapcsolódás létrehozása vizuális eszközökkel A kapcsolódási eszközöket vagy a Server Explorer-bıl vagy a Toolbox ablak Data csoportjából használva hozzunk létre kapcsolatot: Server Explorer-bıl Hozzunk létre egy Data Connection-t a Server Explorer-ben az SQL Server-hez a fentebb leírt módon. SQL Server kapcsolat Server Explorer-ben Egyszerően hozhatunk létre SqlConnection. vagy adjunk meg felhasználónevet és jelszót a bejelentkezéshez. Húzzuk a létrehozott kapcsolatot a Form-ra. és válasszuk az Add Connection menüpontot. mely nincs beállítva. tervezési eszközökkel hozzunk létre kapcsolatot. 2. SqlDataAdapter és SqlCommand objektumokat úgy. 4. vagy gépeljük be a szerver helyét. Toolbox-ból Húzzunk egy SqlConnection objektumot a Form-ra. Válasszuk ki egy szerver nevét a lenyíló listából. Két módon kapcsolódhatunk szerverhez: • Vizuálisan. 5. használjuk a Microsoft OLE DB Provider for SQL Server eszközt. hogy a Server Explorerbıl a Formra húzzuk ıket. Megjelenik a Data Link Properties párbeszédablak. Az alkalmazásunk vagy az adatbázisunk szükségleteihez mérten válasszuk ki vagy a Windows NT Integrated Security-t. 292/312 . Az alapértelmezett elérés a Microsoft OLE DB Provider for SQL Server. • Programkóddal hozzunk létre a kapcsolatot. A Properties ablakban válasszuk ki a ConnectionString property-t. Kapcsolat létrehozása: 1.

2. typeof(int) ).1998’ AND OrderDate <= ’31.NET két megközelítést támogat erre a mőveletre: 1. A megoldás kulcsa a DataTable osztályban rejlik.Add( "name". vagy akár programból generáljunk adatokat.03. hogy lehet a memóriában. // Tíz sor hozzáadása a táblához for( int id=1. Lehetıségünk van arra is. Az ADO. A DataTable Select metódusának használatát.PrimaryKey = new DataColumn[] {CustomerTable. hogy egy tetszıleges adatforrást használjunk.Add( "id". Ami a DESC (csökkenı) vagy az ASC (növekvı) szavakkal határozható meg. A DataView objektum filter. Ez az objektum hozzákapcsolható az adatmegjelenítésre képes objektumokhoz.Add( 293/312 . find és sort metódusai. Szőrés és rendezés az ADO. typeof(string) ). illetve rendezni. id<=10. Ez a metódus szőrt és rendezett adatsorok tömbjével tér vissza.Columns[ "id" ]. mintha egy tetszıleges típusú adatbázis egy-egy táblája lenne. mint a programból generált adatainkhoz.A DataTable osztály Adatokat nem csak úgy kezelhetünk egy DataGrid-ben. „OrderDate DESC” A következı kód egy példa a DataTable Select metódusának használatára: private static void GetRowsByFilter() { DataTable customerTable = new DataTable( "Customers" ). customerTable. customerTable.Columns. id++ ) { customerTable.1998’” A tipikus rendezési kifejezés: a mezı neve és a rendezés iránya. customerTable. customerTable. Ezt az osztályt használhatjuk valós adattáblák kezeléséhez épp úgy. hogy azok valóságos adatbázishoz kapcsolódnak. melyeket ezek után épp úgy kezelhetünk.NET-ben Vizsgáljuk meg. Nézzünk egy példát a szőrıfeltétel felépítésére: „OrderDate >= ’01.Rows.Columns.03. DataSetben tárolt adatokat tovább szőrni.Columns["id"] }.Unique = true.

return. "filtered rows" ). label ).Table. string. if( rows.Add( new object[] { id. string strSort. PrintRows( foundRows. } customerTable. // Újabb tíz sor hozzáadása for( int id=11. id<=20.Select().Select( strExpr. id) } ). string label ) { Console. } 294/312 .new object[] { id.WriteLine( "no rows found" ).Format("customer{0}". id) } ).Columns ) { Console.Format("customer{0}".Added ).Length <= 0 ) { Console. strSort = "name DESC". "all rows" ). strSort. DataRow[] foundRows = customerTable. DataViewRowState. } string strExpr. } foreach( DataRow r in rows ) { foreach( DataColumn c in r.Write( "\t {0}". strExpr = "id > 5".WriteLine( "\n{0}". // Csökkenı sorrend a CompanyName nevő mezıben.AcceptChanges(). foundRows = customerTable. } private static void PrintRows( DataRow[] rows. r[c] ).Rows. PrintRows( foundRows. id++ ) { customerTable. string.

Ezt a lehetıséget sokszor használjuk ki adatbázishoz kapcsolódó programoknál. hanem egy dinamikus táblában. Ez abban különbözik a DataTable Select metódusától.NETben 295/312 . hogy a DataTable-ban tárot adatokhoz különbözı nézeteket hozzunk létre. hogy az eredmény sorokat nem egy tömbben adja vissza.Console. hogy a szőrés eredményeként kapott adatsorokat egy tömbben adja vissza.WriteLine(). } } Az alapvetı probléma a DataTable Select metódusával. Ez a képessége a DataView objektumot ideális eszközzé teszi az adatkapcsolatokat kezelı programok számára. A DataView objektum helye az ADO. Erre a DataView használata ad lehetıséget. Ez nem köthetı sem a DataGridhez sem más adatmegjelenítésre alkalmas objektumhoz közvetlenül. A DataView használatával a táblabeli adatokat különbözı rendezési szempont szerint. Szőrés és rendezés a DataView objektum segítségével A DataView objektum lehetıvé teszi. illetve a sorok állapota . vagy kifejezések álltal meghatározott szőrık szerint mutathatjuk meg.

„ LastName = ’Smith’ ” Rendezés a DataViewban A rendezéshez létre kell hoznunk egy string kifejezést.RowFilter tuljdonsága adhatunk meg egy szőrı feltételt a sorok megjelenítéséhez a DataViewban. „Price DESC. A szőrıkifejezés felépítése: egy oszlopnév.DefaultView tulajdonság a DataView objektumot kapcsolja DatatTable-hoz. Title ASC” Egy táblához több nézet 296/312 . hogy mely oszlopok szerint szeretnénk rendezni a sorokat. Így itt is használható a rendezés.Az alapértelmezett nézet A DataTable. szőrés és keresés a táblában. melyben megadhatjuk. és milyen irányban. a A RowFilter tulajdonság A DataView. operátor és egy érték a szőréshez.

Forms.WriteLine().Data. using System. using System. 297/312 .Windows.uid=sa. using System.Nézzünk egy példát erre: using System. using System.Show(ex. using System.DataView { public class FilterOrder : System.. // Initializing cn = new SqlConnection(" server=xeon..Drawing. ds = new DataSet(). using System..pwd=manager").Forms.ToString()).cn).Data. private SqlConnection cn.Windows. private SqlDataAdapter da. cmd = new SqlCommand("SELECT * FROM orders". Console.ComponentModel. // Kezdı adatok betöltése RetrieveData().Collections.SqlClient. namespace Akadia. da = new SqlDataAdapter(cmd).Form { . public FilterOrder() { try { InitializeComponent().database=northwind. } catch (Exception ex) { MessageBox.Diagnostics. private SqlCommand cmd. private DataSet ds. using System.

Add(dc.Caption). MessageBox.Tables[0]. } } catch (Exception ex) { MessageBox.} } // Orders Tábla adatai private void RetrieveData() { try { da. } } // Combobox feltöltése a mezınevekkel private void FillSortCriteria() { try { if (cmbSortArg.ToString()).ToString()).Items."Orders").Caption).Fill(ds.Add(dc. } foreach (DataColumn dc in ds.Items. cmbFields. } // Sort Combobox // Filter on Column Combobox 298/312 .WriteLine(). DataGrid.Show(ex. Console. // Combobox feltöltése a mezınevekkel FillSortCriteria().Tables[0].ToString()).Items. } catch (Exception ex) { Debug.Count > 0) { return.Columns) { cmbSortArg.DataSource = ds.WriteLine(ex.Show(ex.

Tables[0]. // Kiolvassuk a rekordszámot a DataViewban if (ds. Console.DefaultView.Clear(). } } private void btnQuery_Click(object sender.Show(ex.DataSource = ds.Tables[0]. 299/312 . // Clear Filter ds.RowFilter = "".Tables[0].ToString()).EventArgs e) { try { // Clear DataSet ds.DefaultView.} // Setup Szőrıfeltétel beállítása private void SetFilter(string strFilterExpression) { try { ds. } else { MessageBox.WriteLine(). } } catch (Exception ex) { MessageBox.DefaultView.WriteLine().ToString()). } catch (Exception ex) { MessageBox. Console.Show("Filter criteria does not meet criteria").Count > 0) { DataGrid.DefaultView.RowFilter = strFilterExpression.Tables[0].Show(ex. // Re-Retrieve Data RetrieveData(). System.

DefaultView..Text + " ASC". // IF Radiobox "Ascending" is checked. DataGrid.Show(ex.Text + "'").WriteLine(). then // sort ascending .Tables[0].EventArgs e) { try { string strSort.Sort = strSort.. } // .. if (rbAsc. } } private void btnFilterTitle_Click(object sender. } // Érvényesítjük a rendezést ds. System. else descending else { strSort = cmbSortArg.} } // Beállítjuk a DataViewban a rendezést private void btnSort_Click(object sender. System.DataSource = ds.Text + " DESC". Console.DefaultView.Tables[0]. } catch (Exception ex) // Note space after " // Note space after " 300/312 . } catch (Exception ex) { MessageBox.ToString()).Checked) { strSort = cmbSortArg.EventArgs e) { try { SetFilter("CustomerID like '" + txtFilter..

.ToString()).{ MessageBox. } } } 301/312 .Show(ex.WriteLine().ToString()).Show(ex. } } private void btnGeneralFilter_Click(object sender.. } } .WriteLine(). System. System.Text + " " + txtFilterColumn. } catch (Exception ex) { MessageBox. Console.EventArgs e) { try { SetFilter(cmbFields.ToString()). } catch (Exception ex) { MessageBox.WriteLine(). Console.Text). Console.Run(new FilterOrder()).EventArgs e) { try { SetFilter(txtGeneralFilter. [STAThread] static void Main() { Application.Show(ex. } } private void btnFilteronColumn_Click(object sender.Text).

4E+38 és 3.79E+308 és 1.3648 és 214748.Tárolt eljárások Tárolt eljárások futtatása. új tárolt eljárások készítése. Mi is az a Transact-SQL? A Transact-SQL a Microsoft SQL megvalósítása. ciklusok. Alapvetı programozási szerkezetek: • • • • • • • • • • • Változók használata Feltételes szerkezetek használata Case utasítások használata While ciklusok használata Continue utasítás Break utasítás Return utasítások használata Waitfor utasítások használata Kurzozok használata Függvények használata Felhasználói függvények létrehozása Változók A következı típusokat használhatjuk: Típus Leírás Bigint Egész érték –263 és 263 –1 közötti tartományban Int Egész érték –231 és 231 –1 közötti tartományban Smallint Egész érték –215 és 215 –1 közötti tartományban Tinyint 0 és 255 közötti egész érték Bit 1 vagy 0 étrékő egész Decimal Rögzített pontosságú és mérető számérték –1038 +1 – tıl 1038 –1 –ig Numeric Ugyanaz. A T-SQL segítségével. rögzítése adatbázisban. mint a decimal Money Pénzérték a –263 és 263 –1 közötti tartományban a pénzegység egy tízezrelékének pontosságával Smallmoney Pénzérték a –214748.3647 közötti tartományban a pénzegység egy tízezrelékének pontosságával Float Lebegıpontos érték –1. eljárások és függvények). olyan SQL utasításokat tartalmazó programokat írhatunk. használatba vételük. A nevét gyakran rövidítik T-SQL –re. feltételes szerkezetek. amely programozási szerkezetekkel egészíti ki a nyelvet.4E+38 között 302/312 . amelyekben a szokványos programozási szerkezetek is megtalálhatók (változók.79E+308 között Real Lebegıpontos érték –3.

legfeljebb 8000 bájtig Változó hosszúságú bináris adat. legfeljebb 8000 bájtig Változó hosszúságú bináris adat. Az IF utasítások bármilyen szintig egymásba ágyazhatóak. kivéve text. között. legfeljebb 231-1 bájtig Hivatkozás kurzorra (sormutatóra).Datetime Smalldatetime Char Varchar Text Nchar Nvarchar Ntext Binary Varbinary Image Cursor Sql_variant Table Timestamp Uniqueidentifier Dátum. globally unique identifier) A változókat a DECLARE utasítással vezetjük be. declare @MyProductName nvarchar(40). legfeljebb 8000 karakterig Változó hosszúságú nem Unicode karakterek. amely minden sormódosításnál frissül. legfeljebb 231-1 karakterig Rögzített hosszúságú Unicode karakterek. 303/312 . @MyProductID int A változók null kezdıértéket kapnak. mint már megszoktuk. értéküket a SET utasítással állíthatjuk be: set @MyProductName = ’Szottyesz’ set @MyProductID = 5 Feltételes szerkezetek használata A feltételes szerkezetek ugyanúgy mőködnek. csak ilyenkor BEGIN END közé kell írnunk a kívánt utasításokat. egy táblában csak egy timestamp oszlop lehet Globálisan egyedi azonosító (GUID. június 6. között 1 perc pontossággal Rögzített hosszúságú nem Unicode karakterek. és 9999. amelyet a változó neve és típusa követ. vagyis sorok egy halmazára Bármilyen SQL SERVER adattípust tárolhat.december 31.és idıérték 1753.és idıérték 1900. ntext és timestamp típusúakat Sorok halmazát tárolja Egyedi bináris szám. legfeljebb 4000 karakterig Változó hosszúságú Unicode karakterek. csak a szintaktika más. legfeljebb 8000 karakterig Változó hosszúságú Unicode karakterek. legfeljebb 8000 karakterig Változó hosszúságú nem Unicode karakterek.január 1. és 2079.január 1. A változó neve elé egy kukacjelet @ kell írnunk. Egy sorban több változót is bevezethetünk.33 ezredmásodperc pontossággal Dátum. legfeljebb 2311 karakterig Rögzített hosszúságú bináris adat. Egyszerre több utasítást is megadhatunk. 3.

IF feltétel1 BEGIN Utasítások1 END ELSE BEGIN Utasítások2 END CASE utasítások A következı példában a SELECT utasítás eredményeként kapott értéket egy változóban tároljuk: DECLARE @State nchar(2) SET @State = ’Ma’ DECLARE @StateName nvarchar(15) SELECT @StateName = CASE @State WHEN ’CA’ THEN ’California’ WHEN ’MA’ THEN ’Massachusetts’ WHEN ’NY’ THEN ’New York’ END While ciklusok Ha egy vagy több utasítás többszöri végrehajtására van szükségünk. Az utasításforma a következı: DECLARE @count int SET @count = 5 WHILE(@count>0) BEGIN PRINT ’count = ’ + CONVERT(nvarchar. akkor WHILE ciklusokat használhatunk. amíg a megadott feltétel igaz. A WHILE ciklusok addig futnak. @count) SET @count = @count -1 END 304/312 .

Az utasítás formája: WAITFOR [DELAY ’idıtartam’ | TIME ’jelenlegi idı’] DELAY: várakozási idıtartam. a BREAK utasítást használhatjuk. Általában akkor van szükség erre. mielıtt bizonyos mőveleteket végrehajtanánk. és a program futása a ciklus utáni utasításokkal folytatódik. hogy azt szeretnénk. Az utasítás hatására a végrehajtás kikerül a ciklusból. súlyosság. A BREAK utasítás Ha egy WHILE ciklusnak azonnal véget szeretnénk vetni. WAITFOR utasítások használata Elıfordulhat. átugorva a ciklusból még esetleg hátralévı kódrészeket. ha valamelyik tárolt eljárásban hiba következik be.10 óra 2 perc 15 másodperckor folytatja a végrehajtást RAISERROR utasítások használata A RAISERROR utasítással hibaüzenetet állíthatunk elı. Az utasítás hatására a végrehajtás visszaugrik a ciklus elejére. de csak ha tárolt eljáráshoz használjuk. A WAITFOR utasítással adhatjuk meg.A CONTINUE utasítás A CONTINUE utasítással azonnal egy WHILE ciklus következı ismétlésére ugorhatunk. a RETURN -t követı egyetlen utasítás sem hajtódik végre. Az utasítással értéket is visszaadhatunk. Néhány példa: WAITFOR DELAY ’00:00:06’ . TIME: pontos idıpont. Az utasítás egyszerősített formája a következı: RAISERROR ({szám | leírás}{. RETURN utasítások használata A RETURN utasítással egy tárolt eljárásból vagy utasítások egy csoportjából léphetünk ki.6 másodpercig vár WAITFOR TIME ’10:02:15’ . hogy mennyi ideig várjon a program a többi utasítás végrehajtása elıtt. például éjszaka frissítenénk a felhasználói rekordokat. állapot}) 305/312 . hogy a program megállna.

Egy példaprogramon keresztül bemutatjuk a kurzorok használatát. 3. Ez nem mindig megfelelı. 2. mely megmutatja.Itt a szám a hiba száma. ami 0 és 18 között lehet. akkor egyszerre kapunk meg minden sort. megadva a megfelelı SELECT utasítást.3. a leírás egy 400 karakternél nem hosszabb üzenet. ProductName és UnitPrice oszlopait: Use Northwind -. UnitPrice FROM Products WHERE ProductID <= 10 -. elıfordulhat például. Megnyitjuk a kurzort.4. A kurzor segítségével végiglépkedhetünk az adott SELECT utasítás által visszaadott sorokon. hogy mi is az a kurzor. a súlyosság a hiba fokozata. Kurzor használatakor a következı lépéseket kell követnünk: 1. Bevezetjük a kurzort. KURZOROK használata Felmerülhet a kérdés.1. Ehhez egy kurzort (sormutatót) kell használnunk. ami a hiba hívási állapotát mutatja. az állapot pedig egy tetszıleges érték 1 és 127 között. Bezárjuk a kurzort.2. Nos amikor végrehajtunk egy SELECT utasítást. lépés: a változók bevezetése DECLARE @MyProductID int DECLARE @MyProductName nvarchar(40) DECLARE @MyUnitPrice money -. Kiolvassuk a sorokat a kurzorból. hogy egy adott sor visszakapott oszlopértékei alapján valamilyen mőveletet szeretnénk végezni. Változókat vezetünk be a SELECT utasítás által visszaadott oszlopértékek tárolására. amelynek 50001 és 2147483648 között kell lennie. 4. amellyel a z adatbázisból kinyert sorokat egyenként dolgozhatjuk fel. 5. lépés: a kurzor megnyitása OPEN ProductCursor -. lépés: a kurzor bevezetése DECLARE ProductCursor CURSOR FOR SELECT ProductID. lépés: a sorok kiolvasása a kurzorból FETCH NEXT FROM ProductCursor 306/312 . ProductName. hogy hogyan jeleníthetjük meg a kurzor segítségével a Products tábla ProductID. s mire lehet használni.

mellyel felszabadíthatjuk az általa használt rendszererıforrásokat. A kurzorban számos sor lehet. a FETCH utasításra van szükségünk. a változók típusa meg kell. A kurzort a DECLARE utasítás használatával vezetjük be. illetve a végrehajtani kívánt SELECT utasítást. @MyUnitPrice) END -. -1: A FETCH utasítás hibázott. lépés: a kurzor bezárása CLOSE ProductCursor DEALLOCATE ProductCursor Mint a példaprogramban is látható. A SELECT utasítás addig nem hajtódik végre. @MyUnitPrice PRINT ’@MyProductID = ’ + CONVERT(nvarchar. @MyProductID) PRINT ’@MyProductName = ’ + CONVERT(nvarchar. A kurzor bevezetése abból áll. @MyProductName) PRINT ’@MyUnitPrice = ’ + CONVERT(nvarchar. A @@FETCH_STATUS függvény visszatérési értékei: 0: A FETCH utasítás sikeresen visszaadott egy sort. @MyUnitPrice) WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM ProductCursor INTO @MyProductID. Függvények használata Az SQL Server számos függvényt bocsát a rendelkezésünkre. a kurzor megnyitása az OPEN paranccsal történik. @MyProductName. Ahhoz hogy a sorokat ki tudjuk olvasni a kurzorból. @MyProductName) PRINT ’@MyUnitPrice = ’ + CONVERT(nvarchar. amelyekkel értékeket nyerhetünk ki az adatbázisokból. Mint láthatjuk. s a DEALLOCATE utasítással a kurzorra való hivatkozást. amíg a kurzort meg nem nyitjuk. hogy egyezzen a kinyert sorok oszlopainak típusával. s a @@FETCH_S_TATUS -t kell alkalmaznunk annak megállapítására.INTO @MyProduct. 307/312 . @MyUnitPrice PRINT ’@MyProductID = ’ + CONVERT(nvarchar. Egy tábla sorainak számát például a COUNT ( ) függvénnyel kaphatjuk meg. -2: A lekért sor hiányzik. hogy a ciklusnak mikor kell véget érnie. @MyProductName.5. A kurzort a CLOSE utasítással zárhatjuk be. vagy a kért sor az eredményhalmazon kívülre esett. így egy WHILE ciklust. @MyProductID) PRINT ’@MyProductName = ’ + CONVERT(nvarchar. hogy megadjuk a kurzorhoz rendelendı nevet.

Összesítı függvények: egy tábla egy vagy több sora alapján adnak vissza információkat 2. kivéve a text. ami bármilyen típusú lehet. Helyben kifejtett táblaértékő függvények A helyben kifejtett (inline) táblaértékő függvények table típusú objektumokat adnak vissza. table és timestamp típusokat. @Discount float) RETURNS money AS BEGIN RETURN @OriginalPrice * @Discount 308/312 . Többutasításos táblaértékő függvények A többutasításos táblaértékő függvények is table típusú objektumokat adnak vissza. Matematikai függvények: számítások végzésére használatosak 3.Függvénykategóriák: 1. Kurzorfüggvények: a kurzorokról szolgáltatnak információt 8. de a helyben kifejtet táblaértékő függvényektıl eltérıen több T-SQL utasítást tartalmazhatnak. A felhasználói függvények létrehozására a CREATE FUNCTION utasítás szolgál. például a táblákról adnak információt 9. cursor.és idıfüggvények: dátum. Biztonsági függvények: az adatbázis felhasználóiról és szerepköreirıl nyújtanak információt 10.és képkezelési mőveleteket hajtanak végre Felhasználói függvények létrehozása Az SQL Serverben saját. A table objektumok olyanok. A helyben kifejtett táblaértékő függvények egyetlen SELECT utasítással kinyert adatokat adnak vissza. Metaadatfüggvények: az adatbázisról. mint egy szabályos adatbázistábla. Egy ilyen függvénnyel kiszámíthatunk például egy kedvezményes árat az eredeti ár és egy szorzó alapján. és három fajtájuk van: Skalárfüggvények A skalárfüggvények egyetlen értéket adnak vissza. Rendszerstatisztikai függvények: statisztikai adatokat adnak vissza az SQL Serverrıl 11.és képfüggvények: szöveg. Példa egy skalárfüggvényre: -. Rendszerfüggvények: az SQL Serverrıl szolgáltatnak információt 6.és idıkezelési mőveleteket hajtanak végre 5. Beállítási függvények: a kiszolgáló beállításairól adnak információt 7. ntext. image. Dátum. illetve a felhasználói adattípusokat. úgynevezett felhasználói függvényeket is készíthetünk. csak a memóriában tárolódnak.A DiscountPrice kiszámítja egy termék új árát az eredeti ár és a leértékelési szorzó alapján CREATE FUNCTION DiscountPrice (@OriginalPrice money. Szöveg. illetve annak elemeirıl. Karakterláncfüggvények: karakterláncokon hajtanak végre mőveleteket 4.

END Ha létrehoztuk a függvényt. Reorder nvarchar(3) 309/312 . A skalárfüggvények meghívása a következı: tulajdonos. meghívhatjuk. a függvénynév pedig a függvény neve.Itt nincs BEGIN és END utasítások közé zárt utasításblokk. amelyek UnitsInStock oszlopában a paraméterként átadott újrarendelési szintnél kisebb. és beszúr egy új oszlopot Reorder néven: CREATE FUNCTION ProductsToBeOrdered2(@ReorderLevel int) RETURNS @MyProducts table ( ProductId int. Példa egy helyben kifejtett táblaértékő függvényre: /*Visszaadja a Products tábla azon sorait. mely visszaadja a Products tábla azon sorait. SELECT * FROM ProductsToReordered(10) Többutasításos táblaértékő függvények Példaprogram. */ CREATE FUNCTION ProductsToBeReordered(@ReorderLevel int) RETURNS table AS ( SELECT * FROM Products WHERE UnitsInStock <= @REorderLevel ) A skalárfüggvényektıl eltérıen meghívásukkor nem kell feltüntetnünk a tulajdonost. vagy azzal egyenlı érték szerepel. amelyeket egyetlen SELECT utasítás tölt fel.függvénynév Itt a tulajdonos a függvényt létrehozó adatbázis-felhasználó neve. Helyben kifejtett táblaértékő függvények A helyben kifejtett (inline) táblaértékő függvények table típusú objektumokat adnak vissza. amelyek UnitsInStock oszlopában a paraméterként átadott újrarendelési szintnél kisebb. UnitsInStock smallint. a függvény mindössze egy SELECT utasítást tartalmaz. ProductName nvarchar(40). vagy azzal egyenlı érték szerepel.

majd az AS után jöhet a T-SQL kód. ha a felhasználók hozzáférését az adatbázistáblákhoz korlátozni akarjuk. ’NO’ FROM Products. hogy az adatbázisokban eljárásokat tároljunk. -. ha a UnitsInStock -.’YES’ –re állításával. ha olyan feladatot kell elvégeznünk. és egy tábla néhány adattal.beszúrásuk a MyProducts táblába -. Ezt követıen adhatjuk meg az eljárás nevét. mint a @ReorderLevel. Általában akkor készítünk tárolt eljárást. központosított kódra pedig akkor lehet szükség.) AS BEGIN -. Az SQL Server lehetıvé teszi. hogy 310/312 . ami erıteljesen igénybe veszi az adatbázist.a Reorder oszlop ’NO’ –ra állítása INSERT INTO @MyProducts SELECT ProductID.sorok kinyerése a Products táblából és -. amelynek segítségével a számlákat frissítjük a nap végén. UnitsInStock.a MyProducts tábla frissítése a Reorder oszlop -. CREATE TABLE Table01 ( value1 int. hogy jóval többféle adattípust adhatunk vissza. Az intenzív adatbázis-használatára jó példa lehet egy banki alkalmazás. Tárolt eljárások létrehozása: Szükségünk lesz egy adatbázisra. A tárolt eljárások abban különböznek a felhasználói függvényektıl. value2 varchar(10) ) Tárolt eljárás létrehozásához a create procedure utasítást kell használnunk. vagy azzal egyenlı UPDATE @MyProducts SET Reorder = ’YES’ WHERE UnitsInStock <= @ReorderLevel RETURN END Ennek meghívásakor sem kell a tulajdonost feltüntetnünk: SELECT * FROM ProductsToBeReordered2(20). például ProcedureTest névvel. hogy az egyes felhasználóknak ne kelljen ugyanarra a feladatra saját programokat írniuk.kisebb. ProductName. vagy ha központosítani szeretnénk a kódokat.

2 as select min(value1) as ’Minimum value1’ . ha már minden kapcsolat lezárásra került. UPDATE vagy DELETE 311/312 . a globálisnál pedig ## karaktert. azt más kívülrıl más nem tudja majd használni. hogy a lokális változatok automatikusan törlıdnek a kapcsolat lezárásával. Ha olyan paramétert szeretnénk megadni. ezzel szemben a globális eljárást más kapcsolatból is használhatják. melyen keresztül értéket is adnánk vissza. Létrehozhatunk úgynevezett lokális és globális ideiglenes eljárásokat is. amelyet az adatbázis-kezelı automatikusan futtat. amikor egy meghatározott INSERT. Lokális ideiglenes eljárás létrehozásához az eljárás neve elé tegyünk egy # karaktert. @a + @b) Tárolt eljárások végrehajtása: A tárolt eljárások végrehajtására az EXECUTE utasítást használhatjuk. max(value1) as ’Maximum value1’ from Table01 Futtassuk az imént létrehozott eljárást: execute Procedure01. A név után a paraméter típusát adhatjuk meg. míg a globálisak csak akkor. akkor elegendı megadni az eljárás nevét és annak összes változata törlésre kerül. create procedure Procedure01. Ezt az eljárás neve után tehetjük meg egy vesszıvel elválasztott felsorolásban. akkor a típus után az OUTPUT jelzıt kell írnunk. hogy a név után pontosvesszıvel megadunk egy sorszámot. @b int as select convert(varchar(20).mit is végezzen el a létrehozott eljárás. Természetesen paramétereket is adhatunk a tárolt eljárásnak. Na de nézzünk egy példát: create procedure Procedure01 @a int. Ennek ott lesz elınye. Fontos. execute Procedure01 150. ezek között úgy tudunk különbséget tenni. hogy ha törölni akarjuk az eljárásokat a DROP PROCEDURE utasítással. A lokális csak a saját kapcsolatban használható. 50 Több eljárásnak adhatunk azonos nevet is.2 Kioldók A kioldók (trigger) olyan különleges tárolt eljárás. A paraméternév mindig egy @ jellel kezdıdik.

hogy az adatbázisokban eljárásokat tároljunk. A kioldók igen hasznosak például akkor. amelyekkel értékeket nyerhetünk ki az adatbázisokból.utasítást egy bizonyos adatbázistáblán végrehajtunk. Az SQL Server azt is lehetıvé teszi. A kioldókat a CREATE TRIGGER utasítással hozhatjuk létre. UPDATE vagy DELETE utasítás helyett is elindulhat. 312/312 . Az SQL Server számos függvényt bocsát a rendelkezésünkre. vagy ha központosítani szeretnénk a kódokat. ha olyan feladatot kell elvégeznünk. Általában akkor használjuk. A Transact-SQL –rıl láthattunk egy rövid ismertetıt. A kioldó egy INSERT. Az SQL Serverben saját. A tárolt eljárások abban különböznek a felhasználói függvényektıl. A T-SQL segítségével olyan SQL utasításokat tartalmazó programokat írhatunk. úgynevezett felhasználói függvényeket is készíthetünk. ami erıteljesen igénybe veszi az adatbázist. hogy jóval többféle adattípust adhatnak vissza. hogy az egyes felhasználóknak ne kelljen ugyanarra a feladatra saját programokat írniuk. ha egy tábla oszlopértékeinek változásait szeretnénk ellenırizni. amelyekben a szokványos programozási szerkezetek is megtalálhatók.