CSORDÁS JÁNOS: A PROGRAMOZÁS ALAPJAI VISUAL BASIC-BEN Tartalom I. Bevezetés... 2 II. Programozási alapok... 2 1. Az első lépések... 2 2. Névterek... 3 3. Eljárások (alprogramok)... 4 4. Változók... 5 4.1 A változók elmélete... 5 4.2 Változó típusok... 6 4.3 Példák változók felhasználásával... 6 4.4 Az egydimenziós tömb... 6 4.5 A kétdimenziós tömb... 7 5. Elágazások (szelekciók) a programban... 8 6. Ciklusok (iterációk) a programban... 9 7. Matematikai műveletek a programban... 10 III. Programozás haladó(bb) szinten... 11 1. Adatbeolvasás szöveges fájlból... 11 2. Szöveges fájlok feldarabolása... 12 3. Adatbeolvasás, Split(), kétdimenziós tömb 3 az 1-ben, egészségére!... 15 IV. Az érettségi feladat megoldása beszéljenek a kódok!... 18 Szöveges fájl beolvasása kétdimenziós tömbbe a beolvas() eljárás... 18 1. feladat a feladat1() eljárás... 18 2. feladat a feladat2() eljárás... 18 3. feladat a feladat3() eljárás... 20 4. feladat a feladat4() eljárás... 20 1
I. Bevezetés Oldjuk meg a 2005. májusi érettségi vizsga programozási feladatának első részét (1-6 feladatok). Egy szöveges fájlban (lottosz.dat) 51 hét ötös lottó számai találhatóak. Az első sorban az első héten húzott számok vannak, szóközzel elválasztva, a második sorban a második hét lottószámai vannak stb. A szöveges fájl első négy és utolsó sorának adatai: 2 Megjegyzések: 37 42 44 61 62 18 42 54 83 89 5 12 31 53 60 1 28 47 56 70 9 20 21 59 68 - a lottószámok minden sorban emelkedő számsorrendben szerepelnek - a szöveges fájlt ki kell majd egészítenünk egy 52. sorral (89 24 34 11 64) - a szöveges fájlban található legkisebb szám 1, a legnagyobb pedig 90, mivel a lottószelvényeken 90 szám közül 5 számot kell a fogadónak megjelölnie egy-egy fogadás alkalmával Az első lépés az, hogy a szöveges fájlt valamilyen formában elérhetővé tegyük a Visual Basic számára. II. Programozási alapok 1. Az első lépések A Visual Basic indítása után két választási lehetőségünk van: New Project, illetve Open Project. Természetesen az előbbire van szükségünk. A New Project ablakában többféle programtípus közül választhatunk. Nekünk minden esetben a Console Application-ra van szükségünk. A lehetőség kiválasztása után adjunk nevet a project-nek, majd kattintsunk az OK gombra. A megjelenő ablakban az alábbi kódrészletet látjuk: A Sub Main() a főprogram eleje, az End Sub a főprogram vége. A program futtatásakor a főprogramban található utasítások kerülnek végrehajtásra egymás után. A legalapvetőbb utasítás a képernyőre való kiírás utasítása. Ez a Console.Write() és a Console.WriteLine(). A kettő között az a különbség, hogy a Console.WriteLine() miután a képernyőn megjeleníti a zárójelben található szöveget, a sor végén egy sortörést is elhelyez. A jobb oldalon látható program kimenete: HelloWorld!:-). Amennyiben Console.Write() helyett, Console.WriteLine()-t használunk, a program kimenete a következő lesz: Hello World! :-)
Amennyiben lenne egy harmadik Console.WriteLine() is a programban, annak tartalma a smile alá kerülne. Látható, hogy az utasítások végrehajtása egymás után történik. Ahhoz, hogy a program eredményéből valamit lássunk is, meg kell akadályozni, hogy a Windows az utasítások lefuttatása után bezárja a Console t: 3 A Console.ReadKey() tulajdonképpen arra utasítja, a gépet, hogy egy karakter leütésére várjon. Miután ez megtörtént következik az End Sub, a (fő)program futása véget ér. 2. Névterek A fenti példákban látható, hogy minden utasítás előtt megtalálható a Console bejegyzés. Ennek megadására azért van szükség, mert egyébként nem lenne egyértelmű, hogy hová szeretnénk adatokat írni (Write), illetve honnét szeretnénk adatokat beolvasni (ReadKey). Írhatunk ugyanis a nyomtatóra is, vagy beolvashatunk adatokat az USB portról is. A Console egyértelműen meghatározza, hogy a képernyőre kell a programnak írnia, és általunk a billentyűzet segítségével, a képernyőn megjelenített adatokat kell beolvasnia. Ha csak a monitort szeretnénk használni adatok beolvasására és kiíratására, akkor megtehetjük, hogy a program elején beállítunk egyfajta alapértelmezést (névteret), amely biztosítja, hogy a program futása során, a Console utasítás elhagyása esetén is, egyértelmű legyen, hogy a monitor az alapértelmezett periféria: Az Imports System.Console on kívül hasonló megfontolásból használható a következő két névtér: - Imports System.IO fájlműveleteknél, adatbeolvasásnál, fájlba írásnál - Imports System.Math komplexebb matematikai műveleteknél (Ezekről részletesebben később)
3. Eljárások (alprogramok) Eljárások segítségével a programot kisebb részekre oszthatjuk, ezzel a kód áttekinthetőbb lesz, és jól megírt programok esetén előfordulhat, hogy egy korábban elkészített eljárást egy másik feladat megoldásánál is felhasználhatunk, ezzel pedig időt spórolhatunk. Egy-egy érettségi feladatot egy-egy eljárásban célszerű megoldani. Mi hat feladatot (+1 a beolvasás) fogunk megoldani, így programunk szerkezete valahogy így fog kinézni: 4 Start Kész! Megjegyzések: - az utasítások végrehajtásának logikája nem változott. A Sub Main() nel kezdődik a program, itt rögtön az első utasítás a beolvas() nevű eljárás meghívása. A beolvas() nevű eljárásban található utasítások végrehajtása után a feladat1() eljárás következik. Végül eljutunk a ReadKey()-hez. - a beolvas() nevű eljárásban találunk kettő zöld színű, aposztróffal kezdődő sort. Ezek megjegyzések, a program végrehajtása szempontjából semmiféle jelentőségük sincsen. Arra használjuk őket, hogy emlékeztető szövegeket helyezzünk el a programban. Ha hónapokkal, vagy évekkel később megnyitjuk a project-et, akkor a megjegyzések segíthetnek abban, hogy megértsük mit miért csináltunk. - a programkód bal oldalán csomópontokat találunk ezekben + vagy jeleket. A csomópontok segítségével a program bizonyos részeit elrejthetjük. Ennek hosszú program esetén van külö-
4. Változók nös jelentősége: a már megírt, működő programrészek elrejtésével megakadályozzuk, hogy véletlenül onnét valamit kitöröljünk, vagy oda valamit beírjunk. A program így rövidebbnek fog tűnni, a rövidebb program pedig jobban átlátható. A példafeladatban öt eljárást rejtettünk el. 4.1 A változók elmélete Ha adatokkal szeretnénk dolgozni (azaz mindig ), akkor a programban meg kell teremteni az adatok kezelésének feltételeit. Adatokkal akkor tudunk dolgozni, ha az adatokat változókba (a memória egy meghatározott szegletébe) helyezzük. A változókat egy-egy névvel rendelkező dobozhoz hasonlíthatjuk leginkább. Ahhoz, hogy valamit a dobozba tudjunk helyezni először létre kell hozni a dobozt, létrehozásnál meg kell határozni, hogy mekkora legyen a mérete. Ha kész az adott méretű doboz, akkor az adott tárgyat bele lehet tenni, sőt arra is van lehetőség, hogy a tárgy helyett egy másik tárgyat helyezzünk bele, feltéve, ha belefér. 5 A Visual Basicben is tulajdonképpen így kezeljük az adatokat: - változó (doboz) létrehozása: a változó DEKLARÁLÁSA. A deklarálást a Dim vezeti be. Ezt követően meg kell adnunk a változó nevét (valtozo) majd ez után a változó méretét (Byte), azaz típusát - a változó (doboz) feltöltése: a változó DEFINIÁLÁSA. A deklarálás után közvetlenül a változóba betettünk egy 1-est. - a változó (doboz) tartalmának cseréje szükség esetén: a definiálás után közvetlenül az 1-est 2-esre cseréltük. Ezután érdekes dolgot látunk, a kifejezést jobbról balra kiolvasva: o a változó tartalmához hozzáadunk 2-t. 2+2=4. o az így létrejött számot (4) beletettük a változóba, azaz a 2-es 4-esre cseréljük. Megjegyzések: - a változó neve bármi lehet, azonban lehetőség szerint kerüljük az ékezetes betűket. A változó nevével hivatkozhatunk a programban a változó értékére. Használjunk beszédes neveket! - a változó csak abban az eljárásban él, amelyikben deklaráltunk (ezért is hívjuk lokális változónak). Azaz a fenti példa szerinti (valtozo) csak a Sub Main() ben használható a többi eljárásban nem létezik. Ha olyan változóra van szükség, amely bármelyik eljárásból elérhető, akkor globális változót kell létrehozni. Ez mindössze annyit jelent, hogy eljáráson kívül, a Module Module1 en belül kell deklarálni. - a változó típusa meghatározza, hogy milyen értékeket lehet a változóban tárolni. Eme tény figyelmen kívül hagyása esetén furcsa dolgok történhetnek. Esetek: o szám típusú változóba szöveget próbálunk tenni papírdobozba vizet öntünk: a program hibaüzenettel leáll. Használjunk műanyag dobozt! o szám, konkrétan Byte típusú változóban nagy számot kívánunk tárolni gyufás skatulyába próbálunk elefántot tenni: ún. túlcsordulás lép fel, a program leáll.
4.2 Változó típusok Változók deklarálásánál kell döntenünk arról, hogy a változóban milyen típusú adatokat fogunk tárolni. Gyakori típusok: - Byte: 0-255 közötti szám (a memóriából egy bájtot foglal el) - Integer: -2 147 483 648 és 2 147 483 647 közötti szám (a memóriából négy bájtot foglal el) - Single: amennyiben nem egész számokat kívánunk tárolni. Hatalmas méretű - Char: egy karaktert tárol (a memóriából két bájtot foglal el) - String: szöveg tárolására (a memóriából két bájtot foglal el. Ez azt jelenti, hogy egy ilyen típusú változóba 4 294 967 296 tetszőleges karaktert rögzíthetünk egyszerre) 6 4.3 Példák változók felhasználásával Az előző programot dolgozzuk át egy kicsit!. A változó deklarálása utáni sorban a felhasználó által begépelt értéket beolvassuk a monitorról (ReadLine()), majd elhelyezzük a változóban (valtozo=readline()). Tegyük fel, hogy a felhasználó az 5-öst gépelte be. A program kimenete a következő lesz: valtozo 5 A programban két utasítással írunk ki valamit a képernyőre. Az első WriteLine() a valtozo szót írja a képernyőre, a második pedig a valtozo nevű változó tényleges értékét. Ne keverjük a kettőt! Két megjegyzés: - programunk legyen mindig felhasználóbarát: a felhasználót tájékoztassuk, hogy mi történik, mit várunk tőle - a ReadLine() utasítást a Val() utasítással együtt használjuk számbeolvasás esetén. Az utóbbi ugyanis abban az esetben, ha a felhasználó betűket is begépel, kiszűri a számként nem értelmezhető karaktereket: 4.4 Az egydimenziós tömb Az egydimenziós tömb egy olyan változó, amely doboz helyett inkább egy fiókos szekrényhez hasonló. A deklarálásnál ilyenkor a fiókok számát is meg kell adnunk. A fiókokra, illetve tartalmukra sorszámukkal hivatkozhatunk. Az első fiók sorszáma a 0, az utolsó fiók sorszáma a fiókok száma-1-gyel
egyezik meg. Konkrétan egy 5 fiókos szekrény első fiókja sorszám szerint a 0., az ötödik pedig a 4. Egy egydimenziós tömb deklarálása és a fiókok tartalmának definiálása: A tomb nevű tömb egy ötfiókos szekrény: 1 A 0. fiók tatalma 2 Az 1. fiók taralma 3 A 2. fiók tartalma 4 A 3. fiók tartalma 5 A 4. fiók tartalma A program kiírja az első (0.) és a második (1.) fiók tartalmát szóközzel elválasztva. A WriteLine() utasításban jól látható, hogy egyszerű szöveget (szóköz), miképpen fűzhetünk össze egy-egy változó tartalmával. Az összefűzéshez a & operátort kell használnunk. A & előtt és után egy-egy szóköz kötelező! 7 4.5 A kétdimenziós tömb A kétdimenziós tömb egy olyan változó, amely egy egyszerű fiókos szekrény helyett inkább egy szekrénysorhoz hasonlítható. A kétdimenziós tömb tulajdonképpen egy táblázat, x db sorral, és y db oszloppal rendelkezik. A deklarálásnál ilyenkor a fiókok száma lényegtelen, a sorok (x) és az oszlopok (y) számát kell megadnunk. A fiókokra, illetve tartalmukra a sor- és oszlopszámmal hivatkozhatunk. Az első fiók sorszáma a 0,0, az utolsó fiók sorszáma pedig x-1, y-1. Konkrétan egy 2x2-es szekrény első fiókja sorszám szerint a 0,0, az utolsó pedig az 1,1. Egy kétdimenziós tömb deklarálása és a fiókok tartalmának definiálása: A tomb nevű tömb egy négyfiókos (2x2-es) szekrény: 0,0 fiók 11 21 0,1 fiók 1,0 fiók 13 41 1,1 fiók
5. Elágazások (szelekciók) a programban Elágazások segítségével határozhatjuk meg, hogy adott helyzetben milyen utasítás végrehajtására kerüljön sor: A program bekér egy számot, és ha a felhasználó 1-est üt be, kiír valamit. A kódban látható 8 If (feltételvizsgálat) Then utasítás1 utasítás2 utasítás3 utasításn End if szerkezet egy elágazás. Ha a feltételvizsgálat (beker=1, jelen esetben 1=1) igaz, akkor az elágazásban szereplő utasítás, vagy utasítások végrehajtásra kerülnek. Az ilyen szerkezetet egyágú szelekciónak hívunk, mivel csak a feltétel teljesülése esetén végrehajtandó utasítások listáját tartalmazza. A fenti programban valójában két darab egyágú szelekció található. Ezek csak csak 1 és 2 esetén határozzák meg, hogy mi történjen. Ha a felhasználó pl. 3-at üt be, semmi sem történik. Egyágú szelekciók mellett gyakran használunk kétágú szelekciókat is. A kétágú szelekció nem csak azt írja elő, hogy mi történjen a feltétel teljesülése esetén, hanem azt is, hogy ellenkező esetben milyen utasítás(ok) kerüljön(ek) végrehajtásra: A program bekér egy számot, és attól függően, hogy a megadott szám 1 vagy sem, kiír valamit. A kódban látható kétágú szelekció szerkezete: If (feltételvizsgálat) Then utasítás1 utasítás2 utasítás3 beker=1 utasításn Else utasítás1 utasítás2 utasítás3 beker<>1 utasításn End if A feltételvizsgálatokban használhatóak a következő operátorok: =, <, > és kifejezések: And, Or
6. Ciklusok (iterációk) a programban Ciklusok segítségével egy vagy több utasítást többször hajthatunk végre. Háromféle ciklust használhatunk, de most csak eggyel, a növekményes ciklussal fogunk megismerkedni. A ciklus szerkezete: For [ciklusváltozó]=[kezdőérték] To [befejező érték] utasítás1 utasítás2 utasítás3 utasításn Next A program egymás alatt négyszer jeleníti meg a Hello szót. A ciklusváltozó jelen esetben az i, de lehetne más is, mondjuk j. Ez egy speciális lokális változó, mivel: 9 - nem kell deklarálni - csak a ciklusban létezik, a ciklus után nem használható. A program működése az i aktuális értékétől függ. Az i kezdetben nulla (kezdőérték). A Next utasításnál két dolog történik: - az i értéke eggyel nő - a vezérlés a ciklus elejére (For utasítás) lép ismét. A ciklus elején a program megvizsgálja, hogy az i értéke a kezdő- és befejező érték között van-e. Amennyiben igen, a ciklusban található utasítás (WriteLine("Hello")) ismét végrehajtásra kerül. Majd újra eljutunk a Next hez, i értéke nő, vezérlés visszatér a For hoz. Vázlatosan a következő történik: For Next WriteLine("Hello") i legyen egyenlő 1-gyel az i 0 és 3 között van? IGEN WriteLine("Hello") i legyen egyenlő 2-vel az i 0 és 3 között van? IGEN WriteLine("Hello") i legyen egyenlő 3-mal az i 0 és 3 között van? IGEN WriteLine("Hello") i legyen egyenlő 4-gyel az i 0 és 3 között van? NEM-STOP Könnyen belátható, hogy az alábbi esetekben sem változik meg a program kimenete: - For i = 1 To 4 - For i = 10 To 13 - For i = 11 To 14 Az alábbi program kimenete azonban már eltérő lesz a ciklusváltozó értékeinek módosítása esetén: A For-Next ciklus, mint látni fogjuk, remekül használható tömbök feltöltéséhez. A bal oldalon látható programmal például egy négyelemű egydimenziós tömbbe könnyedén beírhatunk 1-eseket. Amikor i=0, akkor tomb(0)-nak adhatunk értéket,amikor i=1, akkor a tomb(1)-nek, és így tovább. Azaz a For és Next közé elegendő ennyit írni: tomb(i)=1!
7. Matematikai műveletek a programban Alapműveletek: 10 - *: szorzás (6*3 -- 12) - /: osztás (6/3 -- 2) - +: összeadás (6+3 -- 9) - -: kivonás (6-3 -- 3) - \: maradékos osztás (13\2 -- 6) - Mod: maradékképzés (13\2 -- 1) - ^: hatványozás (3 ^ 2 -- 9) - Math.Sqrt(): négyzetgyök (Math.Sqrt(4) -- 2) - Math.Floor(): egészrész képzés (Math.Floor(4.7) -- 4) - Math.Round(): kerekítés (Math.Round(4.7) -- 5) Példa1: Döntsük el egy számról, hogy páros vagy páratlan! 13: páratlan 12: páros Belátható, a fenti két példa alapján is, hogy ha páros számokat kettővel osztunk, akkor a maradék 0 lesz, páratlan számok esetén viszont 1. Ezt kihasználva, a megoldás egyágú és kétágú szelekcióval:
Példa2: Mit csinál az alábbi program? 11 III. Programozás haladó(bb) szinten 1. Adatbeolvasás szöveges fájlból Hozzunk létre (például) a C: meghajtón egy VB nevű könyvtárat. Ebben a könyvtárban hozzunk létre egy nevek.txt nevű szöveges fájlt a következő tartalommal: Gipsz Jakab Aba Botond Nagy Kata A feladat az, hogy olvassuk be a szöveges fájlt, majd a neveket egymás után jelenítsük meg a monitoron:
A megoldás értelmezése: 12 - fájlműveletekhez szükségünk van az IO névtérre. Ezt a második sorban importáltuk - létrehoztunk egy egysor nevű, szöveges típusú változót. A szöveges fájlból ebbe fog kerülni az első, a második és a harmadik sor (név) - a fajl változóról csak azt kell tudnunk, hogy deklarálása során kell megadnunk a fájl elérési útvonalát, ezután pedig azt, hogy mit akarunk vele kezdeni. Jelen esetben csupán megnyitjuk (FileMode.Open). Ez azt jelenti, hogy tartalmát nem tudjuk módosítani, törölni. Ne felejtsük el lezárni a változót, miután már nincs rá szükség (fajl.close())! - az sorok változóról csak azt kell tudnunk, hogy a program a szöveges fájlban található adatokat segítségével tudja közvetlenül elérni. Ne felejtsük el lezárni a változót, miután már nincs rá szükség (sorok.close())! - a sorok.readline kiolvassa az első sort a fájlból. A kiolvasott sort azonnal betesszük az egysor nevű változóba, majd annak tartalmát rögtön ki is íratjuk a monitorra. Mivel Write() helyett WriteLine() utasítást használunk, a nevek egymás alá fognak kerülni. A második sorok.readline a második sort, a harmadik sorok.readline a harmadik sort olvassa ki. - Mivel a kiolvasás és kiíratás utasítása háromszor változatlanul egymás alatt megtalálható, a programot ciklus segítségével egyszerűsíthetjük: 2. Szöveges fájlok feldarabolása Feladat1: A Gipsz Jakab nevet helyezzük el egy String típusú változóba, majd soronként külön jelenítsük meg a vezeték-, majd keresztnevet (A vezeték- és keresztnév között egy szóköz található)! A feladat megoldásához a Split() függvényt fogjuk használni. A Split() függvény a zárójelben megadott karakter mentén darabolja fel a szöveges fájlt. Jelen esetben a szóköz mentén kell két részre vágni Gipsz Jakabot, így kapjuk meg külön a vezeték- és keresztnevet. Igen ám, de ennek következtében két szövegrész keletkezik, hogy kezeljük ezeket? Tegyük be egy kétfiókos String típusú szekrénybe!
A nev nevű változó tárolja a nevet. Létrehoztunk egy elemek nevű kételemű egydimenziós tömböt. Ez fogja tárolni a vezeték- és keresztnevet. A tömb deklarációja után a Split(" ")függvénnyel a bal oldalon látható kód szerint a szóköz helyén feldaraboltuk a nev nevű változó tartalmát, Gipsz Jakab - ot. Ezt követően az elő- és utónevet az elemek nevű tömbbe helyeztük, majd a 0. és 1. sorszámú fiók tartalmát egymás alá a monitorra írtuk. Megjegyzés: 13 - az elemek nevű tömb értelemszerűen kisebb nem lehet, de az az igazság, hogy nagyobb sem. A Split() használata esetén a Split()-tel feldarabolt szöveg részeinek tárolására szolgáló tömb méretét körültekintően kell megtervezni! - Könnyen belátható, hogy ciklus segítségével, a ciklusváltozó felhasználásával is megoldhattuk volna a feladatot Ezt követően az előző fejezetben beolvasott neveket is bontsuk két részre, majd a vezeték- és keresztneveket jelenítsük meg egymás alatt! A neveket egy szóköz választja el egymástól, így a Split() használható. A Split() által feldarabolt szövegrészek tárolásra itt is elegendő egy kételemű egydimenziós tömb, mivel a két részből álló neveket soronként olvassuk ki és daraboljuk fel. Lapozz!
14 A bekarikázott részt ciklusra cserélve a program végleges formája:
Feladat2: A következő, szóközzel elválasztott számokat olvassuk be egy Byte típusú tömbbe: 4 65 12 8 12! Szükségünk lesz egy olyan tömbre, amely a számokat fogja tárolni. Ez ötelemű lesz, mivel öt számról van szó. A tömb neve legyen szamok, típusa pedig Byte. A 4 65 12 8 12 Split()-tel feldarabolható, azonban a Split() csak szöveges típusú tömbbe képes beírni a feldarabolás után keletkezett szövegrészeket. Így először egy ötelemű, szöveges típusú tömböt kell feltöltenünk (legyen ez most is az elemek nevű tömb), majd a tömb értékeit át kell írnunk a szintén ötelemű szamok nevű tömbbe. Az első program ciklus nélkül, a második ciklussal oldja meg a feladatot. Az utóbbi rövidebb, elegánsabb, és bár a feladat nem kéri, de könnyedén megjeleníti a szamok nevű tömb minden értékét: 15 3. Adatbeolvasás, Split(), kétdimenziós tömb 3 az 1-ben, egészségére! A VB könyvtárban készítsünk egy feladat.txt nevű szöveges fájlt a következő tartalommal: 37 42 44 61 62 18 42 54 83 89 A számokat szóköz választja el egymástól. Olvassuk be a számokat egy Byte típusú kétdimenziós tömbbe, majd jelenítsük meg azokat a monitoron először egymás után, majd a fenti mintának megfelelően! Hozzávalók: - az adatbeolvasáshoz szükséges változók (fajl, sorok) - a Split() által használt String típusú tömb. Mivel soronként 5 szám található, ezért 5 eleműnek kell lennie. Legyen a tömb neve továbbra is elemek - a kétdimenziós, Byte típusú, 2x5-ös tömb. Legyen a tömb neve szamok
1. lépés a program keretének elkészítése 16 A program középső részén látunk egy For-Next ciklust. Mivel a szöveges fájlban csak két sor van, ezért a ciklusban található utasításokat kétszer kell végrehajtani. Az i értéke először 0, majd 1, így tényleg kétszer olvasunk ki sorokat a szöveges fájlból (sorok.readline), majd ezeket a sorokat különkülön daraboljuk a szóközök mentén. Az i értéke pedig felhasználható valamire: segítségével először a kétdimenziós tömb első (sorszám szerint 0.), majd második (sorszám szerint 1.) sorát tölthetjük fel. 2. lépés a kétdimenziós tömb feltöltése A megjegyzés helyére a következőt írhatjuk: Az i először 0, így először a tömb első sorába írjuk be az első 5 számot, végül az i értéke 1, így a tömb második sorába írjuk be az utolsó öt számot. A bal oldalon látható kód nem túl szép, és nem túl hatékony, ezért átalakítjuk. 3. lépés a feltöltés optimalizálása és a számok kiírása a monitorra egymás alá:
A végleges kód: 17 Már csak a megjegyzés helyére kell írnunk valamit. Felhívnám a figyelmet, hogy nem véletlenül fogjuk ide a kódot beszúrni. A megnyitott fájlt célszerű lezárni (fajl.close()), ha már nem használjuk. Mivel a kétdimenziós tömböt már feltöltöttük, és a feladatunk csupán az, hogy ennek a tartalmát a mintának megfelelően kilistázzuk, a megnyitott fájlra már nincs szükségünk, így a fájl lezárása után is elkészíthetjük a hiányzó kódrészletet: Az i itt is a sorokat azonosítja. Az i először 0, majd 1. A kiíráshoz a Write() utasítást használjuk, mert soronként szóközzel elválasztva egymás mellé kell írni 5-5 számot. 5 szám után azonban kell egy sortörés. Erre szolgál az üres WriteLine(). Ez a kódrészlet szintén optimalizálható:
IV. Az érettségi feladat megoldása beszéljenek a kódok! Egy nagy kitérő után végre elérkeztünk a feladatmegoldáshoz. Az alábbiakban a megoldásokat közlöm, magyarázatokat viszont nem fűzök a kódhoz. Teszem ezt azért, mert a korábbi fejezetekben minden szükséges információ megtalálható. Így ezt a részt csak azoknak ajánlom, akik az előismereteket más elsajátították. Az alábbi program a mellékelt megoldas.txt-ben is megtalálható. A program váza a II. fejezet 3. pontjában (Eljárások) megtalálható kód lesz. Az alábbiakban csak az egyes eljárások tartalmát közlöm. A forrásfájlt, amit mellékeltem is, a lottosz.dat-ot, a VB könyvtárba másoltam, onnét fogom megnyitni. A továbblépés előtt olvassuk el ismét a tananyag elején található feladatleírást. Az alábbi kódokban figyeljünk a megjegyzésekre is! 18 Szöveges fájl beolvasása kétdimenziós tömbbe a beolvas() eljárás 1. feladat a feladat1() eljárás Kérje be a felhasználótól az 52. hét megadott lottószámait! 2. feladat a feladat2() eljárás Figyelem!!! Ez a feladat a legbonyolultabb, és az alábbiakban használt algoritmust még nem tanultuk. Nyugodtan kihagyhatjuk, és folytathatjuk a 3. feladattal! A program rendezze a bekért lottószámokat emelkedő sorrendbe! A rendezett számokat írja ki a képernyőre! Ahhoz, hogy a bekért számokat rendezni tudjuk, a következő feltételeket figyelembe kell vennünk:
- a feladat1() eljárásban használt ujhet változó tartalmát Split()-tel darabolnunk kell, és az elemeket Byte típusú tömbbe kell elhelyezni - az ujhet lokális változó, a feladat() eljárásból nem érhető el, ezért globális változóvá kell előléptetnünk: 19 Végül a megoldás:
3. feladat a feladat3() eljárás Kérjen be a felhasználótól egy egész számot 1-51 között! A bekért adatot nem kell ellenőrizni! 20 4. feladat a feladat4() eljárás Írja ki a képernyőre a bekért számnak megfelelő sorszámú hét lottószámait, a lottosz.dat állományban lévő adatok alapján! Megjegyzések: - mivel a lottosz.dat adatait már elhelyeztük a szamok nevű kétdimenziós tömbbe, ezért a fájlt nem kell újra megnyitnunk. A szamok azonban lokális változó, a feladat4()-ből nem érhető el. Globális változóvá kell előléptetni: - hasonlóképpen a feladat3() eljárásban bekért szám (szam) is lokális változó. Globális változót kell belőle csinálni, hogy a feladat4() eljárás kezelni tudja:
21 * az ujhet nevű globális változót a feladat2()-ben hoztuk létre. Végül a megoldás: folytatása következik januárban