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 .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

137/312

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

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

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

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

138/312

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

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

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

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

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

139/312

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

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

140/312

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

141/312

Programozás tankönyv

XIII. Fejezet

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

142/312

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

amihez a felhasználó nem fér hozzá. Linklabel A label szöveget jelenít meg. private. 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. protected internal. protected.y formában Gomb lezárása A gomb hozzáférésének a lehetıségei: public. KeyDown KeyUp Leave MouseEnter MouseLeave ParentChanged távolsága x.

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

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

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

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

ami egy másolatot készít. 177/312 . 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. Ha újra akarjuk használni a MinMenut egy speciális menüstruktúrában. mint az arab nyelv írásakor. ami a menüelem szövegét jobbról balra jeleníti meg. Amikor kész van a másolat. akkor el lehet végezni a megfelelı módosításokat az új menüstruktúrán.

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

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

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

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. 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. hogy a vezérlı átméretezhetı. amikor egy 181/312 . amikor egy bizonyos elemet vagy területet meg kell rajzolni DropDown azt jelzi.TabIndex TabStop Visible Adat DataSource DisplayMember rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja. ahonnan a vezérlı az elemeit veszi az adatforrás egy tulajdonsága. 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. amit a comboboxban meg kívánunk jeleníteni Collection. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. hogy a DropDownStyle tulajdonság megváltozott HelpRequested A felhasználó segítséget kér a vezérlırıl MeasureItem akkor következik be. hogy a ComboBox menüje legördült DropDownStyleChanged jelzi. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony.

a lista lenyitható. akkor a SelectedIndex tulajdonságot használjuk. Ha az indexére van szükségünk. (alapértelmezett) Nem szerkeszthetı a mezı. Így kezelése a szokásos metódusok használatával lehetséges. a lista lenyitható A listához hasonlóan a comboboxban is az Items tulajdonság tárolja a lista elemeit. amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. Count Add Insert Remove Indexer. azaz újabb elem kerül kijelölésre jelzi. 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ı. ami egy objektumot ad vissza. ha megváltozott a vezérlı stílusa bekövetkezik. a lista mindig látszik Szerkeszthetı mezı. az elemek számát adja vissza Új elem felvétele a listához Új elem beszúrása a listába Elem törlése A felhasználó által kiválasztott elemet a SelectedItem tulajdonságon keresztül érjük el. Ez a tulajdonság egy ObjectCollection típus. 182/312 .SelectedIndexChanged StyleChanged SystemColorsChanged bizonyos elem magasságát ki kell számítani akkor következik be.

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

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

azaz újabb elem kerül kijelölésre jelzi. amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik.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. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. amikor a rendszerszínek megváltoznak AfterLabelEdit AfterLabelEdit HelpRequested ItemCheck SelectedIndexChanged StyleChanged SystemColorsChanged A következı események mindegyike egy tulajdonság megváltozását jelzik: BackColorChanged ContextMenuChanged CursorChanged DockChanged EnabledChanged FontChanged ForeColorChanged LocationChanged ParentChanged SizeChanged TabIndexChanged TabStopChanged VisibleChanged háttérszín helyzetérzékeny menü kurzor igazítás engedélyezettségi állapot betőtípus elıtérszín (betőszín) helyzet (Lásd Location) szülı méret tab-sorrendbeli hely TAB-bal történı kiválaszthatóság vizuális láthatóság 185/312 . hogy a vezérı átméretezhetı. 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. ha megváltozott a vezérlı stílusa bekövetkezik. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony.

hogy a vezérlı kijelölt elemén megmarad-e a kijelölés. ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg azt jelzi. ami megjelenik a vezérlı fölött. 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 egy elemen történı kattintás kijelöli-e az elem összes al-elemét is azt jelöli. 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ı 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. vagy nem Megmutatja. hogy az elemek hyperlink-stílusúvá váljanak-e. 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. amelybıl a csomópontokhoz tartozó képek származnak 186/312 . betőszín) a TreeView egy elemének magassága pixelben meghatározza. hogy a combobox engedélyezett. amikor a vezérlı elveszíti a fókuszt megmutatja. hogy megjelennek-e CheckBoxok az elemek mellett a kurzor típusa.

hogy a vezérlıben megjelenhetnek-e gördítısávok. 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. á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. amikor a kijelölés megváltozik A vezérlı neve megmutatja. hogy az elem kiválasztható-e a TAB billentyő használatával a vezérlı látható vagy nem Tag: Teszıleges célokra használható egész értékő mezı Tervezés Name Locked Modifiers Anchor Dock Location Size Események Click DoubleClick ItemDrag AfterCheck AfterCollapse AfterExpand AfterLabelEdit AfterSelect kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény akkor következik be. amikor a 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. amikor a felhasználó elkezd „vonszolni”egy elemet akkor következik be. hogy a vezérı átméretezhetı. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest 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 187/312 . hogy a vezérlı tartalma rendezett vagy sem az elem helyét adja meg a TAB sorrendben megmutatja.

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 . 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.BeforeCheck BeforeCollapse BeforeExpand BeforeLabelEdit BeforeSelect HelpRequested StyleChanged SystemColorsChanged kiváltódik.

amikor az egérkurzort fölé mozgatjuk szöveg megjelenítésére használt betőtípus a TabControlhoz DrawMode Enabled HotTrack megmutatja a fülek hol helyezkednek el a TabControlon belül jelzi. hogy a vezérlı fogadhat-e „Fogdés-vidd” értesítéseket megjelenési beállítások helyi menü. vagy nem megmutatja. 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. hogy a TabControl engedélyezett. amikor az egérmutató föléjük ér 189/312 . ami a vezérlın jobb egérgombbal történı kattintásra jelenik meg A TabControl megrajzolási módját vezérli azt jelzi. hogy a fejlécelemek vizuálisan megváltozzanak-e.

mennyi extra hely legyen a vezérlı „fülei” körül ShowToolTips Meghatározza. hogy csak egy. 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. hogy látszódnak-e a lapokhoz tartozó ToolTip-ek. hogy . hogy a vezérı átméretezhetı. hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát A vezérlı mérete pixelben A lapok a TabControlban Anchor Dock Location Size TabPages Események Click DoubleClick kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény 190/312 . hogy a vezérlıknek kapcsolódnia kell-e a pozícionáló rácshoz Horgony. 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. átmozgatható-e A vezérlı láthatósági szintjét jelöli Meghatározza.ItemSize Meghatározza a vezérlı al-ablakainak méretét MultiLine Meghatározza. SizeMode az egyes lapok méretezési módját állítja be TabIndex az elem helyét adja meg a TAB sorrendben TabStop megmutatja. vagy vagy több fül is lehet a vezérlın belül Padding meghatározza. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja.

idıt. Két részbıl áll: egy szövegbeviteli doboz. 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. és egy lenyíló naptár. mely a dátumot/idıt tartalmazza szöveges formában. azaz újabb elem kerül kijelölésre jelzi. mely megegyezik a MonthCalendar komponens kinézetével és használatával. amikor a ComboBox ’SelectedIndex’ tulajdonsága megváltozik. 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. ha megváltozott a vezérlı stílusa bekövetkezik.DrawItem HelpRequested SelectedIndexChanged StyleChanged SystemColorsChanged akkor következik be. 191/312 .

ezeknél kisebb vagy nagyobb dátumot nem lehet beírni. nap) Idı (óra. nap) Rövid dátum (év. ellenırizhetı. 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. melyek határt szabhatnak a bevitelre. hónap neve. A kívánt értékeket négyféle formátumban képes a komponens megjeleníteni: Hosszú dátum (év.A lenyíló naptár helyett használhatjuk a komponenst görgetıkkel is (a lenyitó gomb helyett fel-le gombok jelennek meg) a ShowUpDown tulajdonság igazra állításával. Amíg a jelölınégyzet nincs 192/312 CustomFormat DropDownAlign Format MaxDate MinDate ShowCheckBox . hogy szerepeljen-e egy jelölınégyzet a komponensen. 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. 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. Választhatunk a beépített formátumok közül vagy lehet egyedi Long/Short/Time/Custom A legkésıbbi beírható dátum A legkorábbi beírható dátum Meghatározza. hónap száma. Beállíthatunk két dátumot (minimum és maximum).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

263/312

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

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

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

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

264/312

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

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

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

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

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

és

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

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

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

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

266/312

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

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

267/312

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

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

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

268/312

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

286/312 .

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

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

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

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

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

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

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

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

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

melyben megadhatjuk. Title ASC” Egy táblához több nézet 296/312 .Az alapértelmezett nézet A DataTable. a A RowFilter tulajdonság A DataView. 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. A szőrıkifejezés felépítése: egy oszlopnév. és milyen irányban.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. hogy mely oszlopok szerint szeretnénk rendezni a sorokat. „Price DESC. szőrés és keresés a táblában. Így itt is használható a rendezés.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful