-
1
Gregorics Tibor
PROGRAMOZS
2. ktet
MEGVALSTS
-
2
Egyetemi jegyzet
2012
-
3
ELSZ .................................................................................................................... 8
BEVEZETS ............................................................................................................. 10
I. RSZ ALAPOK ...................................................................................................... 17
1. ELS LPSEK ......................................................................................................... 20
Implementcis stratgia .............................................................. 20
Nyelvi elemek ................................................................................ 23
1. Feladat: Osztsi maradk .......................................................... 28
2. Feladat: Vltoz csere ............................................................... 39
C++ kislexikon ................................................................................ 44
2. STRUKTURLT PROGRAMOK ...................................................................................... 45
Implementcis stratgia .............................................................. 45
Nyelvi elemek ................................................................................ 46
3. Feladat: Msodfok egyenlet .................................................... 61
4. Feladat: Legnagyobb kzs oszt .............................................. 73
5. Feladat: Legnagyobb kzs oszt mg egyszer ......................... 80
C++ kislexikon ................................................................................ 86
3. TMBK ............................................................................................................... 88
Implementcis stratgia .............................................................. 88
Nyelvi elemek ................................................................................ 90
6. Feladat: Tmb maximlis eleme ................................................ 96
7. Feladat: Mtrix maximlis eleme ............................................ 111
8. Feladat: Melyik szra gondoltam ............................................ 117
C++ kislexikon .............................................................................. 127
4. KONZOLOS BE- S KIMENET ..................................................................................... 129
Implementcis stratgia ............................................................ 129
Nyelvi elemek .............................................................................. 132
-
4
9. Feladat: Duna vzllsa ............................................................ 142
10. Feladat: Alshromszg-mtrix ............................................. 150
C++ kislexikon .............................................................................. 163
5. SZVEGES LLOMNYOK......................................................................................... 167
Implementcis stratgia ............................................................ 167
Nyelvi elemek .............................................................................. 170
11. Feladat: Szveges llomny maximlis eleme....................... 179
12. Feladat: J tanulk kivlogatsa ............................................ 187
C++ kislexikon .............................................................................. 194
II. RSZ PROCEDURLIS PROGRAMOZS.............................................................. 199
6. ALPROGRAMOK A KDBAN ...................................................................................... 202
Implementcis stratgia ............................................................ 202
Nyelvi elemek .............................................................................. 205
13. Feladat: Faktorilis ................................................................ 211
14. Feladat: Adott szmmal oszthat szmok ............................. 218
15. Feladat: Pros szmok darabszma....................................... 230
C++ kislexikon .............................................................................. 236
7. PROGRAMOZSI TTELEK IMPLEMENTLSA ............................................................... 239
Implementcis stratgia ............................................................ 239
Nyelvi elemek .............................................................................. 242
16. Feladat: Legnagyobb oszt .................................................... 247
17. Feladat: Legkisebb adott tulajdonsg elem ......................... 262
18. Feladat: Keressnk Ibolyt .................................................... 272
C++ kislexikon .............................................................................. 282
8. TBBSZRS VISSZAVEZETS ALPROGRAMOKKAL ......................................................... 285
Implementcis stratgia ............................................................ 286
-
5
Nyelvi elemek .............................................................................. 290
19. Feladat: Kitn tanul ........................................................... 292
20. Feladat: Azonos szn oldalak ................................................ 304
21. Feladat: Mtrix prhozamos tli ......................................... 315
C++ kislexikon .............................................................................. 330
9. FORDTSI EGYSGEKRE BONTOTT PROGRAM .............................................................. 331
Implementcis stratgia ............................................................ 332
Nyelvi elemek .............................................................................. 334
22. Feladat: Mkorcsolya verseny ............................................... 337
23. Feladat: Melyikbl hny van .................................................. 365
C++ kislexikon .............................................................................. 374
10. REKURZV PROGRAMOK KDOLSA ......................................................................... 376
Implementcis stratgia ............................................................ 376
Nyelvi elemek .............................................................................. 378
24. Feladat: Binomilis egytthat .............................................. 380
25. Feladat: Hanoi tornyai ........................................................... 390
26. Feladat: Quick sort ................................................................. 397
III. RSZ PROGRAMOZS OSZTLYOKKAL ............................................................ 409
11. A TPUS MEGVALSTS ESZKZE: AZ OSZTLY ........................................................... 411
Implementcis stratgia ............................................................ 411
Nyelvi httr ................................................................................ 414
27. Feladat: UFO-k ....................................................................... 423
28. Feladat: Zsk .......................................................................... 439
29. Feladat: Skvektorok .............................................................. 450
C++ kislexikon .............................................................................. 465
12. FELSOROLK TPUSAINAK MEGVALSTSA ............................................................... 467
-
6
Implementcis stratgia ............................................................ 467
Nyelvi httr ................................................................................ 470
30. Feladat: Knyvtr................................................................... 476
31. Feladat: Havi tlag-hmrsklet............................................ 498
32. Feladat: Bekezdsek .............................................................. 520
C++ kislexikon .............................................................................. 539
13. DINAMIKUS SZERKEZET TPUSOK OSZTLYAI ............................................................ 541
Implementcis stratgia ............................................................ 542
Nyelvi elemek .............................................................................. 545
33. Feladat: Verem ...................................................................... 556
34. Feladat: Ketts sor ................................................................. 586
C++ kislexikon .............................................................................. 610
14. OBJEKTUM-ORIENTLT KD-JRAFELHASZNLSI TECHNIKK ....................................... 612
Implementcis stratgia ............................................................ 613
Nyelvi elemek .............................................................................. 618
35. Feladat: Tllsi verseny ....................................................... 622
36. Feladat: Lengyel forma s kirtkelse ................................. 642
37. Feladat: Binris fa bejrsa ................................................... 677
C++ kislexikon .............................................................................. 705
15. EGY OSZTLY-SABLON KNYVTR FELHASZNLSA ..................................................... 707
Osztly-sablon knyvtr tervezse .............................................. 708
Osztly-sablon knyvtr implementlsa ................................... 717
38. Feladat: Kivlogats ............................................................... 729
39. Feladat: Feltteles maximumkeress .................................... 734
40. Feladat: Keress .................................................................... 739
41. Feladat: Leghosszabb sz W betvel ..................................... 751
-
7
42. Feladat: sszefuttats ........................................................... 767
IRODALOM JEGYZK ............................................................................................ 781
-
8
ELSZ
Ez a knyv annak a Programozs cm sorozatnak a msodik ktete,
amelyet az Etvs Lornd Tudomnyegyetem programtervez informatikus
szaknak azon tantrgyaihoz ajnlok, amelyeken a hallgatk az els
benyomsaikat szerezhetik meg a programozs szakmjrl. Az els ktet a
Tervezs alcmet viseli, s a programozsi feladatokat megold algoritmusok
ellltsval foglalkozik. Ennek a ktetnek pedig a Megvalsts az alcme,
mert itt az elz ktet alapjn elksztett tervek kivitelezsrl lesz sz,
amely sorn a tervet egy konkrt programozsi krnyezetben
implementljuk, programkdot hozunk ltre s futtathat alkalmazst
ksztnk.
Ebben a ktetben is a tervezssel kezdem egy feladat megoldst, de
azt nem kommentlom, hiszen errl az els ktetben rszletesen esik sz.
Inkbb azokra a krdsekre szeretnk vlaszolni, amelyek az implementci
sorn vetdnek fel. Olyan dntsi szitucikat, stratgikat veszek sorra,
amelyekkel a programoz a terv megvalstsa sorn tallkozik. Mivel pedig
a vgcl egy szoftver ellltsa, ezrt kell figyelmet fordtok majd a
tesztelsre, st, a megoldsok lersval mintt adok a kielgt
dokumentlsra is.
Egy olyan knyvben, amelyik mkd alkalmazsok ksztsrl szl,
megkerlhetetlen annak a programozsi nyelvnek a bemutatsa, amellyel
programjainkat kdoljuk. Nincs szndkom azonban programozsi
nyelvknyvet rni, hiszen ezekbl sok jt tallni a knyvesboltokban. Az
implementci folyamata, dntsi szitucii, stratgii klnben sem
ktdnek egy-egy konkrt programozsi nyelvhez. Termszetesen legalbb
egy konkrt nyelven meg kell valstani a megoldsokat, s ez a nyelv ebben
a ktetben a C++ lesz, de szeretnm, ha a ktet tancsait ms nyelveken
trtn megvalsts esetn is fel lehetne hasznlni.
Ennek a ktetnek az els rsze a programtervez informatikus szak
Programozsi alapismeretek trgyhoz nyjt kzvetlen segtsget, msodik
rsze s a harmadik rsz els kt fejezete a Programozs tantrgy
implementcirl szl ismeretanyagt fogja t, utols hrom fejezete pedig
-
9
az Objektumelv alkalmazsok fejlesztse tantrgyhoz kapcsoldik. A
ktetben szerepl mintapldk egy rsze a kpzsnkben mr megsznt
Alkalmazsok fejlesztse I. s II. cm tantrgybl szrmazik. Ennek kapcsn
felttlenl meg kell emltenem Szabn Nacsa Rozlia, Sike Sndor, Steingart
Ferenc s Porkolb Zoltn nevt, akik az emltett eldtantrgynak a
kidolgozsban rszt vettek, s kzvetve hozzjrultak ennek a ktetnek a
megszletshez.
Ez a ktet akrcsak az els gyakorlatorientlt. Negyvenkt feladat
megoldsnak rszletes bemutatsa tallhat benne, amely kiegszl a
szksges ismeretek (implementcis stratgik, nyelvi eszkzk) lersval.
A ktetben kln gyakorl feladatok nincsenek, gyakorlsknt az els, a
tervezsrl szl ktet feladatainak megoldsi tervt lehet megvalstani.
A kt ktetet (ezt a megvalstsrl szlt illetve a tervezsrl szl
els ktetet) gy terveztem, hogy ezek egymstl fggetlenl is rthetek
legyenek, de az ajnlott olvassi sorrend az, hogy a ktetek egyes rszeit
prban dolgozzk fel a hallgatk. Az els ktet els rszben az alapvet
programozsi fogalmakat vezetem be. Ennek megismerse utn ennek a
ktetnek az els rszt rdemes ttekinteni, amely nagyon egyszer
programok ksztst, s azokhoz szksges nyelvi elemeket mutatja be. Az
els ktet msodik rszben a visszavezetsre pl programtervezsi
technikt talljuk, mg itt a msodik rsz az ilyen mdon ellltott
programtervek megvalstsrl szl. A harmadik rsz mindkt ktetben a
korszer tpus fogalmhoz kapcsoldik. Az els ktetben a tpus-kzpont
tervezsrl, ebben a ktetben a felhasznli tpusok osztlyokkal trtn
megvalstsrl olvashatunk, azaz az objektum-orientlt programozs
alapjaival ismerkedhetnk meg.
A jegyzet tananyagnak kialaktsa az Eurpai Uni tmogatsval, az
Eurpai Szocilis Alap trsfinanszrozsval valsult meg (a tmogats szma
TMOP 4.2.1./B-09/1/KMR-2010-0003).
-
10
BEVEZETS
A programkszts egy olyan folyamat, amely magba foglalja a feladat
elemzst, a megolds tervezst, a programkd ellltst, majd
tesztelst s vgl a dokumentlst. Ezek sorrendjt mutatja be a szoftver
ellltsnak hagyomnyos, gynevezett vzess modellje (1.bra). A
valsgban egy program elksztse nem ennyire szablyos mederben folyik.
Minl sszetettebb ugyanis a megoldand problma, annl tbbszr fordul
el, hogy a megolds ellltshoz vezet t egyik vagy msik korbban
elvgzett szakaszhoz vissza kell trni, azt jra kell gondolni, s ennek
kvetkeztben az azt kvet szakaszokat (mg ha nem is teljes egszben)
meg kell ismtelni. A vzess modell nem azt mutatja meg, hogy hny
lpsben ll el a megolds, hanem csak azt, hogy milyen termszet
krdsekkel kell foglalkozni a programkszts sorn, s az egyes
szakaszokban hozott dntsek mely ms szakaszokra vannak hatssal.
1.bra Egyszerstett vzess modell
Tesztels, Dokumentls
Megvalsts
Elemzs
Tervezs
Feladat
Specifikci
Programterv
Programkd
Megolds
-
11
A modell pldul egyrtelmen jelzi, hogy egy problma megoldsnl
elszr a problma elemzsvel kell foglalkozni (mi a feladat, milyen
adatokat ismernk, mit kell kiszmolnunk, azaz mi a cl, milyen formban
lltsuk el a vlaszt, milyen eszkzk llnak rendelkezsnkre a
megvalstshoz, stb.). Ezt kveten lehet a megold program logikjt,
absztrakt vzt megtervezni. Ha tervezs sorn kiderl, hogy a feladat nem
teljesen vilgos, akkor vissza kell trni a feladat elemzshez. Csak a terv
(mg ha ez nem is vgleges) birtokban kezdhetjk el a program adott
programozsi nyelven trtn implementlst, majd az gy kapott
programkd ismtelt futtatsaival vgezhet el a megolds mdszeres
kiprblsa, a tesztels. Nem megfelel teszteredmnyek esetn a megelz
lpsek valamelyikt kell korriglni, amely tbb ms lps javtst is
kivlthatja. Sohasem szabad azonban szem ell tveszteni azt, hogy az adott
pillanatban ppen melyik szakaszval foglalkozunk a megoldsnak. Nem
vezetne clhoz ugyanis, ha pldul a tves tervezs miatt rosszul mkd
programnak a kdjt mdostannk a helyett, hogy a tervet vizsglnnk fell.
Vgl nem szabad megfeledkeznnk a megolds dokumentlsrl sem,
hiszen egy programkd akkor vlik termkk, ha annak hasznlatt,
karbantartst, tovbbfejlesztst msok szmra is rthet mdon lerjuk.
Sokszor hallani azt az rvet, hogy egy egyszer feladat megoldsnl
nincs szksg a tervezsre. Ez nem igaz! Az lehet, hogy egy egyszer
feladatot megold program esetben elg, ha a megolds terve csak a
programoz fejben lt testet. De terv ekkor is van, s a programozs
tanulsa sorn eleinte ezt az egyszer tervet sem rt rsban rgzteni. A terv
magba foglalja a feladat elemzsnek eredmnyt, a feladat adatait, az
adatok tpust, vltozik nevt, azt, hogy ezek kztt melyek a bemen
illetve eredmnyt hordoz vltozk, a bemen vltozk milyen
elfeltteleknek tesznek eleget, egy szval a feladat specifikcijt. Az
eredmnyvltozkra megfogalmazott gynevezett utfelttel is a
specifikci rsze, de erre az implementlsnl kzvetlenl mr nincs
szksg (az utfelttel az absztrakt megolds ellltst, illetve a program
tesztelst segti), hanem helyette a megold program absztrakt vzt
pldul struktogrammjt kell ismernnk. A terv teht tartalmazza a
megolds absztrakt, a konkrt programozsi krnyezettl (szmtgptl,
-
12
opercis rendszertl, programozsi nyelvtl, fejleszt krnyezettl)
elvonatkoztatott vltozatt.
A megolds tervbl a megvalsts (implementls) sorn kszl el a
mkd program. A megvalstsnak az eszkze az a programozsi nyelv s
programozsi krnyezet (szmtgp, opercis rendszer, fejleszt
eszkzk), amelyben a programot fejlesztjk. Az implementls hangslyos
rsze a kdols, amikor az absztrakt program utastsait a konkrt
programnyelv utastsaira rjuk t, s ehhez nlklzhetetlen a konkrt
programozsi nyelv ismerete. A programkd elksztse azonban nem
pusztn a tervezs sorn elllt absztrakt program mechanikus lefordtsbl
(kdolsbl) ll. Az implementls szmos olyan dntst s tevkenysget
is magba foglal, amely a programozsi nyelvtl fggetlen. Pldul konzolos
alkalmazsoknl, amelyek kdolsval ebben a ktetben foglalkozunk, a terv
ltalban nem tr ki arra, hogy a bemen vltozk hogyan vegyk fel a
kezdrtkeiket, illetve az eredmnyvltozk rtkeit hogyan tudjuk a
felhasznl fel lthatv tenni. Pedig ezekrl a krdsekrl, az adatok
beolvassrl s az eredmny kirsrl a programnak gondoskodnia kell. A
program ellltsakor a feladat megoldsi tervn tlmutat szmottev
kdot kell teht ellltanunk, ezrt nevezzk ezt a folyamatot a terv
kdolsa helyett a terv implementlsnak. Ugyancsak tlmutat a
mechanikus kdolson az, amikor figyelembe kell venni az olyan nem
funkcionlis kvetelmnyeket, mint pldul a memriaignyre vagy futsi
idre szabott felttelek. A hatkonysgra ugyan mr a tervezsi fzisban
lehet s kell figyelni, de a kdolskor a megfelel nyelvi eszkzk
kivlasztsval is jelentsen lehet javtani a program memriaignyt s
futsi idejt. De ne felejtsk el, hogy egy rosszul mkd program
hatkonysgval rtelmetlen dolog foglalkozni; a hatkonysg krdse csak
akkor kerl eltrbe, ha a program mr kpes megoldani a feladatot.
Ebben a knyvben programozsi nyelvnek a C++ nyelvet vlasztottam,
hiszen azoknl a tantrgyaknl, amelyeknek jegyzetl szolgl ez a ktet,
ugyancsak a C++ nyelvet hasznljuk. A fejezetekben ltszlag sok C++ nyelvi
elemet mutatok be (eleinte sok apr elemet, ksbb egyre kevesebbet, br
slyt tekintve nagyobb horderejt), mgsem e nyelvi elemek bemutatsn
van a hangsly. A C++ nyelv csak illusztrlsul szolgl az implementlshoz,
ezrt nem is trekszem a teljes megismertetsre. Nem foglalkozok annak
-
13
megmutatsval sem, hogy pontosan mi trtnik egy C++ utasts
vgrehajtskor a szmtgpen, ha annak megrtst s felhasznlhatsgt
valamilyen egyszerbb modell segtsgvel is rthetv lehet tenni. Els
sorban azokra a krdsekre koncentrlok, amelyek az implementci sorn
vetdnek fel.
Egy programozsi nyelvnek az alapszint megismershez ha ez nem
az els programozsi nyelv, amivel tallkozunk nhny ra is elegend. Ez
azrt van gy, mert egy gyakorlott programoz mr tudja, hogy melyek egy
nyelv azon elemei, amelyeket mindenkppen meg kell ismerni ahhoz, hogy
egy program kdolst elkezdhessk. Megprblom a C++ nyelvet ilyen
szemmel bemutatni: mindig csak egy kis rszt vizsglok meg belle, ppen
annyit, amelyet felttlenl ismerni kell, hogy a soron kvetkez programot el
lehessen kszteni. Nem vrbeli C++ programozk kpzse a clom, hanem
olyanok, akik meg tudnak oldani egy programozsi feladatot jobb hjn
C++ nyelven. De vajon lehetsges egyltaln kdolsrl beszlni a
programozsi nyelv alapos ismerete nlkl. A vlasz: igen. Ahhoz tudnm
hasonltani ezt a helyzetet, mint amikor valakinek egy idegen nyelvet kell
megtanulnia. Ezt lehet az adott nyelv nyelvtannak tanulmnyozsval
kezdeni (klnsen, ha van mr ismeretnk egy msik, mondjuk az
anyanyelvnk nyelvtanrl), vagy egyszeren csak megprbljuk hasznlni a
nyelvet (anlkl tanulunk meg egy kifejezst, hogy pontosan tudnnk, az
hny szbl ll, melyik az alany, melyik az lltmny). Ebben a ktetben ezt a
msodik utat kvetem, a feladat megoldst helyezem kzppontba, s a
C++ nyelvrl csak ott s ppen annyit mondok el, amire felttlenl
szksgnk lesz. rtelemszeren nem foglalkozok a hatkonysg
nvelsnek nyelvi sajtossgaival, hiszen ez a nyelv halad szint ismerett
ignyli, de igyekeztem minden helyzetre a legalkalmasabb nyelvi eszkzt
megtallni: olyat, amit a szakma tmogat, amelynek a hasznlata biztonsgos
s hatkony, a lersa egyszer, mkdsnek magyarzata nem ignyel
mly opercis rendszerbeli ismereteket, s kellen ltalnos ahhoz, hogy
hasonl nyelvi elemet ms nyelvekben is talljunk.
A mondanivalm szempontjbl a fejleszt eszkz megvlasztsa mg
annyira sem lnyeges, mint a programozsi nyelv. Clszer a kezd
programozknak gynevezett integrlt fejleszt krnyezetet hasznlniuk,
amely lehetsget ad minden olyan tevkenysg vgzsre, amely a
-
14
programozsnl szksges. Tmogatja a kd (C++ nyelven trtn)
szerkesztst, a kdnak a szmtgp nyelvre trtn lefordtst (itt az
adott nyelv szabvnyos fordtprogramjt clszer hasznlni), a fordtsnl
esetlegesen jelzett alaki (szintaktikai) hibk helynek knny megtallst, a
futtathat gpi kd program sszeszerkesztst, a program futtatst,
tesztelst, valamint a tartalmi (szemantikai) hibk nyomkvetssel trtn
keresst.
Alkalmazsainkat minden esetben egy gynevezett projektbe gyazzuk
be. Eleinte, amg az alkalmazsunk egyetlen forrs llomnybl ll, taln
krlmnyeskednek hat ez a lps, de ha megszokjuk, akkor ksbb, a tbb
llomnyra trdelt alkalmazsok ksztse is egyszer lesz.
A programok kdolsnl trekedjnk arra, hogy a bert kdot olyan
hamar ellenrizzk fordts s futtats segtsgvel, amilyen hamar csak
lehet. Ne a teljes kd bersa utn fordtsuk le elszr a programot, mert a
hibazenetek tnyleges okt ekkor mr sokkal nehezebb megtallni! Eleinte
ne szgyelljk, ha utastsonknt fordtunk, de ksbb se rjunk le egy
program-blokknl tbbet fordts nlkl. A bizonytottan helyes absztrakt
program kdolsa tbbnyire nem eredmnyez mkd programot. A kdols
sorn ugyanis elkvethetnk alaki (szintaktikai) hibkat (ezt ellenrzi
fordtskor a fordt program) s tartalmi (szemantikai) hibkat. Ez utbbiak
egy rszt a kdolsi megllapodsok betartsval tudjuk kivdeni, ms
rszt tesztelssel felfedezni, a hiba okt pedig nyomkvetssel megtallni.
A fordtsnl keletkezett hibazenetek rtelmezse nem knny. A
fordtprogram annl a sornl jelez hibt, ahol a hibt szlelte, de a hiba
gyakran tbb sorral elbb tallhat vagy ppen nem tallhat (ilyen pldul
egy vltoz deklarlsnak hinya). rdemes a hibazeneteket sorban
rtelmezni s kijavtani, mert bizonyos hibk egy korbbi hibnak a
kvetkezmnyei. Fontos tudni, hogy a hibazenet nem adja meg a hiba
javtsnak mdjt. Nem szabad a hibazenet ltal sugallt javtst azonnal
vgrehajtani, hanem elszr r kell jnnnk a hiba valdi okra, majd meg
kell keresnnk, hol s mi mdon korriglhatjuk azt. Ne csak a fordt
hibazeneteit (error), hanem a figyelmeztetseit (warning) is olvassuk el. A
figyelmeztetsek rmutathatnak ms, nehezen rtelmezhet hibazenetek
-
15
okaira, vagy ksbb fellp rejtett hibkra. A szerkesztsi hibk egy rsze
elkerlhet a kdolsi megllapodsok betartsval.
rdemes a kdot gy elkszteni, hogy annak bizonyos rszei minl
hamarabb futtathatk legyenek. gy a programot mr akkor ki tudjuk
prblni, amikor az mg nem a teljes feladatot oldja meg.
Ne sajnljuk a tesztelsre sznt idt! Gondoljuk t milyen
tesztesetekre (jellegzetes bemen adatokra) rdemes kiprblni a
programunkat. A fekete doboz teszteseteket a feladat szempontjbl
lnyeges vagy extrm (szlssges) bemen adatok s a vrt eredmnyek
adjk, kln vlasztva ezek kzt a feladat elfelttelt kielgt, gynevezett
rvnyes, s az azon kvl es rvnytelen tesztadatokat. A fehr doboz
teszteseteket a program kd ismeretben generlt tesztadatok alkotjk,
amelyek egyttesen biztostjk, hogy a kd minden utastsa ki legyen
prblva, valamint az sszefut s elgaz vezrlsi szlak minden
lehetsges vgrehajtsra sor kerljn, azaz az gynevezett sztgazsi s
gyjtpontjainl mindenfle irnyban legalbb egyszer keresztlmenjen a
vezrls. A tesztelst (akrcsak a fordtst, futtatst) menet kzben, egy-egy
rszprogramra is rdemes mr vgrehajtani.
A nyomkvets egy tartalmi hiba bekvetkezsnek pontos helyt
segt kiderteni, noha ez nem felttlenl az a hely, ahol programot javtani
kell. A nyomkvets a program lpsenknti vgrehajtsa, melynek sorn
pldul megvizsglhatjuk a program vltozinak pillanatnyi rtkt.
Egy program dokumentlsa alapveten kt rszbl ll. A felhasznli
lers az alkalmazs hasznlatt mutatja be, arrl a programot hasznlknak
ad felvilgostst. Tartalmazza a megoldott feladat lerst, a program
mkdsnek bemutatst nhny tipikus hasznlati esetre (bemen
adatkombincira), a program mkdshez szksges hardver s szoftver
feltteleket, s a program mkdtetsnek mdjt (telepts, futtats). A
fejleszti lers a megolds szerkezetbe enged bepillantst. Elssorban
programozknak szl, s lehetv teszi, hogy a programot ha szksges
knnyebben lehessen javtani, mdostani. Tartalmazza a feladat szvege
mellett a feladat specifikcijt, a program tervt, az implementci sorn
hozott, a tervben nem szerepel dntseket (beolvassi, kirsi szakasz
megvalstsa, hatkonysg javtsa rdekben vgzett mdostsok), a
-
16
programkdot (sszetett program esetn a rszeinek egymshoz val
kapcsoldst), a tesztelsnl vizsglt teszteseteket. Ezen kvl esetleges
tovbbfejlesztsi lehetsgeket is megemlthet. Ebben a ktetben a
feladatok megoldsnl lnyegben ez utbbit, a fejleszti lerst fogjuk
megadni gy, hogy kiegsztjk azt a megrtst segt megjegyzsekkel.
Felhasznli lerst a feladatok egyszer voltra tekintettel nem adunk.
A ktetben negyvenkett programozsi feladat megoldsa tallhat. A
megoldsokat tartalmaz fejezeteket gy alaktottam ki, hogy mindegyik
elejn elszr az rintett feladatok megoldshoz kthet implementcis
stratgikat ismertetem, majd bemutatom a szksges nyelvi elemeket s
kdolsi konvencikat. A fejezetek ezeket az ismereteket fokozatosan,
egymsra pl sorrendben vezetik be. A fejezeteket az azokban elszr
megjelen C++ nyelvi elemek sszefoglalsa zrja le.
A ktet hrom rszbl ll. Az els rsz nagyon egyszer programok
ksztsn keresztl illusztrlja az implementci folyamatt. Megmutatja,
hogyan kell egy struktogrammot kdolni, hogyan kszlnek a programok
beolvasst illetve kirst vgz rszei, ha erre a konzolt vagy szveges
llomnyt hasznlunk. Megismerjk a tmbk ksztsnek s hasznlatnak
mdjt. A msodik rsz az alprogramokra (fggvnyekre, eljrsokra) trdelt
programok ksztsrl szl. Elszr csak az alprogramok hasznlatrl, majd
az els ktetben trgyalt programozsi ttelekbl szrmaztatott kdok
alprogramba gyazsrl, ezt kveten a tbb programozsi ttellel
megoldott feladat programjnak tbb alprogramra bontsrl, s az
alprogramok csoportjainak kln fordtsi egysgben, kln komponensben
trtn elhelyezsrl, s vgl a rekurzvan hvott alprogramokrl lesz sz.
A harmadik rsz az osztlyokat hasznl programokat mutatja be. Elszr az
egyszer osztly fogalmt ismerjk majd meg nhny, az els ktetben
trgyalt tpus megvalstsn keresztl. Majd klnfle felsorolk
megvalstsval az els ktet harmadik rsznek megoldsait
implementlhatjuk. Ez utn dinamikus adatszerkezet tpusok osztlyait
implementljuk. Vgl megismerjk az osztly-szrmaztats s a sablon-
pldnyosts eszkzt, s ezek segtsgvel pldkat mutatunk objektum
orientlt stlus megvalstsokra.
-
17
I. RSZ
ALAPOK
Ebben a rszben egyszer, kismret, egyetlen programblokkban kdolhat
konzolalkalmazsok ksztst vehetjk szemgyre, s ezen keresztl
megfigyelhetjk a programkszts folyamatt.
Egy egyszer konzolalkalmazs esetben a kd hrom szakaszra
tagoldik: bemen adatok beolvassra s ellenrzsre; a szmtsok
elvgzsre; az eredmny megjelentsre. Ez a feloszts a nagyobb (de nem
objektum orientlt) konzolalkalmazsoknl is megfigyelhet.
A szmtsi szakasz az absztrakt algoritmusnak megfelel kdot
tartalmazza. Amennyiben az absztrakt program strukturlt, akkor annak
szerkezete alapjn kvlrl befel halad kzi fordtssal lltjuk el a kdot.
Mindig az adott szerkezeti elemnek (szekvencia, elgazs, ciklus) megfelel
utastst rjuk le, s amikor elemi utastshoz rnk, azt kzvetlenl kdoljuk.
A beolvassi szakaszban gondoskodnunk kell arrl, hogy a bemen
vltozk megfelel kezdrtket kapjanak. A feladat tervbl kiderl, hogy
programunknak melyek a bemen vltozi, s azok kezd rtkeire milyen
felttelnek kell teljeslnie. A bemen adatok kezdrtkeit tbbnyire a
szabvnyos bemenetrl vagy egy szveges llomnybl nyerjk. A beolvasott
adatokra meg kell vizsglni, teljestik-e a szksges elfeltteleket. Ha nem,
akkor hiba-jelzst kell adni, s vagy lelltani a programot, vagy jra meg kell
ksrelni a beolvasst. Elfordulhat, hogy a bemen adatok beolvassa a
szmtsi szakasszal sszeolvad, mert az adatokat olyan temezssel kell
beolvasni, ahogy azt a szmts ignyli.
Az eredmny megjelentse az eredmnyvltozk tartalmnak
kpernyre, vagy ms, a felhasznl ltal olvashat adathordozra trtn
rsbl ll. Itt is elfordulhat, hogy ez a szakasz sszeolvad a szmtsi
szakasszal.
Melyek egy programozsi nyelvnek azon rszei, amelyeket okvetlenl
meg kell ismernnk az egyszer feladatok implementlshoz? Valjban igen
csekly tuds birtokban mr fel tudunk pteni egy egyszer programot.
-
18
1. A programkd szerkezete
2. Tpusok, kifejezsek, vltozk, rtkads
3. Vezrlsi szerkezetek
4. Input-output
5. Knyvtri elemek
I-1.bra. Amit egy programozsi nyelvrl mindenkppen meg kell tanulnunk
Mindenekeltt meg kell tanulnunk, hogy az adott nyelven milyen
szerkezeti keretben lehet a kdjainkat elhelyezni. Ez a szerkezet ltalban
sszetett, de szerencsre az els, egyszer programok elksztshez nem
kell mg azt a maga teljessgben tltni.
Mr a kezdeteknl tisztzni kell, hogy milyen alaptpusokat (pl. egsz,
vals, logikai, karakter) s milyen tpussszetteleket (pl. tmb) ismer az
adott nyelv, hogyan kell lerni e tpusok rtkeit, hogyan lehet ilyen tpus
vltozkat deklarlni, milyen mveletek vgezhetk ezekkel, milyen
kifejezsek pthetk fel bellk.
Az absztrakt program kdolshoz a vezrlsi szerkezetek nyelvi
megfelelit kell megismernnk. Eleinte elg a hrom vezrlsi szerkezetnek
ltalnosan megfelel nyelvi elemeket megtallni, ksbb meg lehet azt
vizsglni, hogy egy vezrlsi szerkezetet specilis esetben milyen sajtos
nyelvi elemmel lehet mg kdolni (pl. mikor hasznljunk for ciklust a while
ciklus helyett, switch-t az if-else-if helyett).
Taln a nyelvek legegyedibb rsze az, ahogyan a krnyezetkkel val
kapcsolatot megvalstjk, azaz az input-output utastsai. Az input-output
ltalban sszetett, de mi csak kt terletvel foglalkozunk: a konzolablakos
input-outputtal s a szveges llomnyokkal.
Egy nyelv erejt mutatja, hogy tmogatja-e korbban megrt kdrszek
jrafelhasznlst. Vannak-e olyan gynevezett kdknyvtrak, amelyeket
szksg esetn a programunkhoz csatolhatunk azrt, hogy azok elemeit
(specilis tpusokat, objektumokat, fggvnyeket) felhasznlhassuk. Ltni
-
19
fogjuk, hogy mr a legegyszerbb programok rsnl is szksg lehet ilyen
knyvtri elemekre.
-
20
1. Els lpsek
Ebben a fejezetben nagyon egyszer (egyszer programtervvel rendelkez)
feladatok megoldsn keresztl mutatjuk be a programksztsnek azt a
szakaszt, amelyet megvalstsnak vagy ms nven implementlsnak
neveznek. Ezzel prhuzamosan megismerkednk a C++ programozsi nyelv
nhny alapvet nyelvi elemvel: az egsz szmok tpusval, vltozk
deklarlsnak mdjval, az rtkads utastssal s a szabvnyos input-
output mveletekkel.
Implementcis stratgia
Az egyszer (gynevezett konzolablakos) megoldsok implementlst t
lpsben vgezzk el. Termszetesen ezeket a lpseket nem kell felttlenl
az itt megadott sorrendben, egymstl szigoran klnvlasztva
vgrehajtani, de mindig fontos tudni azt, hogy a program kdnak ppen
melyik rszt ksztjk, ugyanis ettl fgg, hogy milyen tancsokat s nyelvi
elemeket vehetnk ignybe. Az egyes lpsek elvgzsnl (az els
kivtelvel) a programtervre tmaszkodhatunk.
1-1. bra. Egyszer programok implementlsnak lpsei
Egy program kdjt a vlasztott programozsi nyelvre jellemz keretbe
kell befoglalni. Ehhez a programozsi nyelv azon specilis nyelvi elemeit,
utastsait kell felhasznlni, amelyek kijellik a programkd elejt s vgt,
meghatrozzk, hogy melyik utasts vgrehajtsval kezddjn a program
1. Programkd keretnek elksztse
2. Absztrakt program kdolsa
3. Bemen adatok beolvassa s ellenrzse
4. Eredmny megjelentse
5. Vltozk deklarlsa
-
21
futsa, tovbb klnleges elrsokat adhatnak a programkd
lefordtshoz. Ezen nyelvi elemek kz, mint egy keretbe kell majd a kd
tbbi rszt beilleszteni.
A kdnak lnyeges rszt alkotja a programtervben rgztett absztrakt
programnak az adott programozsi nyelvre lefordtott vltozata. Az
implementci e msodik lpse a sz szoros rtelemben vett kdols,
amikor a programot egy absztrakt nyelvrl (pl. struktogramm lers) egy
konkrt nyelvre (mondjuk: C++) fordtjuk. Ehhez azt kell tudni, hogy az
absztrakt program utastsainak a programozsi nyelv mely utastsai
felelnek meg. Egy utasts lehet egyszer: res lps vagy rtkads, de lehet
sszetett: egy vezrlsi szerkezet (szekvencia, elgazs, ciklus). Elfordulhat,
hogy az absztrakt program lersa olyan elemi utastst tartalmaz, amelyet
nem lehet kzvetlenl kdolni a vlasztott konkrt nyelven. Ilyen lehet
pldul egy szimultn rtkads, amelyik egyszerre, egy idben ad tbb
vltoznak is j rtket. Ilyenkor a megvalsts sorn a programtervet kell
finomtani, rszletezni.
A megvalsts harmadik s negyedik lpsben az absztrakt program
s a futtat krnyezet kztti kapcsolatot megteremt kdot kell kitallni.
Ennek segtsgvel a krnyezetbl eljutnak a bemen adatok a programhoz,
s az eredmny visszajut a krnyezetbe. Ennek a kdnak ltalban nincs
absztrakt vltozata, de a feladat specifikcija kijelli azokat a vltozkat,
amelyek kezd rtkeit be kell olvasni a felhasznltl, s azokat, amelyek
rtkt meg kell jelenteni a felhasznl szmra. Ezekben a lpsekben
teht nem abban az rtelemben vett kdols zajlik, hogy egy adott
programot kell egy msik nyelvre trni, hanem egy sokkal kreatvabb
tevkenysg: ltre kell hozni olyan kdrszleteket, amelyhez korbbi
tapasztalataink, kdmintink szolglhatnak segtsgl.
A specifikciban rgztett llapottr megmutatja a bemen vltozk
tpust, a specifikci elfelttele pedig rgzti, hogy a bemen adatoknak
milyen feltteleket kell kielgtenie. Ezek egyttesen meghatrozzk a
beolvass mdjt. A bemen adatok beolvasshoz olyan kdot kell
ksztennk, amelyik megksrli a kvnt tpus rtk beolvasst s ellenrzi
a szksges feltteleket. Ha nem sikerl a megfelel rtket beolvasni, akkor
a kdnak meg kell akadlyozni a program tovbbi futst. Ehhez ktfle
-
22
stratgia kzl vlaszthatunk. Az egyik megfelel hibazenet generlsa utn
lelltja a program futst, a msik jra s jra megprblja beolvasni az
adatot, amg az helyes nem lesz. Azt, hogy ezek kzl melyiket alkalmazzuk, a
konkrt feladat kitzse illetve a beolvasand adat forrsa hatrozza meg.
Pldul, ha az adatokat kzvetlenl a felhasznltl kapjuk, akkor
alkalmazhat a msodik mdszer, de ha az adatok egy korbban feltlttt
szveges llomnybl szrmaznak, akkor csak az els t jrhat.
A kirs figyelembe veszi az eredmny-vltozk tpust (ez az
llapottrbl olvashat ki), valamint a specifikci utfelttelt. Gyakori eset
pldul az, hogy egy eredmny-vltoz csak bizonyos felttel teljeslse
esetn kap rtket. Ilyenkor a kirs kdja egy elgazst fog tartalmazni,
amely csak megadott esetben rja ki az eredmnyt, egybknt pedig egy
tjkoztatst ad annak okrl, hogy az eredmny mirt nem jelenhet meg.
1-2. bra. Program vltozi tervezsi szempontbl
A vltozk fontos szerepli a programoknak. Ezek java rszt a
tervezs sorn vezetjk be, hiszen mr ott kiderlnek a megoldand feladat
bemen- s eredmny-vltozi, valamint szmos segdvltoz is, de az
implementlskor mg tovbbi segdvltozk is megjelenhetnek. A vltozk
bevezetse a tervezs szintjn a vltozk tpusnak megadsval jr egytt.
A programban hasznlt vltozkat (a feladat bemen- s eredmny-vltozit,
Bemen vltoz: Az absztrakt program olyan vltozja, amely
az absztrakt program vgrehajtsa eltt rendelkezik (a
megoldand feladat elfelttelnek) megfelel
kezdrtkkel.
Eredmny-vltoz: Az absztrakt program olyan vltozja,
amely az absztrakt program (tervezs ltal garantlt)
befejezdse utn a (megoldand feladat utfelttele ltal)
kvnt rtket tartalmazza.
Segdvltoz: A program mkdse kzben ltrejtt vltoz.
-
23
az absztrakt program segdvltozit, s az implementls sorn bevezetett
egyb segdvltozkat) tbbnyire (C++-ban mindig) deklarlni kell, azaz
explicit mdon meg kell adni a tpusukat. Ehhez ismerni kell az adott
nyelvben a deklarci formjt, elhelyezsnek mdjt, a deklarcinl
hasznlhat alaptpusokat s azok tulajdonsgait (tpusrtkeit s
mveleteit). Vannak azonban olyan programozsi nyelvek is, ahol a vltoz
els rtkadsa az rtkl adott kifejezs tpusval deklarlja a vltoz
tpust. A vltozk deklarcija a megvalsts tdik lpse.
Nyelvi elemek
Egy program kdjnak sorait az gynevezett forrsllomnyba rjuk bele,
amelyet brmilyen szveges llomnyt elllt szvegszerkesztvel
elkszthetnk. Ennek az llomnynak ltalban valamilyen specilis, az adott
programozsi nyelvre utal kiterjesztse van. A C++ nyelv programjainkat
.cpp kiterjeszts llomnyokba tesszk. (A gyakorlatban ezen kvl
gyakran elfordul a .c, .C, .cxx kiterjeszts is.) Az egyszer programok
egyetlen forrsllomnyban helyezkednek el, az sszetett programok kdjt
tbb llomnyba lehet sztosztani. A forrsllomnyokban elhelyezett
kdban egyrtelmen kell megjellni azt az utastst, amelynl a program
vgrehajtsa (futsa) elkezddik. C++ nyelven ez az gynevezett main
fggvny blokkjnak els utastsa. Ezt a blokkot a main fggvny nevt
kvet nyit s csuk kapcsos-zrjelek hatroljk.
A kerethez tartoznak a kd olyan bejegyzsei, amelyek a fordt
program szmra hordoznak zenetet. Ilyen pldul azon kdknyvtrak
kijellse, amelynek elemeit fel szeretnnk hasznlni, ezrt a kdknyvtrat
be akarjuk msolni (include) a programunkba. A konzolos input-output
tevkenysgekhez pldul szksgnk lesz egy #include
sorra.
Itt kell megemlteni a minden forrsllomny elejn ktelezen
ajnlott using namespace std utastst is. Szmos sokszor hasznlt
elredefinilt azonost ugyanis az gynevezett standard (std) nvtrben
tallhat. Ez azt jelenti, hogy ezek az elre definilt elemek egy olyan
csomagban tallhatk, amelynek elemeire az std:: eltag (gynevezett
-
24
minsts) segtsgvel lehetne csak hivatkozni, ha nem hasznlnnk a
using namespace std utastst.
C++ nyelven a main fggvnyben elhelyezett return utasts a
program futst lltja le. A main fggvny eltti int (integer) szcska utal
arra, hogy a return utn egy egsz szmot (egsz rtk kifejezst) kell rni.
Ezt az rtket a program lellsa utn a futtat krnyezet (az opercis
rendszer) kapja meg, s tetszs szerint reaglhat r. Ha ez nulla, akkor az a
minden rendben zenetet szimbolizlja. A return kifejezs helyett
hasznlhat mg az exit(kifejezs) is, de ehhez bizonyos
krnyezetekben be kell illeszteni a program elejre egy #include
sort.
A vltoz deklarcija a vltoz tpust rja le. A tpus hatrozza meg,
hogy egy vltoz milyen rtkeket vehet fel s azokkal milyen mveletek
vgezhetk. Egy fut program vltozjhoz a tpusn kvl hozztartozik a
szmtgp memrijnak azon rsze is, ahol a vltoz aktulis rtke
troldik. A memrira els megkzeltsben gondoljunk gy, mint bjtok (1
bjt = 8 darab 0 vagy 1-est trol bit) sorozatra. Minden bjtot
egyrtelmen azonost az ebben a sorozatban elfoglalt pozcija, azaz
sorszma, amit a bjt cmnek hvunk. A sorszmozst nullval kezdjk.
Szmok binris alakja
A szmtgpek memrijban a szmokat binris alakban (kettes
szmrendszerben) brzoljuk. A binris alakban felrt szm egy szmjegye 0
vagy 1 rtk lehet. Ezt hvjuk bitnek. A szmjegy rtke a pozcijtl, a
helyirtktl fgg. A kettes szmrendszer helyirtkei a kett hatvnyai. Egy
termszetes szm binris alakjnak szmjegyeit helyirtk szerint nvekv
sorrendben egy kettvel val osztogatsos mdszerrel lehet ellltani. Az
osztsoknl keletkezett maradk a soron kvetkez szmjegy, az oszts
eredmnye pedig a kvetkez oszts osztandja. Az osztogats addig tart,
amg az osztand nem nulla.
Plda: Adjuk meg a 183(10) binris alakjt!
183 : 2 = 91 maradt: 1
91 : 2 = 45 maradt: 1
-
25
45 : 2 = 22 maradt: 1
22 : 2 = 11 maradt: 0
11 : 2 = 5 maradt: 1
5 : 2 = 2 maradt: 1
2 : 2 = 1 maradt: 0
1 : 2 = 0 maradt: 1
Teht 183(10) = 10110111(2) = 1*27 + 0*26 + 1*25 + 1*24 + 0*23 + 1*22 + 1*21
+ 1*20
Egy trtszm binris alakjnak szmjegyeit helyirtk szerint cskken
sorrendben kettvel val szorzsos mdszerrel lehet ellltani. A szorzat
egsz rsze a soron kvetkez szmjegy, trtrsze a kvetkez szorzs
szorzandja. A mdszer addig tart, amg a szorzand nem nulla. Elfordulhat,
hogy ez nem kvetkezik be, mert a kettes szmrendszerben felrt szm egy
vgtelen kettedes trt lesz.
Plda: Adjuk meg a 0.8125(10) binris alakjt!
0.8125 * 2 = 1.6250 egszrsz: 1 trtrsz: 0.625
0.625 * 2 = 1.250 egszrsz: 1 trtrsz: 0.25
0.25 * 2 = 0.50 egszrsz: 0 trtrsz: 0.5
0.5 * 2 = 1.0 egszrsz: 1 trtrsz: 0
Teht 0.8125(10) = 0.1101(2) = 1*1/2 + 1*1/4 + 0*1/8 + 1*1/16
Plda: Adjuk meg a 0.1(10) binris alakjt!
0.1 * 2 = 0.2 egszrsz: 0 trtrsz: 0.2
0.2 * 2 = 0.4 egszrsz: 0 trtrsz: 0.4
0.4 * 2 = 0.8 egszrsz: 0 trtrsz: 0.8
0.8 * 2 = 1.6 egszrsz: 1 trtrsz: 0.6
0.6 * 2 = 1.2 egszrsz: 1 trtrsz: 0.2
0.2 * 2 = 0.4 egszrsz: 0 trtrsz: 0.4
0.4 * 2 = 0.8 egszrsz: 0 trtrsz: 0.8
Teht 0.1(10) = 0.00011 (2) (vgtelen szakaszos trt)
-
26
Egy vltoznak csak azt kveten lehet rtket adni, hogy kijelltk a
memriban a helyt, azaz megtrtnt a vltoz helyfoglalsa. Ezt nevezzk
a vltoz defincijnak. Az rtket binris kdolssal egy vagy tbb egyms
utni bjton troljuk. A trolshoz szksges memria szelet els bjtjnak
cme a vltoz cme, a trolshoz hasznlt bjtok szma a vltoz mrete.
1-3. bra. Vltoz jellemzi
Az ersen tpusos nyelvekben egy vltoznak mindig van tpusa, de
neve, memria cme s rtke nem felttelenl. A vltoz deklarcija s a
helyfoglalsa kztti idben a vltoz nem rendelkezik mg memria
terlettel, teht sem cme, sem rtke nincs. A memriafoglals utn, a
vltoznak mr lesz rtke, mert a kijellt memria szelet eleve tartalmaz 0
vagy 1-es biteket. Az ezekbl kiszmolt rtk azonban elre nem ismert,
bizonytalan, mskppen fogalmazva nem definilt, amit gy is felfoghatunk,
hogy a vltoz mg nem kapott kezdeti rtket. (Tallkozhatunk olyan
vltozkkal is, amelyeknek hinyzik a neve, az rtkkre csak a cmk
segtsgvel hivatkozhatunk.)
C++ nyelven a vltoz neve (csak gy, mint ms azonostk) betk s
szmok sorozatbl ll. Az els karakternek mindig betnek vagy _ (alhzs)
jelnek kell lennie, s nem hasznlhatak vltoznvknt a nyelv foglalt
kulcsszavai.
A vltozkkal kapcsolatos alapvet utasts az rtkads. Egy kicsit
megtveszt, hogy az absztrakt programokban (s a Pascal nyelven)
vltoz:=kifejezs formban felrt rtkadst a C-szer nyelvekben a
vltoz = kifejezs utasts rja le, azaz nincs benne az rtkads irnyt
jelz kettspont. A kifejezs olyan vltozkbl, tpusrtket megjelent
szimblumokbl (gynevezett literlokbl), mveleti jelekbl s fggvnyek
rtk
nv tpus cm lefoglalt memria
szelet
vltoz regisztrci
-
27
visszaadott rtkeibl ll formula, amely megfelel bizonyos alaki s
jelentsbeli szablyoknak. Alaki (szintaktikai) hiba, pldul ha egy oszts
mveleti jelhez csak egy argumentumot runk (/8.2), jelentsbeli
(szemantikai) pedig, pldul ha kt karakterlncot akarunk sszeszorozni
(fzr*lnc), feltve, hogy nem definiltuk kt lnc szorzst.
Elfordulhat olyan eset is, amikor a kifejezs helyes, de mgsem lehet az
rtkt kiszmolni, a program abortl. Gondoljunk pldul az x/y osztsra, ha
az y vltoz rtke nulla.
A konzolos input-output mveletek alapszinten lehetsget adnak
arra, hogy egy bemen vltoz a billentyzetrl rtket kaphasson, illetve
egy eredmny-vltoz vagy eredmny-kifejezs rtkt a konzol ablakban
megjelenthessk. A kdban elhelyezett beolvass utastsnak tartalmaznia
kell, hogy melyik vltoznak akarunk rtket adni, a kir utastsnak pedig
azt a kifejezst, amelynek az rtkt meg akarjuk jelenteni. Az rtkek a
felhasznl szmra karakterek sorozatval rhatak le. Pldul egy egsz
szm egy eljelbl (-/+), majd nhny szmjegybl ll. A beolvass sorn
ezeket a karaktereket a megfelel billentyk lenyomsval adjuk meg, s az
billentyvel fejezzk be az rtk lerst. A begpelt karaktersorozat
a konzolablakban is lthat. Kirskor az rtket ler karakterek sorozata fog
a konzol ablakban megjelenni.
C++-ban a beolvass s a kirs legegyszerbb formja az gynevezett
szabvnyos input- illetve output adatfolyamok hasznlata. A cin (consol
input) objektumon keresztl a szabvnyos bemeneten (ez lehet a
billentyzet) keletkez jeleket (karaktereket) tudjuk beolvasni s adatokk
csoportostani attl fggen, hogy milyen tpus vltozt kell velk feltlteni.
A beolvas utasts formja: cin >> vltoz. A cout (consol output)
objektumon keresztl a szabvnyos kimenetre (pldul a kperny
gynevezett konzolablakra) sznt adatot (egy kifejezs rtkt)
karaktersorozatra bontva kldhetjk el. A kirs utastsa: cout
-
28
1. Feladat: Osztsi maradk
Olvassunk be kt termszetes szmot a billentyzetrl, hatrozzuk meg az
osztsi maradkukat, majd az eredmnyt rjuk ki a konzolablakba!
Specifikci
A feladatban hrom darab, termszetes szmot (nem negatv egszeket)
rtkl vev vltoz szerepel, ezek kztt az x s y vltozk kezdetben
bemen adatokat tartalmaznak, amelyek rgztett kezd rtkeit jelljk az
x-vel s y-vel. Mivel az x-nek az y-nal vett osztsi maradkt (x mod y) kell
kiszmolnunk, az y rtke nem lehet nulla, hiszen a nullval val oszts
eredmnye nincs rtelmezve.
A = ( x, y, z : )
Ef = ( x=x y=y y>0 )
Uf = ( x=x y=y z = x mod y )
Absztrakt program
A szmtsok elvgzst megold algoritmus a clfelttelbl kzvetlenl
addik. A z vltoznak kell j rtket adni, amely az x rtknek y rtkvel
vett osztsi maradka.
z := x mod y
Implementls
A programkdot a klasszikus hrmas tagolssal adjuk meg, amely egy jl
megrt essz (bevezets, trgyals, befejezs) programozsi megfelelje
1. A bemen adatok beolvassa
2. Szmols: Az absztrakt program kdja
3. Az eredmny kirsa
-
29
amelyek implementlst a korbban ismertetett t lpsben vgezzk el.
Elksztjk a program kerett, deklarljuk a vltozit, majd kdoljuk a fenti
hrom rszt.
Program kerete
C++ nyelven a program kerett az a main fggvny adja, amelynek
blokkjban (kapcsos zrjelekkel kzre zrt rszn) elhelyezett utastsok
vgrehajtsval kezddik a program futsa. A blokk utastsai
pontosvesszvel vagy csuk kapcsos zrjellel vgzdnek. Ezek egyfell
elklntik az utastsokat, msfell a kzttk lev sorrendet is
egyrtelmen kijellik.
Abban a forrsllomnyban (legyen ennek a neve most main.cpp),
ahol a main fggvnyt elhelyezzk, mg a fggvny eltt le kell rnunk kt
sort. Az els, az
#include
a konzolablakos input/output mveletek defincijt tartalmaz iostream
knyvtri csomagra hivatkozik, a msodik arra szolgl, hogy cin, cout
azonostkat ne kelljen std::cin, std::cout formban rni.
#include
using namespace std;
int main()
{
...
return 0;
}
-
30
A pontozott rsz helyre kerlnek majd az utastsok. A return 0 a
program futst lellt utasts. A nulla rtk a minden rendben zenetet
szimbolizlja. A main fggvny eltti int (integer, egsz szm tpus)
szcska a visszatrsi rtk (ami teht most a nulla) tpust jelzi.
Deklarcik
C++ nyelven egy vltoz deklarcija a kd tetszleges helyn elhelyezett
nll utasts:
tpus vltoz
A C++ nyelvben a termszetes szmok tpusnak nincs az egsz szmok
tpustl klnbz jele. (Az eljel nlkli, unsigned, egszeket mi nem
hasznljuk.) Tbb azonos tpus vltoz deklarcijakor a kzs tpusnv
utn vesszvel elvlasztva is felsorolhatjuk a vltoz neveket.
int x, y, z;
Az egsz szmok (itt termszetes szmok) tpusa megengedi az
alapmveletek (+, *, -, /) hasznlatt. Az oszts itt az gynevezett egsz-
osztst jelenti, azaz kt egsz rtk hnyadosa is egsz lesz: annyi, ahnyszor
az oszt megvan az osztandban, az osztsi maradk pedig elvsz. Az osztsi
maradkot kln mvelettel szmolhatjuk ki. Ennek a mveletnek a jele C++-
ben a %. A szmokra rvnyesek mg az sszehasonlt (kisebb, nagyobb,
egyenl, nem-egyenl) relcik is.
Absztrakt program kdolsa
Az absztrakt programban szerepl x mod y kifejezst a C++-ban x%y alakban
kell rni; az rtkads jobboldali kifejezse teht megengedett C++ nyelvben,
gy maga az rtkads is megengedett. A kdols nem okoz klnsebb
gondot, ha ismerjk az rtkadsnak a C++ nyelvi alakjt.
-
31
A vltoz:=kifejezs rtkadst a C++ nyelvben vltoz=kifejezs
formban rjuk. Az rtkads-utastsok utn mindig pontosvessz ll
kivve, ha az nem nll utastsknt, hanem egy kifejezs rszeknt
jelenik meg.
Az absztrakt programunk C++ nyelv kdja teht egyetlen rtkads
utastsbl ll, amit az albbi mdon runk le.
z = x % y;
Bemen adatok beolvassa
A beolvass sorn kt problmt is meg kell oldanunk. Egyfell el kell juttatni
a program futsa sorn a felhasznl ltal begpelt szmokat az x s y
vltozkba, msfell ellenrizni kell, hogy ezek a szmok a feladat
szempontjbl helyesek-e. Ez utbbi valjban hrom fle ellenrzst jelent.
Egyrszt vizsglni lehetne, hogy a felhasznl tnyleg szmot ad-e meg, mert
csak ebben az esetben kerlhet a bemen vltozinkba futsi hiba nlkl
rtk. (Ilyen ellenrzst most nem vgznk, de ksbb majd megmutatjuk,
hogyan lehet ezt megtenni.) Msrszt, mivel a vltozink egsz szmokat
tartalmazhatnak, de a feladat csak termszetes szmokrl szl, vizsglni kell,
hogy a beolvasott szmok nem negatvok-e. Harmadrszt pedig a feladat
elfelttelt is ellenrizni kell, azaz hogy a msodik szm nem nulla-e.
Szmot (de karaktert vagy karakterlncot is) gy tudunk beolvasni,
hogy az annak rtkt ler (billentyzeten keletkezett) jelekbl kpzett
adatot az billenty lenyomsnak hatsra a megfelel tpus
vltozba irnytjuk:
cin >> x
Egy beolvas utasts ltalban nem ll nmagban; megelzi azt egy
kirs. Beolvasskor ugyanis a program futsa megszakad s vr az
billenty letsre. Megfelel tjkoztats hinyba a felhasznl ilyenkor
nem tudja, mit csinljon, s ezrt is vrni fog, majd arra gondol: Na, ez a
-
32
program lefagyott!. Ezrt a beolvass eltt zenjk meg a felhasznlnak
pldul a konzolablakba trtn kirssal azt, hogy mit vrunk tle.
Programunkban az osztand beolvassa a kvetkez utastsokkal
vgezhet el.
cout > x;
Az adatok beolvassa utn kvetkezik az adatok ellenrzse. Azzal
teht most nem foglalkozunk, ha a felhasznl nem egsz szmot adna meg;
egyelre felttelezzk, hogy ez trtnt. Azt viszont megvizsgljuk, hogy az
els szm nem-negatv, a msodik szm pedig pozitv. Az ellenrzseket
kln-kln, kzvetlenl az adott adat beolvassa utn vgezzk. Ez egy
feltteltl fgg tevkenysg: ha a vizsglt szm negatv, akkor hibajelzst
runk a konzolablakba s lelltjuk a program futst (Ksbb ennl
rugalmasabb megoldssal is megismerkednk.) Ellenkez esetben tovbb
engedjk a program futst. Ennek lershoz egy elgazs utastst fogunk
hasznlni.
Az elgazs legegyszerbb C++ nyelvbeli formja az if utasts. Az if
kulcssz utni kerek zrjelpr kz kell egy logikai rtk kifejezst rni,
amelyik teljeslse esetn (amikor a kifejezs igaz rtk) hajtdik vgre a
kerek zrjelpr utn rt utasts, az gynevezett if g (ms nyelvekben
szoktk ezt then gnak is hvni). Ez az utasts lehet egyszer (ilyenkor a
vgt pontosvessz jelzi), de lehet sszetett, tbb utasts szekvencija,
amelyet egy gynevezett utasts blokkba (kapcsos zrjelek kz) kell zrni.
Az if gnak a vgrehajtsa utn a vezrls tbbnyire az elgazs utni
utastsra kerl (hacsak az if g mst nem r el). Ha az elgazs felttele
nem teljesl (rtke hamis), akkor a vezrls tugorja az if gat, s az
elgazs utni utastsnl folytatdik.
if(felttel) utasts; vagy if(felttel)
{
utasts1;
-
33
utasts2;
...
}
A felttel egy logikai rtket hordoz kifejezs. Ilyen kifejezs
brmelyik alaptpus rtkeibl kpezhet, ha azokra alkalmazzuk az
sszehasonlts relcikat. Ilyen az egyenlsg (==), a nem egyenlsg (!=),
a kisebb (=).
cout > x;
if (x
-
34
eltr brmelyik (pldul az 1-es) kd, valamilyen programhibra utal. Az y
vltoz rtknek ellenrzsekor a nulla rtk is hibsnak szmt.
Ha a programunkat egy integrlt fejleszt eszkz keretben futtatjuk,
akkor ott tbbnyire hozzpl a programunkhoz egy olyan funkci, amely a
program befejezdse utn mg nyitva tartja az alkalmazs konzolablakt,
gy lesz idnk a legutoljra kirt zeneteket, eredmnyeket elolvasni, s az
ablak csak kln felhasznli beavatkozsra tnik el. Ha azonban ugyanezt a
programot a fejleszt krnyezeten kvl indtjuk el, akkor nem fog mkdni
ez a funkci: a program befejezdsekor a konzolablak eltnik. Ez a jelensg
kivdhet, ha a programunk minden kilpsi pontjnl elhelyeznk egy
vrakoz utastst. Opercis rendszertl fggetlen, teht ltalnos, minden
krnyezetben megfelelen mkd, ugyanakkor felhasznlbart vrakoz
utastst nem knny tallni, a C++ nyelvben sincs ilyen. Van azonban egy
ltalnos, minden krnyezetben mkd br nem tl elegns megolds a
vrakozs megoldsra.
char ch;
cin >> ch;
Ez a kt utasts egy karakter tpus vltozba olvas be rtket
(karaktert), s amg a felhasznl a karakter begpelse utn nem t
-t, addig vrakozik. Nem tl knyelmes megolds, hiszen kt
billenty letse kell hozz, de univerzlis.
Eredmny kirsa
Adatot, egy kifejezs rtkt gy tudunk kirni, hogy azt a cout-ra irnytjuk.
A z vltozban keletkez eredmnyt a
cout
-
35
Egy szveges zenet kirsa a konzolablak aktulis sorba:
cout
-
36
szempontjbl helyes-e a program. Ilyenkor a teszteseteket a feladat
szempontjbl lnyeges vagy extrm adatok kiprblsnak cljbl
ksztjk. Ezek kztt megklnbztetjk az rvnyes teszteseteket (amikor
a bemen adat kielgti a specifikci elfelttelt) az rvnytelen
tesztesetektl (amikor azt vizsgljuk, hogyan viselkedik a program az
elfelttelt nem kielgt adatokra).
rvnyes tesztesetek:
1. Olyan szmprok, amikor az osztsi maradk nulla (Pl: 24, 8 )
2. Olyan szmprok, amikor az osztsi maradk egy (Pl: 9, 4 vagy 9, 8
vagy 1, 7)
3. Olyan szmprok, amikor az osztsi maradk az osztnl pont eggyel
kisebb (Pl: 9, 5)
4. Olyan szmprok, amikor az osztand kisebb az osztnl (Pl: 4, 5)
5. Olyan szmprok, amikor az osztand nulla (Pl: 0, 7)
rvnytelen tesztesetek:
1. Olyan szmprok, amikor az oszt nulla. (Pl: 15, 0).
2. Mindkt szm nulla.
3. Olyan szmprok, amikor az osztand negatv. (Pl: -6, 8)
4. Olyan szmprok, amikor az oszt negatv. (Pl: 6, -8)
5. Olyan szmprok, amelyek negatvak. (Pl: -6, -8)
A fehr doboz tesztels a programkd alapjn kszl. Mivel a
programunk szerkezete most egyltaln nem bonyolult, ennek a tesztelsnek
itt nincs nagy jelentsge. Legfeljebb az adatellenrzsi rszek elgazsainak
tesztelsvel lehetne foglalkozni. Ezeket azonban az rvnytelen tesztesetek
sorn mr kiprbltuk.
-
37
Teljes program
Vgl nzzk meg teljes egszben a programkdot. Az utastsok kztt
megjegyzseket (kommenteket) is elhelyeztnk a knnyebb
ttekinthetsg vgett. Megjegyzsnek szmt a // utni sor, illetve a
/* s */ ltal kzrefogott szveg, amelyeket a fordt figyelmen kvl
hagy.
Lthat, hogy az utastsok vgt tbbnyire pontosvessz jelzi.
Az, hogy mi szmt utastsnak, mikor lehet a pontosvesszt elhagyni,
ksbb tisztzzuk. Egyelre jegyezzk meg azt, hogy a deklarcik,
rtkadsok, beolvassok s kirsok utn, valamint a using
namespace std s return 0 utastsok utn mindig van
pontosvessz.
#include
using namespace std;
int main()
{
int x, y, z;
// Adatok beolvassa s ellenrzse
cout > x;
if (x
-
38
}
cout > y;
if (y
-
39
2. Feladat: Vltoz csere
Cserljk ki az egsz szmokat tartalmaz kt vltoz rtkeit! Olvassunk be
kt egsz szmot a billentyzetrl, vgezzk el a csert, majd az eredmnyt
rjuk ki a konzolablakba!
Specifikci
A feladatban kt egsz szm tpus vltoz szerepel, amelyek egyszerre
bemen- s eredmny-vltozk is. A specifikciban lnyeges szerepet
jtszanak a vltozk kezdetben megadott rtkei (x s y), hiszen gy tudjuk a
clfelttelben lerni azt, hogy az x vltoz az y kezdrtkt, az y vltoz
pedig az x kezdrtkt veszi fel. A bemen rtkekre semmilyen
megszortst nem kell tenni.
A = ( x, y : )
Ef = ( x=x y=y )
Uf = ( x=y y=x )
Absztrakt program
A szmtsok elvgzst megold algoritmus a clfelttelbl add szimultn
rtkadsbl ll.
x, y := y, x
Az x,y:=y,x szimultn rtkadst gy kell rteni, hogy egyidejleg
hajtjuk vgre az x:=y s az y:=x rtkadsokat. Arra kell itt majd figyelni,
hogy ez a szimultn rtkads nem ekvivalens az x:=y s y:=x rtkadsok
szekvencijval.
Implementls
-
40
A programkd ellltsnl elszr elksztjk a program kerett, majd
deklarljuk a vltozkat, kdoljuk az absztrakt programot, amely el a kt
vltoz kezd rtknek beolvasst vgz kd, utna pedig ugyanezen
vltozk rtkt kir kd kerl.
Program kerete
#include
using namespace std;
int main()
{
...
return 0;
}
Deklarcik
int x, y;
Absztrakt program kdolsa
Absztrakt programjainkban gyakran alkalmazunk szimultn rtkadsokat.
Ezek egyszerre tbb vltoz szmra jellnek ki j rtkeket. A C++ nyelvben
ezek kzvetlen kdolsra nincs lehetsg, azt elbb szt kell bontanunk
egyszer rtkadsok egyms utn trtn vgrehajtsra, azaz
szekvencijra. Pldul az x,y := 3,5 rtkadst az x:=3 s y:=5 rtkadsok
-
41
tetszleges sorrendje helyettestheti. Az x,y:=y,5 rtkads (az x vegye fel y
eredeti rtkt, az y j rtke pedig legyen 5) felbontsnl viszont szre kell
vennnk, hogy az y:=5 rtkadst csak az x:=y rtkads utn szabad
vgrehajtani, klnben az x nem kapja meg y eredeti rtkt, hanem csak az
jat, az 5-t. Az x:=y rtkads fgg az y:=5 rtkadstl, pontosabban annak
helytl.
Az x,y:=y,x szimultn rtkadsban az x:=y s az y:=x rtkadsok
klcsnsen fggenek egymstl. Ezrt ahhoz, hogy a szimultn rtkadst
egyszer rtkadsok szekvencijra felbontsuk, egy segdvltozt is be kell
vezetni: z:=x; x:=y; y:=z.
Ha specilisan egsz tpus vltozkrl van sz mint most a pldban
akkor egy msik lehetsg is knlkozik. Az itt felrt vltozatok helyessgt
az els ktetben trgyalt mdszerrel lthatjuk be.
z := x x := x - y
x := y y := x+ y
y := z x := y - x
Ennek megfelelen az absztrakt program kdja vagy
int z;
z = x;
x = y;
y = z;
vagy
x = x - y;
-
42
y = x + y;
x = y - x;
lesz. Az els vltozat a segdvltoz deklarcijt is tartalmazza.
Bemen adatok beolvassa
A beolvass rsz igen egyszer. Mindssze azt kell egyrtelmv tenni, hogy
mikor adunk rtket az els, mikor a msodik vltoznak, hiszen az
eredmnyt csak ennek fnyben tudjuk majd rtelmezni.
cout > x;
cout > y;
Adatellenrzsre most nincs szksg: a feladat elfelttele ugyanis
nem tett megszortst s felttelezzk, hogy a felhasznl (megfelel
mret) egsz szmokat fog megadni.
Eredmny kirsa
Az eredmny megjelentse nem kvn magyarzatot.
cout
-
43
102), s amikor a msodik szm a nagyobb. Ezutn ebben a programban
kln fehrdoboz teszteseteket mr nem kell generlni.
Teljes program
Vgl nzzk meg teljes egszben a programkdot megjegyzsekkel s
vrakoz utastssal kiegsztve. Absztrakt program kdjaknt a msodik
vltozat szerepel.
#include
using namespace std;
int main()
{
int x, y;
// Adatok beolvassa s ellenrzse
cout > x;
cout > y;
// Szmts
x = x - y;
y = x + y;
x = y - x;
// Eredmny kirsa
cout
-
44
ch;
return 0;
}
C++ kislexikon
Program kerete #include
using namespace std;
int main()
{
return 0;
}
Deklarci tpus vltoz
rtkads vltoz = kifejezs
Beolvass
billentyzetrl
cin >> vltoz
cin >> vltoz1 >> vltoz2
Kirs kpernyre: cout
-
45
2. Strukturlt programok
Ebben a fejezetben arra szeretnnk rvilgtani, hogy hogyan lehet
minimlis, de jl megvlasztott programnyelvi kszlettel egy tetszleges
absztrakt programot kdolni. Konkrt feladatok megoldsn keresztl
ismerkednk meg a C++ nyelv alaptpusaival s vezrlsi szerkezeteivel.
Implementcis stratgia
Az elemi programok adott programnyelvre trtn lekpezse
tbbnyire igen egyszer. Az res (semmit nem csinl, SKIP) program
kdolshoz ltalban semmit nem kell rni; az rtkadsnak is minden
nyelven van megfelelje. A szimultn rtkadst azonban ltalban
nem tudjuk kzvetlenl kdolni (kivtel pldul a Python nyelv), ezrt
azt elbb t kell alaktani kznsges rtkadsok szekvencijra (lsd
elz fejezet 2. feladat), s ha szksges, ehhez egy vagy tbb
segdvltozt is bevezethetnk.
Ha a kdoland programrsz egy nevezetes vezrlsi szerkezet,
akkor az annak megfelel nyelvi elemet kell hasznlni. Egy szekvencia
esetn kln kdoljuk a szekvencia egyes tagprogramjait, s azokat
egyms utn, a szekvenciban rgztett sorrendben rjuk le.
Elgazsnl az egyes gakat ad programokat kell kln-kln kdolni,
s azokat az elgazs utastsba begyazni. Ciklus esetn a ciklusmag
kdjt kell a ciklus-utastsban elhelyezni.
d,c := n,m rtkads
c d ciklus-
utasts
szekvencia
c
-
46
d := dc c := cd rtkads utasts
2-4. bra. Strukturlt program kdolsa
Egy strukturlt program kdolsa a benne lev
programszerkezetek mentn, kvlrl befel vagy bellrl kifele
haladva trtnik. A kvlrl befele halad stratgia (top-down) sorn
az absztrakt programban megkeressk annak legkls vezrlsi
szerkezett, meghatrozzuk e szerkezet komponenseit (szekvencia
esetben az egymst kvet rszprogramokat, elgazsnl az egyes
gak programjait s a hozzjuk tartoz feltteleket, ciklusnl a
ciklusmagot s a ciklusfelttelt), s lerjuk az adott szerkezetet kifejez
utastst. Ennek meghatrozott pontjain kell majd a komponensek
kdjait elhelyezni. Ezutn a programkomponenseken megismteljk az
elz eljrst. Ha egy rszprogram mr nem sszetett (res vagy
rtkads), akkor a megfelel elemi utastssal kdoljuk. A bellrl
kifele halad stratginl (bottom-up) ppen az ellenkez irnyba
haladunk. Elszr az absztrakt program elemi utastsait kdoljuk,
majd mindig kivlasztjuk az absztrakt programnak egy olyan vezrlsi
szerkezett, amelynek rszprogramjait mr kdoltuk, s a nyelv
megfelel vezrlsi utastsval ezeket a rszprogramokat egy kzs
kdba fogjuk ssze.
Az absztrakt programok kdolsa sorn vltozkat hasznlunk,
ezeket deklarljuk, rtket adunk nekik s az rtkket felhasznljuk. Ehhez
ismerni kell a hasznlhat (megengedett) adattpusokat, azokat a
szablyokat, ahogyan a tpusok mveleteinek segtsgvel kifejezseket
tudunk szerkeszteni a vltozkbl s a tpusrtkekbl. Ezek a kifejezsek
jelennek meg az rtkadsok jobboldaln, az elgazsok s ciklusok
felttelben.
Nyelvi elemek
-
47
A vltoz:=kifejezs rtkads C-szer nyelvekben trtn kdolsval az
elz fejezetben mr tallkoztunk. Fontos, hogy a vltoz = kifejezs
formj utastsban a kifejezs rtknek tpusa meg kell, hogy egyezzen a
vltoz tpusval. Ettl azonban bizonyos esetekben eltekinthetnk. Pldul
egy egsz rtk gond nlkl rtkl adhat vals tpus vltoznak. C++
nyelven ennek a fordtottja is megtehet, de ilyenkor az rtkl adott vals
szm trtrsze elvsz, csak az egsz rsze addik t az egsz tpus
vltoznak. A programozsi nyelvek pontosan definiljk a tpus-
kompatibilitsi szablyokat, azaz hogy milyen eltr tpusok kztti engedjk
meg az rtkadst, hogyan lehet egy rtket msik tpusra konvertlni,
mikor kvetkezhet be adatveszts. Ezekkel ebben a knyvben ltalnosan
nem foglalkozunk, csak a konkrt helyzetekre nzve alaktunk ki egy
biztonsgos kdolsi szokst. Ennek els ajnlsa az, hogy trekedjnk arra,
hogy egy rtkads baloldaln lev vltozjnak s a jobboldaln lev
kifejezsnek azonos legyen a tpusa.
Az rtkads hatsra a vltoz a kifejezs rtkt veszi fel. A C-szer
nyelvekben azonban az rtkadsnak rtke is van, ez pedig ppen az rtkl
adott kifejezs rtke. Az rtkads kifejezs tulajdonsgt hasznljuk ki
pldul a vltoz1 = vltoz2 = kifejezs; utastsban is, amely
mindkt vltoznak a kifejezs rtkt adja, mert az els rtkads
jobboldaln lthat msodik rtkadsnak van rtke, amely a msodik
rtkads jobboldali kifejezsnek rtke. Az, hogy egy rtkads egyben
kifejezs is, szmos bonyodalmat okozhat. Pldul egy C++ program
fordtsakor tbbnyire nem kapunk hibazenetet akkor, ha egy
egyenlsgvizsglatnl helytelenl nem a C++ nyelvnl hasznlatos dupla
egyenlsgjelet (==), hanem a matematikban egybknt szoksos szimpla
egyenlsgjelet hasznljuk, ami azonban itt az rtkads jele. Gondoljunk
pldul arra, hogy el akarjuk dnteni egy vltozrl, hogy az rtke egyenl-
e eggyel, de az i==1 kifejezs helyett hibsan az i=1 rtkadst rjuk. (Nem
tallkoztam mg olyan programozval, aki legalbb egyszer ne kvetett volna
el ehhez hasonl hibt.) Ilyenkor magnak az rtkadsnak az rtke is egy,
amit a C++ nyelv igaz logikai rtknek tekint. Teht ez az rtkads egy
logikai kifejezsnek is tekinthet, amelynek az rtke igaz, mikzben
vgrehajtsakor mellkesen a vltoz az egyet veszi fel j rtkknt. A
fordtprogram nem jelez hibt, de futskor nem a vrt mkds kvetkezik
-
48
be, radsul az rintett vltoz elveszti a korbbi rtkt, hiszen fellrjuk az
eggyel. Ezt a nem vrt jelensget elkerlend clszer, ha az az i==1 jelleg
vizsglatokban a konstanst rjuk baloldalra: 1==i, ugyanis az 1=i kifejezs
esetn biztosan fogunk hibajekzst kapni.
C++ nyelvvel specilis formj rtkadsok is rhatk. nll
utastsknt a ++i vagy az i++ hatsa egyenrtk az i = i+1
rtkadsval, a --i vagy i-- hatsa pedig az i = i-1 rtkadsval.
Ilyenkor rdemes a prefix vltozatokat (++i, --i) hasznlni. Ha viszont egy
kifejezsbe gyazzuk ezeket a specilis rtkadsokat, akkor nem mindegy,
hogy melyik alakot hasznljuk. Az i++ egy kifejezsben az i kezdeti rtkt
mutatja, s csak utna fogja megnvelni eggyel. A ++i elbb vgzi el az i
nvelst, s a kifejezs ezt megnvelt rkt kpviseli. (Hasonl a helyzet a
--i vagy i-- rtkadsokkal.) rdekes lehet tudni, hogy az olyan
rtkadsokat, mint i=i+a, i=i-a, i =i*a, stb. rvidebb alakban is lehet
C++ nyelven rni: i+=a, i-=a, i*=a, stb.
Megjegyezzk vgl azt is, hogy egy vltoz deklarcija sszevonhat
azok els (kezdeti) rtkadsval. A
tpus vltoz = rtk
utasts a vltoz defincijval egyidejleg kezdrtket is ad a vltoznak.
C++ nyelven a vltozk deklarlsa is egy elemi utasts. Ennek sorn
foglaldik le a vltozban trolt rtk szmra a megfelel memria terlet.
Ennek mrete a vltoz tpustl fgg. Tekintsk most t a leggyakrabban
hasznlt alaptpusokat: az egsz szm, a vals szm, a logikai, a karakter s a
karakterlnc tpust.
Az egsz szm tpusnak egyik formjval, az int-tel mr
tallkoztunk. Ezt hasznljuk a termszetes szmok tpusnak kdolsra is.
Az egsz szmokat tbbnyire gynevezett kettes komplemens kdban
brzoljk a memriban. Ez a kdols a kettes szmrendszerbeli (binris)
brzolson tl a negatv szmok jellsnek sajtos technikjt jelenti. A
programozsi nyelvek (C++ is) tbb fajta egsz tpust is bevezet. Ezek abban
klnbznek, hogy eltr mret memria terletet jellnek ki a vltoz
szmra, gy klnbzik az ltaluk brzolhat legnagyobb s legkisebb egsz
-
49
szm. Olyan egsz szm tpus nincs, amelyikkel az sszes egsz szmot
brzolni lehet, hiszen a memria vgessge miatt minden esetben
brzolsi korltokba tkznk. Az, hogy legfeljebb s legalbb mekkora
egsz szmot lehet trolni egy egsz tpus vltozban, pldul az int tpus
esetn, az fordtprogram fgg.
Az egsz szmokra, illetve az egsz tpus vltozkra alkalmazhatjuk az
alapmveleteket (+, -, *, /, %), az sszehasonlt relcikat s nhny
beptett fggvnyt. Ne felejtsk el, hogy kt egsz szm osztsnak
eredmnye is egsz szm lesz. A mveletek nem minden esetben adnak
helyes eredmnyt: ha az eredmny nem brzolhat a vlasztott egsz tpus
ltal kijellt memria terleten, akkor tlcsorduls, s ebbl fakad
adatveszts jn ltre.
-
50
Egsz szmok kettes komplemens kdja
Az egsz szmok ltalnosan elterjedt kdolsa. A szmokat s biten
brzoljuk gy, hogy a szm abszolt rtknek binris alakja nullval
kezddjn. Ezrt az brzolhat szmok -2s-1 s 2s-11 kz kell, hogy
essenek, ellenkez esetben tlcsordulsrl beszlnk. A pozitv egsz szmot
annak binris alakjval kdoljuk (az els bit 0 lesz, ami jelzi, hogy a szm
pozitv), a negatv egsz szm esetn a szm abszolt rtknek binris
alakjt bitenknt invertljuk (0-bl 1-et, 1-bl 0-t csinlunk) s az gy kapott
s jegy szmhoz hozzadunk egyet. (Az els bit 1 lesz, ami jelzi, hogy a szm
negatv.)
1. Plda. Adjuk meg a +12 egsz szm kettes komplemens kdjt 4 bjton!
12(10) = 00000000 00000000 00000000 00001100(2)
2. Plda. Adjuk meg a -12 egsz szm kettes komplemens kdjt!
i) 12(10) = 00000000 00000000 00000000 00001100(2)
ii) Vegyk a binris alak komplemenst (invertlt alakjt)!
11111111 11111111 11111111 11110011
iii) Adjunk hozz binrisan 1-et!
11111111 11111111 11111111 11110100
A vals szmok tpusra is tbb lehetsg knlkozik a C++ nyelvben,
de tisztban kell lenni azzal, hogy ezek mindegyike csak vges sok vals szm
brzolsra kpes. Mindig lesznek olyan vals szmok, amelyek vagy olyan
nagy abszoltrtkek, hogy egyltaln nem jelenthetek meg
(tlcsorduls), vagy olyanok, amelyek helyett csak egy hozzjuk kzel es
msik vals szmot tudunk brzolni (kerektsi hiba). Ez utbbi specilis
esete az alulcsorduls, amikor nagyon kicsi szmok helyett a nulla kerl
brzolsra. (Ez akkor jelent klnsen problmt, ha egy ilyen szmmal
pldul osztanunk kell.) A vlaszthat vals tpusok a float, double s a
long double, amelyek a vals szmokat lebegpontosan brzoljk.
Mi ltalban a double tpust fogjuk hasznlni. A tpushoz tartoz
rtkeinek lersban szerepel vagy a tizedes pont, vagy a lebegpontos alak
jelzsre utal e bet:
-
51
1.23 .23 0.23 1 1.0 1.2e10 1.23e-15 1e10
Vals szmok lebegpontos szmbrzolsa
A vals szmok IEEE 754 szabvny szerinti (4 illetve 8 bjtos) lebegpontos
brzolsnl a szmokat ((-2)*b+1)*m*2k alakban rjuk fel, ahol b az
eljelbit (0 - pozitv, 1 - negatv), az m a mantissza (1 m
-
52
A double (float, long double) tpus rtkekre s vltozkra
megengedettek az alapmveletek, ezeken kvl a cmath csomagban szmos
olyan matematikai fggvnyt tallhatunk, amelyet vals szmokra
rtelmezhetnk. Ilyen pldul az sqrt() fggvny, amellyel ngyzetgykt
vonhatunk egy nem-negatv vals szmbl.
A karakter tpus jele C++ nyelven a char. Egy karakter-vltoz
karaktereket vehet fel rtkl. A tpus rtkeit aposztrfok kz rva tudjuk a
kdban kzvetlenl lerni. Karaktereket ssze lehet hasonltani az egyenl
(==) s a nem-egyenl (!=) opertorokkal. rvnyesek a kisebb s nagyobb
relcis jelek is, de ezek eredmnye a vizsglt karakterek kdjtl fgg.
Karakterek brzolsa
Egy adott karakterkszlet elemeit, karaktereit megsorszmozunk 0-val
kezdden, s ezeket a sorszmokat troljuk binrisan kdolva a megfelel
karakter helyett. Az egyik legegyszerbb az ASCII karakterkszlet, amelyik
256 klnbz karaktert tartalmaz. A 0 s 255 kztti sorszmok binris
kdja egy bjton brzolhat. Az UTF-8 vltoz hossz kdolssal brzolja a
karaktereket (magba foglalja s 1 bjton brzolja az ASCII karaktereket, de
pldul az kezetes betk sorszmai 2 bjton kdoldnak.)
A karakterlncok tpusa a C++ nyelven a string. Ellenttben a tbbi
alaptpussal, ennek hasznlathoz szksg van az #include
sorra, s a using namespace std nlkl pedig csak std::string
alakban hasznlhatjuk. A tpus rtkeit idzjelek kz rt karakterlnccal
rhatjuk le.
A C++ nyelv a C nyelvbl fejldtt ki, s ezrt szmos, a C nyelvben is
hasznlhat elemet is tartalmaz. A C nyelvben a karakterlnc egy \0
rtkkel lezrt karaktersorozat. A C++ nyelvben e helyett jelent meg a
string tpus, de tovbbra is hasznlhatk mg C stlus karakterlncok is.
Ennek hasznlata akkor indokolt, amikor olyan mveletekre van szksg,
amelyeket csak a C stlus karakterlncokra definil a nyelv. Ilyenkor a C++
stlus karakterlncot C stlus karakterlncc kell talaktani. Erre szolgl a
c_str() fggvny: ha str egy string tpus vltoz, akkor az
-
53
str.c_str() kifejezs az str-ben tallhat karakterlnc C stlus
megfelelje lesz.
Karakterlnc brzolsa
A karakterlnc egy vltoztathat hosszsg karaktersorozat. A karakterek
kdjt sorban egyms utn troljuk el. A sorozat hosszt vagy egy kln
szmll vagy a lnc vgn utols utni karakterknt elhelyezett specilis
karakter (\0) jelzi.
A \ karakternek egy karakterlncban ltalban specilis jelentse van:
az azt kvet karakterrel egytt tbbnyire a karakterlnc megjelentsvel
kapcsolatos tevkenysget vezrli. Ilyen pldul a \n, amelyik a karakterlnc
kirsakor nem ltszik, de a kirsnl sortrst eredmnyez. Vagy a \t, amely
utn a kirs egy tabultornyival jobbra folytatdik. Ha viszont kifejezetten a
\-t tartalmaz sztringet akarjuk lerni, akkor azt meg kell duplzni:
"c:\\Program Files".
Egy string tpus str vltozra nagyon sok mvelet alkalmazhat.
Lekrdezhetjk a hosszt: str.size() vagy str.length();
lekrdezhetjk vagy megvltoztathatjuk az i-edik karaktert: str[i]; a + jel
segtsgvel sszefzhetnk kt karakterlncot. Lehetsg van a
karakterlncok lexikografikus sszehasonltsra is. Egy karakterlncnak ki
lehet hastani egy darabjt is: str.substr(honnan, mennyit). A find()
fggvnycsald (sok vltozata van) egy sztringben keres karaktert vagy rsz-
sztringet, annak sztringbeli pozcijt adja vissza, ha nem tall, akkor a
string::npos extremlis rtket. Lehet a sztring adott pozcijtl
kezdden keresni az els vagy az utols elfordulst. A sztringet
megvltoztat fggvnyek kztt talljuk a karaktert vagy rsz-sztringet
adott pozcira beszr (insert), adott pozcirl trl (erase), adott
pozcin helyettest (replace) mveleteket.
A logikai tpus jele C++ nyelvben a bool. A tpus rtkei a false
(hamis) s a true (igaz). A tpus mveletei a logikai s (jele: &&), a logikai
vagy (jele: ||) s a tagads (jele: !). Logikai rtk kifejezshez jutunk, ha
tetszleges tpus kifejezsek kztt alkalmazzuk a relcis jeleket (==,
-
54
, >=). Ilyen kifejezsekbl s logikai vltozkbl sszetett logikai
kifejezseket is szerkeszthetnk. A logikai mveleti jelek eltr prioritsak:
a tagads a legersebb, a vagy a leggyengbb mvelet. Pldul az u&&!v||w
kifejezs egyenrtk az (u&&(!v))||w kifejezssel. Ha nem vagyunk
biztosak a prioritsi szablyokban, akkor inkbb zrjelekkel tegyk magunk
szmra egyrtelmv a kifejezseinket.
Logikai rtk brzolsa
Habr a logikai rtkek (igaz vagy hamis) trolsra egyetlen bit is elg lenne,
de mivel a legkisebb cmezhet egysg a memriban a bjt, ezrt legalbb
egy bjtot foglalnak el. A nulla rtk (csupa nulla bit) bjt a hamis rtket,
minden ms az igaz rtket reprezentlja.
A programozsi nyelvek az utastsok vgrehajtsi sorrendjt
(szekvencijt) az utastsok egyms utni elhelyezsvel jellik ki. Az
utastsok vgrehajtsa ennek a sorrendnek megfelelen, elejtl a vgig,
egyms utn szekvenciban trtnik. Ez egyben azt is jelenti, hogy a
szekvencia vezrlsi szerkezetet az t alkot programok kdjainak egyms
utn rsval tudjuk kifejezni. Tbb utasts szekvencija befoglalhat egy
gynevezett utastsblokkba, amelyet a fordt egyetlen br sszetett
utastsknt kezel.
Vannak nyelvek, ahol a szekvencia minden tagjt j sorban kezdve kell
lerni, de a C++ nyelven ez nem szksges, hiszen egyrtelmen ltszik egy
utastsnak a vge, ami egy pontosvessz vagy egy csuk kapcsos zrjel.
ltalnosan elfogadott szoks azonban, hogy a szekvencia minden egyes
rszt kln sorban kdoljuk. Tbb utasts szekvencijt egyetlen
sszetett utastsba zrhatunk, ha azt utastsblokknt egy nyit s egy
csuk kapcsos zrjel kz helyezzk. Ezt a blokkot nem kveti pontosvessz,
de a blokkbeli utastsokat pontosvessz zrja le. C++ nyelven olyan specilis
utastsok is rhatak, amelyek ugyancsak szekvencit kdolnak: ilyen pldul
a mr emltett vltoz1 = vltoz2 = kifejezs utasts, amely
elszr a vltoz2-nek adja rtkl a kifejezs rtkt, majd a
-
55
vltoz1-nek. Az ilyen rvidtsekkel azonban vatosan bnjunk, mert mr
egy egyszerbb sszettel rtelmezse sem egyrtelm (pl. i = j = i++).
A programozsi nyelvek ltalban rendelkeznek az gynevezett if-then
elgazs utastssal, (C++ nyelven: if(felttel) g ), amely az albbi
absztrakt program megfelelje:
Az elgazs utastsnak szokott lenni egy klnben (else) ga is,
amely akkor kerl vgrehajtsra, ha az if felttele nem teljesl. Ilyenkor a
vezrls az if gat tugorva az else gra kerl. Ha nem runk else gat, az
olyan mintha az else g az res (semmit nem csinl) program lenne. C++
nyelven az gak llhatnak egyetlen egyszer (pontosvesszvel lezrt)
utastsbl, vagy tbb utastst tartalmaz utastsblokkbl. sszetett gak
esetn a C++ nyelven tbbfle rsmdot is szoktak alkalmazni:
if(felttel) if(felttel){ if(felttel){
{ g_1 g_1
g_1 } }else{
} else{ g_2
else g_2 }
{ }
g_2
}
Amikor az egyes programgak egyetlen utastsbl llnak, akkor nem
szksges az utastsblokk hasznlata. Azt javasoljuk azonban, hogy egyetlen
utastsbl ll gat is zrjunk utastsblokkba. Ha ezt mgsem tennnk,
felttel
g SKIP
-
56
akkor ilyenkor az utastsokat az if illetve else kulcsszval azonos sorba
rjuk.
if(felttel) utasts_1;
else utasts_2;
Az if-then-else utasts teht lehetv teszi az olyan struktogrammok
kdolst is, ahol egyik g sem res program. Egy ltalnos elgazsnak
azonban kettnl tbb ga is lehet, s minden ghoz egyedi felttel
tartozik, azaz egy g nem akkor hajtdik vgre, ha egy msik felttele nem
teljesl. Viszonylag kevs programozsi nyelv rendelkezik az ilyen valdi
tbbg elgazst kdol utastssal.
Itt jegyezzk meg, hogy az absztrakt tbbg elgazs nem-
determinisztikus (ha tbb felttel is igaz, akkor nem eldnttt, hogy melyik
programg hajtdik vgre), s abortl, ha egyik felttel sem teljesl. ppen
ezrt nem teljesen egyenrtk a fenti struktogramm s annak talaktsval
kapott albbi vltozat, amely egymsba gyazott if-then-else elgazsokkal
mr egyszeren kdolhat:
felttel1
g1
felttel2
g2
feltteln
gn SKIP
Az talaktott vltozat minden esetben az els olyan gat hajtja vgre,
amelyik felttele teljesl, s res programknt mkdik, ha egyik felttel
felttel1 felttel2 ... feltteln
g1 g2 ... gn
-
57
sem igaz. A kt vltozat csak akkor lesz azonos hats, ha az elgazs
felttelei teljes s pronknt diszjunkt rendszert alkotnak. Ennek hinyban
is igaz azonban az, hogy ha egy feladat megoldshoz egy helyesen mkd
sokg elgazst terveztnk, akkor annak a fent bemutatott talaktott
vltozata is helyesen fog mkdni.
C++ nyelven a sokg elgazst egymsba gyazott if-else-if
elgazsokkal kdolhatjuk:
if(felttel_1){
g_1
}
else if(felttel_2){
g_2
}
else{
g_n+1
}
A struktogrammokban az gynevezett ell tesztel ciklust hasznljuk.
Egy ell tesztel ciklus mindannyiszor jra s jra vgrehajtja a ciklusmagot,
valahnyszor a megadott felttel (ciklusfelttel) teljesl.
felttel
mag
Az absztrakt program (ell tesztels) ciklust C++-ban a while(){}
utastssal kdoljuk, ahol a while kulcssz utni kerek zrjelpr
tartalmazza a ciklusfelttelt, az azt kvet kapcsos zrjelpr pedig a
-
58
ciklusmagot. (A kapcsos zrjelpr ugyan elhagyhat, ha a ciklusmag
egyetlen utastsbl ll, de ezt az rsmdot nem javasoljuk. Ha mgis
megtennnk, akkor ebben az esetben a ciklusutastst rjuk egy sorba.)
ltalban az albbi rsmdok valamelyikt hasznljuk:
while(felttel){ while(felttel)
mag {
} mag
}
Azoknl a programozsi nyelveknl, ahol a vltozk deklarlsnak a
helye kttt (pldul a Pascal nyelv), minden vltozt a program kijellt
helyn kell deklarlnunk. Ms nyelvek esetben a vltoz deklarcikat a
vgrehajthat utastsok kztt lehet elhelyezni (pldul a C++ nyelvben).
Mindkt esetben figyelembe kell venni azonban a vltozk egy specilis
tulajdonsgt, a lthatsgot. Egy vltoz lthatsgn a programszveg
azon rszt rtjk, ahol a vltozra hivatkozni lehet (azaz ahol leszabad rni a
vltoz nevt). Ez ugyanis nem felttlenl lesz a teljes programszveg. A
programszveg gyakran tbb, akr egymsba gyazhat egysgre, blokkra
bonthat. A C++ nyelven pldul minden kapcsos zrjelek kz rt kd
nll blokkot alkot, de nll blokk egy elgazs- illetve a ciklusutasts is. A
blokkokat egymsba gyazhatjuk. Maga a main fggvny is egy blokk,
jelenlegi programjainkban ez a legkls. Egy blokkban deklarlt vltozt csak
az adott blokkban a deklarcit kvet rszben hasznlhatunk, csak ott
lthat. ppen ezrt krltekinten kell eljrni a vltoz deklarci helynek
megvlasztsakor. Pldul az gynevezett segdvltozkat elg csak azokban
a blokkokban, ahol tnylegesen hasznljuk ket.
Ha a programblokkok egymsba gyazdnak, akkor a kls blokkban
deklarlt vltoz a bels blokkban is lthat. Ezt a begyazott
programblokkra nzve globlis vltoznak szoktk nevezni. A bels
blokkban deklarlt vltoz viszont csak ott lesz lthat, a klsben nem, ez
teht egy loklis vltoz. Itt most egy relatv rtelemben vett globalitsi
fogalomrl beszlnk. (Ismeretes ezeknek a fogalmaknak egy szigorbb
rtelmezse is, amikor a programban mindenhol lthat vltozt nevezik
-
59
globlis vltoznak, a tbbit loklisnak. Ilyenkor abszolt rtelemben vett
globalitsrl beszlnk.)
Vgezetl fontos felhvni a figyelmet arra, hogy a programkdot
megfelel eszkzkkel C++ nyelven tabullssal (behzssal) ,
kommentekkel (megjegyzsekkel) s res sorokkal rdemes gy trdelni,
hogy ezzel szemlletess tegyk azt, hogy egy programegysg milyen mlyen
gyazdik egy msikba, ennl fogva knnyen azonosthatjuk egy vltoz
lthatsgi krt, azaz a vltoz deklarcijt tartalmaz programegysget.
2-5. bra. Vltoz lthatsga s lettartama
A deklarci helye nemcsak a lthatsgot befolysolja, hanem a
vltoz lettartamt is. Egy vltoz lettartamn a program f