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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

de nem javasolt – karakterkészlet és kódlap függı forráskódot eredményez. Hová írjuk az eljárásainkat? Az Objektum Orientált programozás elvei szerint a programok építıkövei az osztályok. betővel. 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.Természetesen van rá lehetıség. függvényeket. 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ó. Az osztály (class) mintegy csoportba foglalja az egy témakörbe. hogy ne csak a Main()-bıl hívjunk eljárásokat. feladatkörbe tartozó eljárásokat. E miatt a program felépítése a következı lehet: 129/312 . számjeggyel. 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. e miatt másik gépen másik programozó által nehezen elolvashatóvá válik a forráskód.

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

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

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

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

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

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

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

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

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

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

137/312

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

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

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

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

138/312

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

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

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

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

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

139/312

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

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

140/312

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

141/312

Programozás tankönyv

XIII. Fejezet

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

142/312

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

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

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

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

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

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

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

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

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

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

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

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

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.ref tomb[j]).Length. A fenti eljárás kitőnıen felhasználható egy rendezı eljárásban: static void Rendezes(int[] tomb) { for(int i=0. Mivel ilyenkor érdekes a paraméterek aktuális értéke is.i<tomb. } 155/312 .j++) if (tomb[i]>tomb[j]) Csere(ref tomb[i].j<tomb.i++) for(int j=i+1.Length-1.

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

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

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

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

A fontosabbakat az alábbi táblázatban foglaltuk össze.) A következı példa bemutatja.ar). függetlenül az elıtte keletkezett hibáktól. } catch (ArithmeticException ar) { Console. Tipikus példa erre a fájlkezelés. vagy alulindexelése Érvénytelen típus átalakítás A keletkezet érték nem véges (hibás számalak) Null értékre való hivatkozás Nem támogatott tagfüggvény Elfogyott a memória Túlcsordulás (checked esetén) Verem túlcsordulás Hibás típus beállíás (static kontruktornál) A finally blokk Sokszor lehet szükség arra is. (Nem igaz ez arra az esetre. ha a program végzetes hibával áll le. hogy egy program részlet hibás és hibátlan mőködés esetén is lefusson. hogyan alkalmazhatjuk a nyelv finally kulcsszavát: int a=0. try { c=10/a.A System névtérben rengeteg kivétel típust definiáltak. Az ilyen típusú problémákra nyújt megoldást a finally kulcsszó. double c. ahol a megnyitott fájlt hiba esetén is le kell zárni. } 160/312 .WriteLine("Aritmetikai hiba : {0}". 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. A finally blokkban elhelyezett kód mindig lefut.

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

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

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

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

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

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

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

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

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

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

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. Az imagelistben megadott képnek az indexe A gomb a bal felsı saroktól való 171/312 . a kontrollok Button (Gomb) A nyomógomb komponens által a felhasználó mőveletet hajthat végre. 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.A látható komponensek. vagy megszakíthat egy folyamatot. Például elindíthat. vagy tiltja a drag and drop funkciót.

Locked Modifiers Size TabStop TabIndex Text TextAlign Visible Események: Click Enter GotFocus Keypress. 172/312 . amihez a felhasználó nem fér hozzá.y formában Gomb lezárása A gomb hozzáférésének a lehetıségei: public. Linklabel A label szöveget jelenít meg. 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. KeyDown KeyUp Leave MouseEnter MouseLeave ParentChanged távolsága x. protected. protected internal.

vagy tiltja a drag and drop funkciót.y formában A címke mérete A címke felirata Látható-e Az aktivált link színe A link stílusa amikor a mutató fölötte van A link színe Volt-e már megnézve? Megnézett link színe Textbox A textbox egy olyan területet jelöl ki. ahol a felhasználó általában egysoros szöveget adhat meg.Közös tulajdonságok: Name AllowDrop Anchor BackColor BackgroundImage Enabled Font ForeColor ImageList ImageIndex Location Size Text Visible Linklabel tulajdonságai: ActiveLinkColor LinkBehavior LinkColor LinkVisibled VisitedLinkColor Név Engedélyezi. 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. 173/312 . Az imagelistben megadott kép indexe A gombnak a bal felsı saroktól mért távolsága x.

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

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

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

akkor használjuk a CloneMenu metódust. ami egy másolatot készít. ami a menüelem szövegét jobbról balra jeleníti meg. 177/312 . Egy formhoz lehet készíteni több MainMenut is ha több menüstruktúrát szeretnénk megvalósítani. Amikor kész van a másolat.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. akkor el lehet végezni a megfelelı módosításokat az új menüstruktúrán.

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

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

vagy nem true.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. 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. hogy a vezérlı fogadhate „Fogd-és-vidd” értesítéseket helyi menü. ha a listarészlet csak teljes elemeket tartalmazhat. betőszín) a vezérlıben látható szöveg DropDownStyle Font ForeColor Text Viselkedés AllowDrop ContextMenu meghatározza. hogy a vezérlı tartalma 180/312 DrawMode DropDownWidth Enabled IntegralHeight ItemHeight MaxDropDownItems MaxLength Sorted . hogy a ComboBox engedélyezett. 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. ami megjelenik a vezérlı fölött. 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.

a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja.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. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. 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. mezıje. amikor egy 181/312 . amikor egy bizonyos elemet vagy területet meg kell rajzolni DropDown azt jelzi. hogy a vezérlı átméretezhetı. hogy az elem kiválasztható-e a TAB billentyő használatával a vezérlı látható vagy nem Items Tag a listát jelöli. hogy a ComboBox menüje legördült DropDownStyleChanged jelzi. 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. amit a comboboxban meg kívánunk jeleníteni Collection. 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.

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

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

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

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

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

amikor a felhasználó elkezd „vonszolni”egy elemet akkor következik be. 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. hogy a vezérlıben megjelenhetnek-e gördítısávok. 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. 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. 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. a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. átmozgatható-e A vezérlı láthatósági szintjét jelöli Horgony. hogy a vezérı átméretezhetı.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. 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.

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

hogy a fejlécelemek vizuálisan megváltozzanak-e. hogy a vezérlı fogadhat-e „Fogdés-vidd” értesítéseket megjelenési beállítások helyi menü. 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. 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. ami megjelenik a vezérlı fölött. hogy a TabControl engedélyezett.TabControl Feladata: lapok összefüggı halmazát alkotja Megjelenés Cursor Font ImageList Megjelenés Alignment AllowDrop Appearance ContextMenu a kurzor típusa. amikor az egérmutató föléjük ér 189/312 . vagy nem megmutatja.

hogy a vezérlı mely szélei vannak összekapcsolva az ıt tartalmazó elem szélével Beállítja vagy lekérdezi a vezérlı bal felsı sarkának az ıt tartalmazó elem bal felsı sarkától mért relatív távolságát A vezérlı mérete pixelben A lapok a TabControlban Anchor Dock Location Size TabPages Események Click DoubleClick kattintáshoz kötıdı esemény Dupla kattintáshoz kapcsolódó esemény 190/312 . 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. á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. hogy . a vezérlı mely szélei rögzítettek az ıt tartalmazó konténer széleihez képest megmutatja. hogy látszódnak-e a lapokhoz tartozó ToolTip-ek. 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 a vezérlıknek kapcsolódnia kell-e a pozícionáló rácshoz Horgony. vagy vagy több fül is lehet a vezérlın belül Padding meghatározza.mennyi extra hely legyen a vezérlı „fülei” körül ShowToolTips Meghatározza. hogy a pozícionáló rács kirajzolásra kerüljön-e meghatározza a pozícionáló rács méretét megmutatja. hogy a vezérı átméretezhetı.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

A szöveget kijelölhetjük közvetlenül a komponensben. hogy belépjen és szerkessze a szöveget. mint egy mezei TextBox komponens. Észerevételek: A RichTextBox komponens megengedi a felhasználónak.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. A komponensen belüli szöveg lehet egyszerő karakteres vagy paragraph formátumú. vagy egy egyszerő text fájlból. vagy be tölthetjük egy Rich Text Format (RTF) fájlból. Itt lehet a képeket az ImageListhez főzni Képméret beállítása Beállíthatjuk a fogantyút az ImageListStreamerhez összekapcsolva az aktuális kép listával Beállítja az Isitetot a komponenshez Szináttetszıség beállítása Site TransparentColor RichTextBox Reprezentál egy Windows rich text box komponenst. egymástól különbözı formátumot is engedélyez. ami mellett még több. 215/312 .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.A listBox Items tulajdonságánál gépeljünk tetszıleges szöveget a listBox-ba.NET elhelyezi a kódban!) A futtatáskor a következı kimenet látható: Az C# nyelv vizuális részében található többi dialógus is hasonló módon mőködik. 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 .

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

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

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

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

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

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

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

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

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

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

Számos grafikus könyvtár létezik. A továbbiakban a C#-hoz kapcsolódó Ms-Windows GDI+ lehetıségeit tárgyaljuk 246/312 . 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. amelyek egy része az operációs rendszerhez kötött.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. Zárt görbék különbözı t értékeknél 269/312 .

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

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

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

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

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

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

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

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.ShearY).0). myMatrix.Shear(ShearX. attól függıen. különben elıre nehezen meghatározható hatást érünk el. 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 . A Shear metódus két paramétere közül érdemes az egyiket nullának választani.

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

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

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

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

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

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

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

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

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful