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 .

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

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

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

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

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

Visszatérés az ugró utasítást követı utasításra (azon helyre. Ezek mindegyike 1 byte tárolási igényő. - Ezekbıl kellett összerakni a programot. ’bool’. 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. ha az elıírt feltétel teljesül. csak ezen 1 byte-on hordozott információ jelentésében térnek el. Feltételes vezérlésátadás (feltételes ugró utasítás): mint az egyszerő ugró utasítás. 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ı. csak egy olyan típusnév volt. hogy itt valójában feltételes elágazás történt – nem egyszerő. de az ugrást csak akkor kell végrehajtani. Vezérlési szerkezetek az assembly nyelvben Az assembly nyelv másik szegényes tulajdonsága a vezérlési szerkezetek hiánya. ahonnan az ugrás történt). Mivel a jelentést a fordító még nem kezelte. ’short int’. Nem volt ’char’. ’unsigned short int’ típusok. amelynek 1 byte volt a tárolási igénye. Ennek megfelelıen ezt még nem tekinthetjük tényleges típusnévnek. majd attól a ponttól kezdve a végrehajtás újra szekvenciális. mindössze tárolási-igény névnek. hogy az assembly nyelvő programból kibogozni.Nem voltak ’finom’ típusnevek. A változó más komponenseinek (élettartam. és az assembler programokból. hatáskör) kezelése is hiányzott az assembly nyelvbıl. Feltétlen vezérlésátadás (ugró utasítás): a program folytatása egy másik memóriabeli pontra tevıdik át. Hasonló problémákkal jár a 13/312 .

nagyon sokat könnyítenek a programkód olvashatóságán. és a tesztelési ideje is alaposan lerövidült. és nem generálta újra a hozzá tartozó object kódot. hogy mely forráskód-fileokból tevıdik össze a project. értékkel tér vissza az adott függvény? A fenti kérdésekre a válaszokat maga az assembly nyelv nem tartalmazza. akkor hol kapjuk meg a visszatérési értéket? Illetve honnan tudjuk. melyek segítségével a programok fejlesztési ideje. mert az assembly programok általában nagyon hosszúak voltak. Egy másik programozó által fejlesztett. és az assembly nyelv értelemszerően átvette. Amennyiben a forráskódon nem történt módosítás. úgy azt az assembler egy gyors ellenırzéssel észrevette. Ezt a szakaszt újra és újra lefordítani az assemblerrel felesleges idı és energiapocsékolás volt. hanem hogy az eljárásnak hogyan adunk át paramétereket? Illetve. Egy hosszú forráskód fordítása nagyon sok idıbe került. A probléma nem is itt rejtızik. milyen típusú adattal. de megfelel az eljárásnév primitív fogalmának. másrészt az akkori számítógépek még nagyon lassúak voltak. 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. 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. azt a programozó nem módosította – mivel a program már másik pontján járt a fejlesztés. 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). Így 14/312 . Több modulból álló programok az assembly nyelvben A több modulra tagolás azért volt fontos.ciklusok megtervezése és kódolása is – különösen az egymásba ágyazott ciklusok esete. 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. mint újra megírni a szóban forgó eljárást. Az assembler a forráskód-modulokat egyenként fordította le egy-egy tárgykód (object) állományba. Ezeket a lehetıségeket maga a gépi kód tartalmazza. újra felhasználható eljárásokat és függvényeket. A programozók szívesen fejlesztettek általános. A nevesített címkék egy jó névválasztással. hanem függvény. Ekkor az assembler a fordításhoz egy listát kapott. Ugyanakkor a program jelentıs része a fejlesztés közben már elkészült. ha ez nem eljárás.

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

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

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

változók. mint kódolási technikákban. és nagyon egyszerő. Mivel ezen függvények és operátorok az adott típushoz tartoznak. szelekció.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. iteráció). amely elsısorban adatbázis-kezelésre van felkészítve. hogy nagyon kevés nyelvi elemmel dolgoznak. A saját típusokhoz nem csak operátorokat rendelhet. szinte mondatszerően olvasható utasítások fogalmazhatók meg. Erre jó példa az SQL nyelv. Ezek után a saját típus szinte minden szempontból egyenragúvá válik a nyelvi alaptípusokkal. Egy OOP nyelvben tehát szintén megtalálhatóak az eljárások és függvények. Ezért az OOP nyelvek inkább csak szemléletmódban mások (melyik eljárást és függvényt hova írjuk meg). 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. Meglévı típusok továbbfejlesztésével (öröklıdés) kevés munkával készíthet új típusokat. Ezért az OOP nyelveket nem tekintik külön generációnak. illetve a paraméterek. 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 . gyakorlatilag e nyelvek kutatása. a hozzájuk tartozó mőveletek és operátorok csoportját (halmazát) osztálynak nevezzük. a típus részeinek tekintendık. amelyek az adott típusú adatokkal végeznek valamilyen mőveletet. fejlesztése még folyamatban van. A vezérlési szerkezetek is a megszokott három formára épülnek (szekvencia. A saját típusaihoz (általában) készíthet operátorokat is (melyeknek jelentését természetesen le kell programozni). Ö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. Ezen nyelvek jellemzıje. A felhasználó sokkal egyszerőbben és szabadabban készítheti el a saját típusait. hanem megadhat függvényeket és eljárásokat is.

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

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

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

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

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

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

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

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

-

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

eltelik egy kis idı (1 másodperc). amilyen sorrendben a programozó leírta azokat. Miért? A számítógép a program sorait nem akármilyen sorrendben hajtja végre.WriteLine("Hello Világ"). kis ideig nem történik semmi. } A kiírt szöveg megjelenik. A megadott érték (1000) éppen 1 másodpercnyi várakozást jelent.Thread.WriteLine("Hello Világ"). 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).Console. és azonnal bezáródik az ablak. Próbáljuk meg fordított sorrendben: static void Main(string[] args) { System. hogy a program jelen esetben 1 másodpercre ’elalszik’. } Indítsuk el a programot.Console.Threading. hogy hova írjuk ezt a sort! A szabály értelmében a Main függvény belsejébe kell írni. A Sleep=aludni jelentése konkrétan annyi. 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 . 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. és gondolkozzunk el a látottakon: a kis ablak elıbukkan. Ezt azt elvet késıbb pontosítjuk. majd felvillan a kiírás. System. és elnevezzük szekvencia-elvnek.Thread. Van egy nagyon fontos szabály: az utasításokat ugyanabban a sorrendben kell végrehajtani. 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.Sleep(1000).Threading.Sleep(1000). majd bezáródik az ablak.

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

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

pl. Programozási feladat: Írassuk ki a képernyıre a családfánk egy részét. az alábbi formában: *** WriteLine *** Kiír egy szöveget a képernyıre. 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. *** ReadLine *** Vár egy ENTER leütésére.Feladatok: 1. *** Sleep *** Várakozik a megadott idıig. pl. 36/312 . és rövid leírásukat. Programozási feladat: Írassuk ki a képernyıre az eddig megismert C# parancsokat.

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

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

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

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

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

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

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

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

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

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

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

x = x – 2. mely a felhasználótól bekéri egy tetszıleges kör sugarát. csak a megfelelı formátum string-et kell elkészítenünk. A feladat az. A kifejezések kiszámítását elvégezhetjük a kiíró utasításban is. összehasonlítások: a = = b. (egész osztás) x = x % 2. hogy egy változóba beolvassuk az adott kör sugarát. A mőveleteket csoportosíthatjuk a következı módon: • • • • Értékadás: a = 2. A programhoz szükséges ismeretek: a kör kerülete: 2r*∏. x %= 2. Jelentés x = x + 2. 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. x *= 2. A mőveleti jelek alapján három kategóriát hozhatunk létre. x -= 2. 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. Az elsıben már egész jól megtanultuk a társas érintkezés formáit. Honnan vegyük a pí-t? Írhatnánk egyszerően azt. vagy r2*∏. mind a programok világában. rövid forma += -= *= /= %= Használat x += 2. hogy a mőveletben hány operandus szerepel.Az ilyen és hasonló párbeszédek érthetetlenné teszik a kommunikációt mind a valós életben. Unáris. hogy elegendı tudással rendelkezünk a Consol I/O parancsairól és a mőveletek használatáról. (maradékos osztás) Most. feltételes mőveletek. és a területe: r*r*∏. készítsünk programot. és a pí értékét behelyettesítenünk a képletekbe. bináris és ternáris mőveletek. és azt. hogy a rövidített formulák mivel egyenértékőek. x = x / 2. hogy 3. 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 . majd kiszámítja annak kerületét és területét. matematikai mőveletek: z = a + b.14. x = x * 2. Az aritmetikai értékadásokat rövid formában is írhatjuk. a < c. Az elnevezések arra utalnak. x /= 2. A következı táblázat bemutatja a rövidítések használatát.

majd a Console. 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.Convert. 49/312 .PI.ToBoolean(Console.using System. Console. s a program az enter leütése után befejezi futását. Console. Console. r=Convert.WriteLine("A kör kerülete : {0}.WriteLine("kör sugara : ").ReadLine(). és a Convert osztályról. } } } Vizsgáljuk meg. területe : {1} ". namespace ConsoleApplication7 { class Class1 { [STAThread] static void Main(string[] args) { int r=0. Az eredmény kiíródik a képernyıre. A legtöbb alkalmazásban szükség van a típusok közti konverzióra.WriteLine("{0}". Bool b=Convert. A fejezetben már szóltunk a típusok konverziójáról. a kör sugarát. Az egész típusú számokkal már jól boldogulunk.PI).WriteLine() – metódusban kiszámoljuk a megadott kifejezés alapján a kör kerületét és területét. Nullánál false visszatérési értéket kapnánk.2*r*Math. Console.r*r*Math. Logikai true értéket kapunk eredményül. de sajnos az élet nem ilyen egyszerő.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.ReadLine()). hogyan mőködik a program! Az r változóban tároljuk a billentyőzetrıl beolvasott értéket.ReadLine()).ToInt32(Console.

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

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

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

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

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

vagy hamis. VAGY A TRUE B TRUE A || B TRUE 55/312 . illetve a logikai vagy operátorok.A logikai típusú változó A logikai típusú változónak két lehetséges értéke van. Logikai kifejezéseket logikai operátorokkal köthetünk össze. Ezek a tagadás. attól függıen. hogy mi a változó pillanatnyi értéke. Ezek az értékek konstansként is megadhatók: bool logikai = true. a TRUE és a FALSE. 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. Például ha Sz változó int típusú. Az összehasonlítás eredményét tudjuk tárolni egy logikai típusú változóban. logikai = sz < 4. É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. a logikai és. ha mindkét paraméter értéke igaz.logikai). akkor az Sz < 4 kifejezés értéke lehet igaz is és hamis is. Console.WriteLine("{0}". bool logikai = true. Két kompatibilis érték összehasonlításának eredménye vagy igaz (true) vagy hamis (false) lesz. vagyis igaz. int sz = 2.

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

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

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

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

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

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

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

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

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

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

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

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

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

ha a1=1! 69/312 . 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.2.23. Programozási feladat: Írjunk olyan programot. amely bekéri egy tetszıleges mértani sorozat elsı elemét.11.! 8. vagy az Euklideszi algoritmussal is.30.10-re! 11. 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 az an=an-1+2n sorozat elsı 10 elemét. amely mindkét számot osztja. Programozási feladat: Számoljuk ki és írjuk ki a képernyıre a 2n értékeit n=1. 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. 3. Programozási feladat: Állapítsuk meg.5. Programozási feladat: Írjunk olyan programot. Programozási feladat: Állapítsuk meg két billentyőzetrıl bekért számról. 4.stb. ha a legnagyobb közös osztójuk az 1.! Ellenırizzük le az eredményt a számtani sorozat összegképlete segítségével! 7. amely bekéri egy tetszıleges számtani sorozat elsı elemét.5. és az elemek összegét! 10. egy sorban! 9. Programozási feladat: Állapítsuk meg két billentyőzetrıl bekért számról. Programozási feladat: Állapítsuk meg egy billentyőzetrıl bekért számról.8.stb.Feladatok: 1. 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. és a kvócienst! Ezek után kiírja a képernyıre a mértani sorozat elsı 20 elemét.12. hogy mi a legnagyobb közös osztójuk! A legnagyobb olyan szám. hogy relatív prímek-e! Akkor relatív prímek.…. amely kiszámolja és kiírja az alábbi változó növekményő számtani sorozat elsı 20 elemének összegét: 3. 2. Ezen értéket meghatározhatjuk kereséssel (ciklus). az elemeket egymástól vesszıvel elválasztva.7. Programozási feladat: Írjunk olyan programot. hogy prímszám-e! A prímszámoknak nincs 1 és önmagán kívül más osztója.9.

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. amely addig írja ki a képernyıre a an=2n-2n-1 sorozat elemeit a képernyıre.b] intervallum belsejébe esı négyzetszámokat (írjuk ki a képernyıre). Programozási feladat: Írjunk olyan programot. 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 . amíg a sorozat következı elemének értéke meg nem haladja az 1000-t! A sorozat elsı eleme: a1=1! 13.12. és azok összegét! Az a és b értékét kérjük be billentyőzetrıl! 15. Programozási feladat: Határozzuk meg egy [a.

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

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

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

Write(j. Array. Deklarációja: public static void Sort(Array array). Használata: tm[0] = 1. melynek egy paramétere van. tm[3] = 90. tm[4] = 4.Console. int length).ToString()+" ").Console. Ha a Sort metódus három paraméteres változatát használjuk. int index. tm[1] = 2.Sort(tm). ShowArray(tm). ShowArray(tm). 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. System.WriteLine(). tm[2] = 17. A Sort metódus. akkor a tömb egy résztömbjét rendezhetjük. 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.A tömb elemeinek rendezése. helyben rendezi a paraméterként kapott tömböt.} Ennek a segítségével vizsgáljuk meg az Array osztály lehetıségeit. 74/312 . Deklarációja: public static void Sort(Array array.

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

ShowArrayST(stm2). tm[2] = 17.Write(j+" "). Array items.Sort(tm. ShowArray(tm). Array. } tm[0] = 1. de csak részhalmaz rendezésre használható az alábbi metódus: Deklaráció: public length).stm2).Console."második". System. tm[3] = 90. ShowArrayST(stm2). string[] stm2 = new string[5] {"elsı". static void Sort(Array keys. int index.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."harmadik". a kulcsokhoz tartozó elemeket tartalmazó tömb index: a rendezendı terület kezdıpozíciója length: a rendezendı terület hossza 76/312 . int keys: egy egydimenziós kulcsokat tartalmazó tömb items: egy egydimenziós. tm[1] = 34. ShowArray(tm).Console. "ötödik"}. 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. "negyedik".WriteLine(). tm[4] = 4.

tm[3] = 90. melyenek megoldásához tömböket használunk."második". string[] stm2 = new string[5] {"elsı". Array.Sort(tm.3. ShowArray(tm). ShowArray(tm). tm[4] = 4.stm2. tm[1] = 34. 77/312 . ShowArrayST(stm2). ShowArrayST(stm2). 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."harmadik". tm[2] = 17.Használata: tm[0] = 1.2). "negyedik". "ötödik"}.

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

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

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

WriteLine(). i++) { tm[i] = rnd. Megoldás: int[] tm = new int[10]. Random rnd = new Random(). i<10. int i. i<10.Next(100. majd határozzuk meg a számok összegét.Write("{0} } Console. Console.tm[i]).WriteLine("A számok összege: {0}". for (i=0. for (i=0 . Töltsük fel véletlen számokkal.200). egész típusú tömb. Magyarázat: 81/312 . sum = 0. ". Console.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ő. i++) sum += tm[i]. sum).

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

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

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

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

BinarySearch: Rendezett listában a bináris keresés algoritmusával megkeresi az elemet Clear: Minden elemet töröl a listából. Csak olvasható tulajdonság. Deklarálás: ArrayList arl = new ArrayList(). Item: A megadott indexő elemet lehet írni vagy olvasni. Sort: Rendezi az elemeket az ArrayListben. 86/312 . IndexOf: A megadott elem elsı elıfordulásának indexét adja vissza. 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. A lista elsı elemének az indexe a 0. Insert: Beszúr egy elemet az ArrayListbe a megadott indexhez. CopyTo: Átmásolja az ArrayList-át egy egydimenziós tömbbe. Count: az elemek számát olvashatjuk ki. Az ArrayList fıbb jellemzıi: Capacity: az elemek számát olvashatjuk illetve írhatjuk elı.

a). Amennyiben ez nem nulla értékő.Write("{0} } ". if (elem != 0) dtm. míg nullát nem írunk be. Az adatbekéréskor a ReadLine() függvény által visszaadott karakterláncot konvertáljuk Int32 típussá.Parse(Console.Feladatok dinamikus tömbre Kérjünk be számokat a nulla végjelig ArrayList dtm = new ArrayList(). int i = 0.Add(elem). 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. 87/312 . Az adatbekérést mindaddig folytatjuk. és példányosítsuk is. elem. do { elem = Int32.ReadLine()). hozzáadjuk az ArrayListánkhoz az add metódus meghívásával. Deklarálunk egy dtm nevő ArrayList objektumot. } while (elem != 0). és a konverzió eredményét tároljuk az elem nevő változóba.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Az osztály (class) mintegy csoportba foglalja az egy témakörbe. hogy ne csak a Main()-bıl hívjunk eljárásokat. függvényeket. ezért érvényes az azonosító névképzési szabálya: betővel vagy aláhúzással kezdıdik. 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. számjeggyel.Természetesen van rá lehetıség. 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. 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ó. feladatkörbe tartozó eljárásokat. változókat. betővel. Hová írjuk az eljárásainkat? Az Objektum Orientált programozás elvei szerint a programok építıkövei az osztályok.

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

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

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

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. Programozási feladat: Készítsünk olyan eljárást. amely két megosztott. feltöltött tömb elemeit mint halmazokat kezeli. Programozási feladat: Készítsünk olyan eljárást. amely egy megosztott tömb elemei közül meghatározza a legnagyobb elem sorszámát. de csak pozitív számokat fogad el! 17. Készítsünk olyan eljárást. amely két megosztott. ahol a 0 jelenti a tócsát. Egy arra járó sétáló maximum 4 egymás melletti tócsát képes átugrani egyszerre. amely egy ilyen tömb 133/312 . Az ösvényt egy tömbben írjuk le. de nem enged meg ismétlıdést (két egyenlı értékő elemet nem fogad el)! 18. feltöltött tömb elemeit mint halmazokat kezeli. amely két megosztott. az 1 jelenti a száraz foltot. feltöltött tömb elemeit mint halmazokat kezeli. Programozási feladat: Készítsünk olyan eljárást. és ezen értéket berakja egy megosztott ’maxI’ nevő változóba! 21. Programozási feladat: 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. é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. Programozási feladat: Egy ösvényen tócsák és száraz foltok váltogatják egymást. és ezen értéket berakja egy megosztott ’max’ nevő változóba! 20.Random osztály példányát kell használni)! 19. 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. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást. amely egy feltöltött. amely egy megosztott tömb elemeit kéri be billentyőzetrıl. Programozási feladat: Készítsünk olyan eljárást. é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. amely egy megosztott tömb elemeit kéri be billentyőzetrıl. Programozási feladat: Készítsünk olyan eljárást. megosztott tömb alapján meghatározza.Feladatok: 16. Programozási feladat: Készítsünk olyan eljárást. amely egy megosztott tömb elemei közül meghatározza a legnagyobb elem értékét.

amely egy feltöltött tömb elemeinek ismeretében megadja azt a legszőkebb intervallumot. Az x értékét 134/312 . Programozási feladat: Készítsünk olyan eljárást. amelybıl a tömb elemek származnak! 29. mint a tömb elemszáma. amely egy megosztott tömb elemeit végigolvasva megadja. amely egy polinom helyettesítési értékét számolja ki. amely egy ’a’ tömb páros elemeit átmásolja egy ’b’ tömb elejére. ahol a tömb elemek növekvı sorrendben vannak! 28. Programozási feladat: Készítsünk olyan eljárást. amely egy ’a’ tömb elemeit fordított sorrendbe bemásolja egy ’b’ tömbbe! 30. Programozási feladat: Készítsünk olyan eljárást. bemásolja egy ’b’ tömbbe. hogy a sétáló képes-e átjutni az ösvény egyik végébıl a másikba anélkül. Programozási feladat: Készítsünk olyan eljárást. a maradék elemeket pedig a ’b’ tömb végére! 32. akkor is helyesen mőködjön a program! 34. Programozási feladat: Készítsünk olyan eljárást. amelyek párosak. Programozási feladat: Készítsünk olyan eljárást. hogy tócsába kellene lépnie! 26. 27. n=1 esetén elızı feladat)! Ha az n értéke nagyobb. A maradék helyeket töltsük fel 0-kal! 31. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást. Programozási feladat: Készítsünk olyan eljárást. amely egy feltöltött tömb elemeinek ismeretében megadja a leghosszabb olyan szakasz elemszámát.alapján meghatározza. 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. o c: rendezetlenek. 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]. Programozási feladat: Készítsünk olyan eljárást. hogy a tömb elemei o a: növekvı sorrendbe vannak-e rendezve. 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 egy. 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. o b: csökkenı sorrendbe vannak-e rendezve. egész számokkal feltöltött ’a’ tömb elemei közül azokat.

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

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

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

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

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

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

int típusú tömbben a leghosszabb egyenlı elemekbıl álló szakasz hosszát! 48. amely kap paraméterként két számot.Feladatok: 45. és visszaadja a két szám közül a nagyobbik értékét! Amennyiben a két szám egyenlı. 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. úgy az elsı szám értékét kell visszaadni! 46. Programozási feladatok: készítsünk olyan függvényt. Programozási feladatok: készítsünk olyan függvényt. amely kap két int tömböt paraméterként. 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. amely meghatározza egy paraméterben megadott. 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.

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

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

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

Csakhogy a ’kisTomb’ értéke egy memóriacím. ez az. static void Kiiras(int a) { . ami valójában átmásolódik a ’tomb’ váltózóba. Kiiras(x). A fenti ábrán látszik. } static int[] kisTomb=new int[10].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. akkor azt a küldı oldal is észlelni fogja majd: static void Feltoltes(int[] tomb) { tomb[0] = 10. hogy a ’kisTomb’ változónk aktuális értéke átmásolódik a ’tomb’ aktuális értékébe. 151/312 . } 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é).. Ekkor a fogadó oldal megkapja a memóriaterület címét. és nem ténylegesen a tömb elemei. és ha beleír ebbe a memóriaterületbe. hanem csak a szóban forgó tárterület címe (memóriacíme) adódik át.. Feltoltes( kisTomb ).

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

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

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

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. Mivel ilyenkor érdekes a paraméterek aktuális értéke is. } 155/312 .j++) if (tomb[i]>tomb[j]) Csere(ref tomb[i]. ezért a ’ref’ kulcsszót kell használni.j<tomb.Length.A fenti eljárás a paramétereként megkapott két változó tartalmát cseréli fel.i<tomb.ref tomb[j]).i++) for(int j=i+1.

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

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

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

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

} catch (ArithmeticException ar) { Console. (Nem igaz ez arra az esetre. függetlenül az elıtte keletkezett hibáktól. ahol a megnyitott fájlt hiba esetén is le kell zárni.) A következı példa bemutatja. try { c=10/a. A fontosabbakat az alábbi táblázatban foglaltuk össze. Az ilyen típusú problémákra nyújt megoldást a finally kulcsszó. hogyan alkalmazhatjuk a nyelv finally kulcsszavát: int a=0. } 160/312 . A finally blokkban elhelyezett kód mindig lefut.ar). 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. 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.A System névtérben rengeteg kivétel típust definiáltak. double c.WriteLine("Aritmetikai hiba : {0}".

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

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

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. majd a képernyıre írja a beolvasott számok négyzetét! A program csak számokat fogadjon el inputként. mely számokat olvas be a billentyőzetrıl. Írjon programot. Módosítsa az elızı programot úgy. hogy a beolvasásnál csak 3-mal és 5-tel osztható számokat fogadjon el! 6. majd tárolja egy int típusú változóban. Nem számtípus beolvasásakor kivételekkel kezelje le az elıforduló hibákat! 8. Készítsen programot. mely egy n elemő tömbbe olvas be egész típusú értékeket. Írjon programot. Készítsen programot. ha a felhasználó a string-ben nem számokat ad meg. 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. A beolvasott számot alakítsa szám típussá. mely a fejezetben felsorolt kivételek nevét kiírja a képernyıre. 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. Az elızı programot módosítsa úgy. de csak páros számokat fogad el! 5. A beolvasás és a konverzió során keletkezı hibákat kivételekkel kezelje le! (Hiba az is. Erre külön hívjuk fel a figyelmét!) 163/312 . 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. hogy a kivételek dobáskor a hibaüzenetek megjelenjenek a képernyın! 4. Készítsen programot.Programozási feladatok 1. Készítsen programot.

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

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

A .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. A panelre kattintva tudjuk megmondani a szerkesztınek. A panel a projekt elemeit fa struktúrába szervezve tartalmazza. hogy a using rész kibıvült a következı hivatkozásokkal: 166/312 . hogy mutassa meg a forráskódot. A program sorait tanulmányozva rögtön feltőnik az. melynek a felirata Class View. a szerkesztıbe betöltıdik a Form-hoz tartozó kód. Ha itt kiválasztjuk a Form1 címkét. és duplán kattintunk rá.

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

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

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

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

vagy tiltja a drag and drop funkciót. Alapbeállításban tiltva van.A látható komponensek. a kontrollok Button (Gomb) A nyomógomb komponens által a felhasználó mőveletet hajthat végre. Az imagelistben megadott képnek az indexe A gomb a bal felsı saroktól való 171/312 . vagy megszakíthat egy folyamatot. Properties (Tulajdonságok) AllowDrop Anchor BackColor BackgroundImage ContextMenu DialogResult Dock Enabled Font ForeColor ImageList ImageIndex Location Engedélyezi. 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. 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. Például elindíthat.

protected. amihez a felhasználó nem fér hozzá. KeyDown KeyUp Leave MouseEnter MouseLeave ParentChanged távolsága x. 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. 172/312 .Locked Modifiers Size TabStop TabIndex Text TextAlign Visible Események: Click Enter GotFocus Keypress. private.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.

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.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. ahol a felhasználó általában egysoros szöveget adhat meg. Az imagelistben megadott kép indexe A gombnak a bal felsı saroktól mért távolsága x. 173/312 . vagy tiltja a drag and drop funkciót. 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. vagy módosíthat.

amikor egy igaz/hamis. 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. 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. De amíg a CheckBoxnál a lista elemeinek kombinációját választhatjuk ki. és a CheckAlign ContentAlignment. Ha ez FlatStyle.MiddleLeft vagy ContentAlignment. Az Appearance (megjelenés) tulajdonságnál azt állíthatjuk be.MiddleRight igazítást figyelembe véve jelenik meg. Ha három akkor mindezt a CheckState tulajdonságnál tudjuk megtenni. Ha kettı akkor a CheckBox aktuális értékét lekérdezni és beállítani a Checked tulajdonságnál tudjuk.Systemre van állítva. addig a RadioButtonnál már csak a lista egy elemét. Mindkettı lehetıvé teszi a felhasználó számára. hogy egy listából válasszon. akkor tulajdonság figyelmen kívül van hagyva. hogy a CheckBox egy általános kiválasztó négyzet legyen vagy egy nyomógomb.Tulajdonságai: AutoSize Borderstyle CharacterCasing Lines MaxLength Multiline PasswordChar Text Események: Keypress. hogy a CheckBoxnak két vagy három állapota legyen. Megjegyzés: Mikor a FlatStyle tulajdonság FlatStyle.Systemre van állítva. igen/nem választási lehetıséget szeretnénk adni a felhasználó számára. Ha a CheckAlign tulajdonság az egyik jobb igazításra van állítva akkor ez a vezérlı elem úgy jelenik meg. A ThreeState tulajdonság azt határozza meg. . hogy a 174/312 . akkor a felhasználó operációs rendszerének beállításai határozza meg ezt. A CheckBoxnak és a RadioButtonnak a funkciója ugyanaz.

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

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

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

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

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

ami megjelenik a vezérlı fölött.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 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. 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. betőszín) a vezérlıben látható szöveg DropDownStyle Font ForeColor Text Viselkedés AllowDrop ContextMenu meghatározza. ha a listarészlet csak teljes elemeket tartalmazhat. hogy a ComboBox engedélyezett. 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.

hogy a ComboBox menüje legördült DropDownStyleChanged jelzi. amikor egy bizonyos elemet vagy területet meg kell rajzolni DropDown azt jelzi. 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. ahonnan a vezérlı az elemeit veszi az adatforrás egy tulajdonsága. 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 Items Tag a listát jelöli.TabIndex TabStop Visible Adat DataSource DisplayMember rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja. 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. mezıje. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. amit a comboboxban meg kívánunk jeleníteni Collection. 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. amikor egy 181/312 . hogy a vezérlı átméretezhetı.

amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. a lista mindig látszik Szerkeszthetı mezı. Count Add Insert Remove Indexer. akkor a SelectedIndex tulajdonságot használjuk. 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. a lista lenyitható. ami egy objektumot ad vissza. Ha az indexére van szükségünk. 182/312 . (alapértelmezett) Nem szerkeszthetı a mezı. Így kezelése a szokásos metódusok használatával lehetséges. 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ı. Ez a tulajdonság egy ObjectCollection típus. ha megváltozott a vezérlı stílusa bekövetkezik. 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.SelectedIndexChanged StyleChanged SystemColorsChanged bizonyos elem magasságát ki kell számítani akkor következik be.

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

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ıben megjelenhetnek-e gördítısávok. hogy a vezérlı kijelölt elemén megmarad-e a kijelölés. 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. 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. hogy az elemek címkéit megváltoztassák azt jelöli. lista.Cursor Font ForeColor FullRowSelect GridLines View Viselkedés Activation mellett a kurzor típusa.. 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 . ami megjelenik a vezérlı fölött. hogy kijelölhetı-e egy elem azáltal. az elemek megjelenítési módja (ikonok. 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. hogy a felhasználó megváltoztathatja-e az oszlopok sorrendjét jelzi. hogy a vezérlı fogadhat-e „Fogd-és-vidd” értesítéseket az ikonok automatikus rendezettségét jellemzi helyi menü. hogy a combobox engedélyezett.) Alignment AllowColumnReorder AllowDrop AutoArrange ContextMenu Coulumns Enabled HeaderStyle HideSelection HoverSelection ImeMode Items LabelEdit LabelWrap LargeImageList MultiSelect Scrollable meghatároza. 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. betőszín) Megmutatja. vagy nem Oszlopfejlécek stílusa azt jelöli. ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg A vezérlıben megjelenı oszlopfejlécek.. Collection azt jelzi. hogy az egérkurzort fölötte hagyjuk A ListView elemei megengedi a felhasználónak. amikor a vezérlı elveszíti a fókuszt megmutatja. részletek.

hogy a vezérı átméretezhetı. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. 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 . ha megváltozott a vezérlı stílusa bekövetkezik. 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. 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. azaz újabb elem kerül kijelölésre jelzi.Tervezés Name Locked Modifiers Anchor Dock Location A vezérlı neve megmutatja. 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 a vezérlı elveszíti a fókuszt megmutatja. ami megjelenik a vezérlı fölött. ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg azt jelzi. amelybıl a csomópontokhoz tartozó képek származnak 186/312 . hogy az elemek hyperlink-stílusúvá váljanak-e. vagy nem Megmutatja. hogy a vezérlı fogadhat-e „Fogd-és-vidd” értesítéseket helyi menü.TreeView Ez az osztály az elemek hierarchikus rendben történı megjelenését szolgálja. betőszín) a TreeView egy elemének magassága pixelben meghatározza. hogy egy elemen történı kattintás kijelöli-e az elem összes al-elemét is azt jelöli. 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. 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. hogy a combobox engedélyezett. amikor az egérkurzort fölé mozgatjuk szöveg megjelenítésére használt betőtípus elıtérszín (pl. hogy megjelennek-e CheckBoxok az elemek mellett a kurzor típusa. hogy a vezérlı kijelölt elemén megmarad-e a kijelölés.

amikor a felhasználó elkezd „vonszolni”egy elemet akkor következik be. 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 . amikor a kijelölés megváltozik A vezérlı neve megmutatja. 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 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. hogy a vezérlı tartalma rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. hogy a vezérı átméretezhetı. 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. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. 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.

BeforeCheck BeforeCollapse BeforeExpand BeforeLabelEdit BeforeSelect HelpRequested StyleChanged SystemColorsChanged kiváltódik. ha megváltozott a vezérlı stílusa bekövetkezik. 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. 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 .

hogy a fejlécelemek vizuálisan megváltozzanak-e. hogy a vezérlı fogadhat-e „Fogdés-vidd” értesítéseket megjelenési beállítások helyi menü. 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. amikor az egérmutató föléjük ér 189/312 . ami megjelenik a vezérlı fölött.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. vagy nem megmutatja. hogy a TabControl engedélyezett.

átmozgatható-e A vezérlı láthatósági szintjét jelöli Meghatározza. 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.ItemSize Meghatározza a vezérlı al-ablakainak méretét MultiLine Meghatározza. hogy csak egy. 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 a vezérlıknek kapcsolódnia kell-e a pozícionáló rácshoz Horgony. hogy látszódnak-e a lapokhoz tartozó ToolTip-ek. hogy . hogy a vezérı átméretezhetı. 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 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 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.

191/312 .DrawItem HelpRequested SelectedIndexChanged StyleChanged SystemColorsChanged akkor következik be. idıt. és egy lenyíló naptár. amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. azaz újabb elem kerül kijelölésre jelzi. Két részbıl áll: egy szövegbeviteli doboz. 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. 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. mely megegyezik a MonthCalendar komponens kinézetével és használatával. 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. 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. Amíg a jelölınégyzet nincs 192/312 CustomFormat DropDownAlign Format MaxDate MinDate ShowCheckBox . nap) Idı (óra. nap) Rövid dátum (év. ezeknél kisebb vagy nagyobb dátumot nem lehet beírni. hónap neve. melyek határt szabhatnak a bevitelre.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. ellenırizhetı. Beállíthatunk két dátumot (minimum és maximum). hogy szerepeljen-e egy jelölınégyzet a komponensen. 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. 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. hónap száma. 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.

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

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

Ezek lehetnek egyedi dátumok. 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.31. A hét kezdı napja is megváltoztatható: Angliában a hét vasárnappal kezdıdik. Alapértelmezés szerint az aktuális nap a naptárban pirossal be van karikázva. és fel van tüntetve a rács alatt is.A komponens kinézete változtatható. A rács mellett megjeleníthetjük a hetek számait is. Bizonyos dátumokat megjelölhetünk félkövér írásmóddal. …) Itt állítjuk be az elérhetı legkésıbbi dátumot a naptárban Alapértelmezés: 9998.01.01. Egy tulajdonság megváltoztatásával akár több naptár is lehet egymás mellett vagy alatt.12. 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. évenkénti vagy havi dátumok. 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. Tartalma a havonta elıforduló fontos dátumok FirstDayOfWeek MaxDate MaxSelectionCount MinDate MonthlyBoldedDates 195/312 . nálunk hétfıvel. Height=1 A hét kezdı napja Alapértelmezés: Default.

13).: 2004. mely DateTime objektumokból áll. AnnuallyBoldedDates és MonthlyBoldedDates) tárolhatja ezeket az egyedi. 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 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. DateTime NyariSzunetVege = new DateTime(2004. hogy látható-e az aktuális dátum a komponens alján Alapértelmezés: True Beállítja.05. Hogyan lehet hozzáadni vagy elvenni ezek közül? Dátum hozzáadás: 1. 9. havonta vagy évente elıforduló dátumokat. kiemelten szerepeltethetünk a naptárban. Hozzunk létre DateTime objektumot: DateTime NyariSzunetKezdete = new DateTime(2004. 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.06. Három tulajdonság (BoldedDates. 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. 196/312 . 1). 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.ScrollChange SelectionRange ShowToday ShowTodayCircle ShowWeekNumbers TitleBackColor TitleForeColor TodayDate TrailingForeColor DateTime[] tömb Ez a változó állítja be. 7. hogy a komponens bekarikázza-e az aktuális napot a naptárban Alapértelmezés: True Beállítja. Ezek a tulajdonságok tartalmaznak egy tömböt.

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

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

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

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

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

ClientSize = New Size(xSize.CenterImage. ClientSize: A betöltött kép méreteit állíthatjuk be. Timer komponens A timer komponens egy eseményt idéz elı rendszeres idıközönként. ySize). akkor kerül aktivizálásra a SizeModeChanged esemény. Nincs lehetıség a timer szüneteltetésére. a Size.pictureBox1. visszaáll alaphelyzetbe. a Tick esemény minden egyes alkalommal bekövetkezik.Normal. pictureBox1.CenterImage: a betöltött kép a komponens területének közepére igazodva jelenik meg pictureBox1. A timer-t elindíthatjuk vagy leállíthatjuk. .SizeMode = PictureBoxSizeMode.Normal: alaphelyzet.SizeMode = PictureBoxSizeMode. Ha a timer engedélyezve van. . ha eltelt a megadott intervallum.SizeMode = PictureBoxSizeMode.Width és Size. 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 . Az idıtartam az Interval tulajdonságban van megadva ezredmásodpercben.StretchImage.Height property-kel adhatjuk meg a kép szélességét és magasságát. Ha megszakítjuk. ilyenkor a kép a komponens bal felsı sarkához lesz igazítva pictureBox1.

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

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

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

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

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

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

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

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

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

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

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

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

hogy belépjen és szerkessze a szöveget. A szöveget kijelölhetjük közvetlenül a komponensben. mint egy mezei TextBox komponens. 215/312 . vagy egy egyszerő text fájlból.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. 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. egymástól különbözı formátumot is engedélyez. Észerevételek: A RichTextBox komponens megengedi a felhasználónak. ami mellett még több. 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ú.

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

RichTextBoxStreamType. 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.Add(richTextBox1).Bold). } 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.richTextBox1. 12. FontStyle.rtf".RichText). this.SelectionColor = Color.Controls. 217/312 . richTextBox1.SaveFile("C:\\MyDocument.Red.SelectionFont = new Font("Verdana". richTextBox1. 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….

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

Végezetül. a RemoveAll függvényt használjuk. } Tulajdonságok: Active AutomaticDelay AutoPopDelay Megadja vagy beállítja a kijelezendı értéket.button1. toolTip1. ToolTip toolTip1 = new ToolTip(). InitialDelay.SetToolTip(this. toolTip1. toolTip1.AutoPopDelay = 5000. System. toolTip1.használjuk a GetToolTip függvényt. és ReshowDelay-el. a példabeli megoldás összeköti a ToolTip szöveget két komponenssel a Formon.checkBox1. 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. A kód ezután initalizál késleltetı tulajdonságokat az AutoPopDelay. private void Form1_Load(object sender. toolTip1. ami nincs engedélyezve. egy Button-al és egy CheckBox-al. // Set up the delays for the ToolTip. hogy a ToolTip szövegek mindaddig megjelenjenek. amíg várnia kell a szöveg felvillantásakor. "My button1"). Ha törölni akarjuk az összes ToolTip szöveget. "My checkBox1").ShowAlways = true. toolTip1.ReshowDelay = 500. amíg a Form fut. 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.EventArgs e) { // Create the ToolTip and associate with the Form container. 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 . Megjegyzés: A ToolTip szöveg olyan komponens fölé nem íródik ki.InitialDelay = 1000. amíg a Tooltip aktív.SetToolTip(this. Automatikus késleltetés beállítása Itt állíthatjuk be azt az idıt amíg a szöveg jelen legyen.A ShowAlways tulajdonság igazra állításával tudjuk beállítani.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

private void button1_Click(object sender. hibaüzeneteket generálni.Font=fontDialog1. melyen a felhasználói beállítások elvégezhetıek. egy fontDialog-ot és egy nyomógombot (button)! 234/312 . majd a megfelelı komponens fontkészletéhez hozzárendelhetjük a felhasználó választásának eredményét.EventArgs e) { fontDialog1. A dialógusok megtalálhatóak a komponens palettán. } 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.Font. vagy beállításokat. listBox1. mivel segítségükkel tudunk a felhasználóval kommunikálni. 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. valamely megfelelı osztályból történı származtatással is.Dialógusok A különbözı párbeszéd ablakoknak. System. vagyis a kívánt font típust.ShowDialog(). de elı lehet állítani ıket dinamikusan. dialógusoknak fontos szerepe van a Windows alatt futó programok készítésénél. paramétereket kérni tıle. helyezzünk a Form-ra egy listBox-ot. Amennyiben programot szeretnénk készíteni a fontDialog komponens kipróbálására.

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. Színek kiválasztása Font megváltoztatása colorDialog fontDialog Nyomtatási kép printDialog Fájl megnyitása openFileDialog 235/312 . 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.A listBox Items tulajdonságánál gépeljünk tetszıleges szöveget a listBox-ba. Az alábbi táblázatban összefoglaltuk a fontosabbakat. mivel a nyomógombhoz tartozó függvényt a .

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

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

hogy meghívjuk a showDialog() függvényüket. Csak annyi a dolgunk velük. s támogatják a fájlkezeléshez szükséges metódusokkal. Ez a két komponens is könnyen használható. A következı forráskód részlet bemutatja a MsgBox használatát: MessageBox. melynek metódusaival különbözı párbeszéd paneleket tudunk megjeleníteni a képernyın. 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é. segítve ezzel a kommunikációt a felhasználóval. 238/312 . majd a kiválasztott fájlt (fájlokat) a megfelelı metódusok segítségével elmentjük. vagy éppen betöltjük. MessageBox Fontos még megemlíteni a MessageBox osztályt is.Show("Üzenetablak komponens futás közben").

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

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

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

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

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

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

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 . Síkbeli és térbeli objektumok modellezése. hanem számtalan alkalmazási területe van a grafikus adatok feldolgozásának is. hogy az alkalmazások milyen feladatcsoportot ölelnek fel és a használt módszerekben milyen összefüggések találhatók. hogy a számítógépi grafika témakörébe tartozó alkalmazásokat csoportosítsuk. Mintafelismerés: Képekbıl meghatározott információk kiolvasása. • • • 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. képek elıállítása. leírások és adtok elıállítása. nem teljesen elkülönülı fıterületet ölel fel: • Generatív grafikus adatfeldolgozás: képek és grafikus adatok bevitele. A következı felsorolásban kísérletet teszünk arra.A grafikus szoftver A számítógépi grafika (Computer Graphics) természetesen képekkel foglalkozik. 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. 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. • • • • • • • • • 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). manipulálása és rajzolása leírások alapján. Grafikus képek tárolása a számítógépen és adathordozókon kódolt formában.

amelyek egy része az operációs rendszerhez kötött.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 . Számos grafikus könyvtár létezik. más része független.

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

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

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

PaintEventArgs e) { Graphics g= e.LinearGradientBrush myBrush = new System. System.FillEllipse(myBrush. mint pl.300.Windows. System.150). } Antialising támogatás A GDI+ lehetıséget biztosít a szépséghibák javítása. a lépcsıhatás.Graphics. lépcsızetes színátmenet.10.Color.Drawing.ForwardDiagonal).Drawing2D.LinearGradientMode.Drawing2D.Drawing.A GDI+ újdonságai Gazdagabb színkezelés és színátmenetek lehetısége Gradient Brushes. System.Color.azaz. 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 .Forms. g. 10.Red.Blue.Drawing.Drawing2D.LinearGradientBrush( ClientRectangle.

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

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

PaintEventArgs e) { Graphics myGraphics= e.FillRectangle(myBrush3. myGraphics. System.100.Drawing. 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 . myGraphics.jpg").100. 255)).FromArgb(128.SolidBrush myBrush2 = new SolidBrush(Color. //félig látszik át System.FillRectangle(myBrush2.50. Ha egy kép minden pixeléhez rendeltek alfa-értéket.SolidBrush myBrush3 = new SolidBrush(Color.100).Forms.FromArgb(32.50.300.TextureBrush myBrush0 = new TextureBrush(myBitmap).100).FillEllipse( myBrush0.50.150).100). 0.Graphics.10.Drawing.50. } Nem látszik át.Drawing. //Szinte teljesen átlátszik System. bittérképes (Bitmap) és metafile-ok kezelésére. 255)). // nem látszik át System. 255)).100. 0.50.SolidBrush myBrush1 = new SolidBrush(Color. akkor beszélünk alfa-csatornáról. 0. Tekintsünk egy példát: private void Form1_Paint(object sender. myGraphics. 0. myGraphics.0. System.FromArgb(255.általában 0 és 1 között van. félig látszik át.300.Drawing.Windows.FillRectangle(myBrush1. 0.155. és két kép keverésének arányát határozza meg. Bitmap myBitmap = new Bitmap("navaho. 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).

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

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

1). ugyanez a GDI+ -ban: private void Form1_Paint(object sender. 50.0F. 250. Más programozási nyelvek grafikus könyvtáraiban szokás az ellipszist középpontjával. 3).Graphics.Cross. e. és hosszúságát (left.FillRectangle(myHatchBrush. myGraphics.Windows. 0.top.DrawRectangle(myPen.FromArgb(255.y. float top = y-b.left. // Átalakítás a GDI+ szerint float left = x-a. HatchBrush myHatchBrush = new HatchBrush( HatchStyle.Graphics. float a = 200. Teljesen hasonlóan járunk el az DrawEllipse és a FillEllipse metódusok használatakor is. 256/312 . Pen myPen = new Pen(Color. Color. 50. és tengelyei float x = 300. 3). 30).0F. 255. width és height).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. width. } 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. Tekintsünk egy példát: private void myFillexample(PaintEventArgs e) { Graphics myGraphics=e. Pen redPen= new Pen(Color. e. A DrawRectangle metódus a Pen objektummal. //Az ellipszis középpontja. 0.FromArgb(255.x. s a téglalap szélességét. float b = 100. 255)).PaintEventArgs e) { Pen blackPen= new Pen(Color.Forms. myGraphics.DrawLine(blackPen.0F.a. float y = 150. height). Color.b). 0. float width = 2*a.DrawEllipse(redPen. valamint a kis és nagy tengelyével megadni: Ellipse(x. 100.FromArgb(255.Red. top. float height = 2*b.x.y. 0.0F. 0). 100. 0). 100. System.Black.y-b). 255. a FillRectangle metódus pedig a Brush objektummal használhatjuk. 30).Graphics.

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

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

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

amely nincs benne az elsı régióban (komplementer képzés). 260/312 .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.

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

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

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.

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

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

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

0f).Cos(alpha). egy téglalapot érintı ellipszisen. 273/312 .0f.Cos(alpha).0f.0f. 1. majd a Graphics. Matrix myMatrix1 = new Matrix(2. 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.(float)Math.PI/180. 0.0f. 0. 0.Blue.Sin(alpha). // Mátrixok inicializálása: // Skálázás. 1).0f. // Elforgatás 30 fokkal.Multiply metódussal. // Eltolás. 0.Sin(alpha). double alpha=30*Math.Transform metódussal végrehajtjuk a transzformációt a Graphics objektumain. 0. 1).0f. Matrix myMatrix2 = new Matrix( (float)Math. Pen myPen2 = new Pen(Color.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. A Multiply metódus MatrixOrder paramétere határozza meg a mátrix szorzás sorrendjét.0f). 0.Red.(float)Math.

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

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

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

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.0). Az x tengely irányú ShearX=k mértékő nyírás • Nyírás az x tengely irányában: myMatrix. A Shear metódus két paramétere közül érdemes az egyiket nullának választani.Shear(ShearX. hogy x vagy y tengely irányában nyírunk. • Nyírás az y tengely irányában: 277/312 . attól függıen.Shear(k. myMatrix. különben elıre nehezen meghatározható hatást érünk el.ShearY).

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

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

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.

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

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

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

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

286/312 .

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

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

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

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

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

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

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

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

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

Így itt is használható a rendezés. operátor és egy érték a szőréshez. „ LastName = ’Smith’ ” Rendezés a DataViewban A rendezéshez létre kell hoznunk egy string kifejezést.Az alapértelmezett nézet A DataTable.RowFilter tuljdonsága adhatunk meg egy szőrı feltételt a sorok megjelenítéséhez a DataViewban.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. „Price DESC. a A RowFilter tulajdonság A DataView. és milyen irányban. szőrés és keresés a táblában. A szőrıkifejezés felépítése: egy oszlopnév. melyben megadhatjuk.

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

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

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

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

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

4E+38 és 3.3647 közötti tartományban a pénzegység egy tízezrelékének pontosságával Float Lebegıpontos érték –1. 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. olyan SQL utasításokat tartalmazó programokat írhatunk. amelyekben a szokványos programozási szerkezetek is megtalálhatók (változók.3648 és 214748. A T-SQL segítségével. eljárások és függvények). amely programozási szerkezetekkel egészíti ki a nyelvet.79E+308 és 1. használatba vételük.Tárolt eljárások Tárolt eljárások futtatása. új tárolt eljárások készítése.79E+308 között Real Lebegıpontos érték –3. ciklusok. rögzítése adatbázisban. A nevét gyakran rövidítik T-SQL –re. Mi is az a Transact-SQL? A Transact-SQL a Microsoft SQL megvalósítása. 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.4E+38 között 302/312 . feltételes szerkezetek.

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

A WHILE ciklusok addig futnak. Az utasításforma a következı: DECLARE @count int SET @count = 5 WHILE(@count>0) BEGIN PRINT ’count = ’ + CONVERT(nvarchar. amíg a megadott feltétel igaz. akkor WHILE ciklusokat használhatunk. @count) SET @count = @count -1 END 304/312 .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.

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful