Professional Documents
Culture Documents
0008 Simon PDF
0008 Simon PDF
SIMON GYULA
A PROGRAMOZS ALAPJAI
Egyetemi tananyag
2011
COPYRIGHT: 20112016, Dr. Simon Gyula, Pannon Egyetem Mszaki Informatikai Kar
Rendszer- s Szmtstudomnyi Tanszk
LEKTORLTA: Dr. Szebernyi Imre, Budapesti Mszaki s Gazdasgtudomnyi Egyetem
Villamosmrnki s Informatikai Kar Irnytstechnika s Informatika Tanszk
TMOGATS:
Kszlt a TMOP-4.1.2-08/1/A-2009-0008 szm, Tananyagfejleszts mrnk informati-
kus, programtervez informatikus s gazdasginformatikus kpzsekhez cm projekt kere-
tben.
ISBN 978-963-279-521-8
KULCSSZAVAK:
algoritmusok, programok, vezrlsi szerkezetek, adatszerkezetek, strukturlt program.
SSZEFOGLALS:
A jegyzet platform-fggetlen mdon igyekszik megismertetni a programozs alapjait, a struk-
turlt programozst. Trgyalja az alapvet programozi httrismereteket s alapfogalmakat
mind a hardver, mind a szoftver oldalrl. Bemutatja az algoritmusok s programok alapvet
ptelemeit, valamint a strukturlt programok ksztsnek alapvet szablyait. Az algorit-
musok s adatszerkezetek lersra tbbfle ler modellt is hasznl (folyamatbra, Jackson-
bra, regulris kifejezsek s defincik), valamint a C programozsi nyelv segtsgvel ezek-
re implementcis pldkat is mutat.
Fl a lbam, szemem fl, de n mgse flek,
Falbbal s bekttt szemmel kalz mdra lek.
Pisztolyommal tjutok minden akadlyon,
Vllamon meg csrg szpen reg papagjom.
Gryllus Vilmos
Tartalomjegyzk
Elsz ......................................................................................................................................... 7
1. Bevezets ............................................................................................................................. 9
1.1. A szmtgp felptse ............................................................................................. 9
1.1.1. A CPU .......................................................................................................... 10
1.1.2. A memria .................................................................................................... 13
1.1.3. A perifrik................................................................................................... 14
1.2. A programok ............................................................................................................ 15
1.2.1. A programok kezelse, futtatsa .................................................................. 15
1.2.2. Programok ksztse ..................................................................................... 16
1.2.3. Alacsony s magas szint nyelvek ............................................................... 16
1.2.4. Fordts s rtelmezs .................................................................................. 19
1.3. Httrismeretek ........................................................................................................ 22
1.3.1. Szmrendszerek, szmbrzols .................................................................. 22
1.3.2. Prefixumok ................................................................................................... 23
1.3.3. Az ASCII kdols ........................................................................................ 24
Vitorlt fel!
ILH
Bevezets
Krnyezetnkben nagyon sok fajta szmtgppel tallkozhatunk, nha taln fel sem merl
bennnk, hogy az egyltaln nem szmtgp-szer berendezs is tulajdonkppen egy (vagy
akr tbb) szmtgpet is rejthet magban. Ha a szmtgp szt halljuk, leginkbb egy asz-
tali vagy laptop szmtgp kpe ugrik be, de telefonjaink, autink, jtkaink is mind-mind
tartalmaznak szmtgpeket. Igaz, ezeknek nha nincs kpernyje s billentyzete sem, de
azrt felptsk s funkcijuk nagyon hasonlt asztali testvreikre. Ezekben is van CPU,
memria, kezelnek perifrikat, s ami a legfontosabb kzs vonsuk: programokat hajtanak
vgre azrt, hogy minket segtsenek, szrakoztassanak. Tekintsk teht t elszr szmtg-
peink felptst.
tartalmaz nhny nagyon hasonl elemet. A programjainkat minden szmtgpben agy (vagy
tbb) CPU hajtja vgre, fut programjainkat a memriban troljuk, s a programok a klvi-
lggal (velnk, felhasznlkkal is) perifrikon keresztl kommuniklnak.
A szmtgp fbb elemeit s azok kapcsolatt az 1.1. bra mutatja, ahol a kzponti egysg,
a CPU a memrival s klnfle perifrikkal ll kapcsolatban. Az rn lthatunk jl ismert
bemeneti perifrikat (pl. billentyzet), kimeneti perifrikat (pl. monitor), de a perifrik kz
tartoznak a httrtrak s pl. a hlzati kapcsolatot biztost hlzati csatol egysg is.
1.1.1. A CPU
A CPU rvidts az angol Central Processing Unit (kzponti vgrehajt egysg) kifejezsbl
szrmazik. Gyakran hasznlt elnevezs mg a processzor is. A nv jl kifejezi a CPU-k fel-
adatt: ezen a helyen trtnik a programok vgrehajtsa. Nmi tlzssal szoks a CPU-t
a szmtgp agynak is nevezni; a hasonlat kicsit sntt ugyan, hiszen a CPU nem gondolko-
dik, viszont villmgyorsan, tveds nlkl, szolgai mdon vgrehajtja a programok utastsait.
A programok vgrehajtsa kzben a CPU termszetesen kapcsolatot tart a memrival s
a perifrikkal. A processzor a memribl olvassa be a program utastsait, rtelmezi ezeket,
majd vgre is hajtja azokat. Az utastsok hatsra vltoztatsokat hajthat vgre krnyezetn
is (a memrin, vagy valamelyik perifrin). A processzorutastsok nagyon egyszerek (pl.
kt szm sszeadsa, egy memriacm olvassa/rsa), viszont cserben nagyon gyorsan vg-
rehajthatk: egy kommersz processzor a jegyzet rsakor msodpercenknt tbb millird uta-
stst is kpes volt vgrehajtani.
A processzorok nagyon bonyolult eszkzk, felptskkel, mkdskkel ms trgyak
foglalkoznak. Itt most rviden s a vgletekig leegyszerstve trgyaljuk a processzorok fel-
ptsnek alapvet elemeit, amelyek szksgesek ahhoz, hogy a programok vgrehajtsnak
folyamatt megrthessk.
A processzorok szmtsi kpessgeit az aritmetikai-logikai egysg (az angol Arithmetic
Logic Unit nvbl rviden ALU) biztostja. Ez az egysg kpes pl. sszeadni kt szmot,
vagy pl. bitenknt logikai S mveletet vgrehajtani kt szmon. Az utastsokat a processzor
utasts-beolvas egysge olvassa be memribl, majd azokat rtelmezve utastja pl. az
ALU-t a megfelel mvelet vgrehajtsra. A processzorban helyet foglal regiszterek gyors
bels memriaegysgek, melyek pl. az aritmetikai mveletek operandusait s eredmnyt
trolhatjk. A processzor aritmetikai s logikai utastsai ltalban egy vagy kt regiszter k-
ztt mkdnek s az eredmnyeket is valamelyik regiszterben troljk. (Vannak olyan pro-
cesszorok is, amelyek kpesek a memribl, a regiszterek megkerlsvel is bizonyos mve-
letek vgrehajtani, de nem ez a jellemz.) Tipikus aritmetikai/logikai mveletek lehetnek pl.
a kvetkezk:
Add ssze az R1 s R5 nev regiszterek tartalmt s tedd az eredmnyt az R3 nev re-
giszterbe.
Szorozd ssze a R1 s R2 regiszterek tartalmt, az eredmnyt helyezd az R8 nev re-
giszterbe.
Vgezz logikai kizr vagy (XOR) mveletet az R1 s R2 bitjei kztt, az eredmny
az R3-ban kpzdjn.
Cm Utasts Megjegyzs
0 MOVE 0, D ; a D regiszterben troljuk az sszeget, ez kezdetben legyen 0
1 MOVE 20, B ; a B regiszterben troljuk az adatok cmt, az els 20
2 MOVE (B), C; beolvassuk az aktulis adatot a C regiszterbe
3 ADD C, D ; sszeadjuk az aktulis adatot az eddigi sszeggel
4 MOVE A, D ; eltroljuk az eredmnyt a D regiszterbe
5 MOVE A, 1 ; az A regiszterbe betltnk egyet a kvetkez sszeadshoz
6 ADD A, B ; a B regiszterben lev cmet megnveljk 1-el
7 MOVE A, B ; az eredmnyt visszatltjk a B regiszterbe
8 MOVE 30, A ; az A regiszterbe betltjk a utols adat utni cmet (ez ppen 30)
9 SUB A, B ; majd kivonjuk ebbl a B regiszterben lv cmet
10 JMPNZ 2 ; ha nem 0 volt, akkor folytatjuk a kvetkez adattal (a 2-ik utasts-
cmtl)
11 MOVE D, (30) ; ha az eredmny 0, akkor vgeztnk, a D-ben lv eredmnyt elt-
roljuk
A program a memria 0-ik cmtl a 11-ig bezrlag foglal helyet. A fenti programlist-
ban az utastsokat az emberek szmra is rthet s olvasmnyos mnemonikjaikkal jelltk,
de a szmtgp memrijban termszetesen nem ezek, hanem az utastsok gpi kd meg-
feleli foglalnak helyet. Erre majd ltunk konkrt pldt is a 1.2.3. fejezetben.
Lthat, hogy ehhez az egyszer feladathoz is viszonylag sok utastsra volt szksg s
a feladat megvalstsa nem volt trivilis, ksznheten a furcsa utastskszletnek. Jllehet
ez mr emberi fogyasztsra sznt (mnemonikos) megjelents, a programra rpillantva nem
egyszer megmondani, mit is csinl. Persze, aki sokat programoz alacsony szinten, annak egy
ilyen utastskszlet termszetes. Akinek pedig a fenti kd els olvassra nem sokkal rthe-
tbb, mint egy egyiptomi hieroglifa, az se keseredjen el: mi a tovbbiakban majd magasabb
szint programozsi nyelveket fogunk hasznlni. De j, ha szben tartjuk, hogy minden prog-
ram ilyen primitv gpi utastsok sorozatv alakul t, mieltt szmtgpnk vgrehajtan
azt. s persze rtkeljk annak szpsgt is, hogy magas szint utastsokat hasznlhatunk
a primitv gpi utastsok helyett...
1.1.2. A memria
A memria adatok s programok trolsra szolgl a szmtgpben. Egy korszer architekt-
rj szmtgpben szmtalan helyen tallkozhatunk memrival, de mi most csak a sz-
munkra fontos elemmel, az operatv trral foglalkozunk, a memria szt ezen rtelemben fog-
juk hasznlni. (Ms, pl. cache memriknak is fontos szerepe van a hatkony, gyors mkds
biztostsnl, de ezek nlkl is mkdhetnek szmtgpek, radsul a programozs szem-
pontjbl ezek mintha nem is lteznnek, ezrt mi most ezeket nem trgyaljuk.)
Az operatv trban foglalnak helyet az ppen fut programok s a program ltal hasznlt
adatok. Az adatmemria trolja a bemeneti s kimeneti adatokat, a program futsa kzben
hasznlt tmeneti adatokat; programjaink az adatmemrit futs kzben olvassk s rjk is.
A programmemria tartalmazza a fut programot; ez is rhat s olvashat memria: a CPU
1.1.3. A perifrik
A perifrik biztostjk, hogy vgrehajts alatt ll programjaink kpesek legyenek a klvi-
lggal is kapcsolatot tartani, pl. bemen adatokat beolvasni vagy az eredmnyt kirni.
Az egyik legfontosabb perifria a httrtr. A httrtr egy nem felejt memria (ellenttben
az operatv trban alkalmazott memrival), gy a httrtrra rt informcik akkor is megr-
zdnek, ha a gpnket kikapcsoljuk, vagy ppen laptopunkbl kifogy az akkumultor. A ht-
trtrak tipikusan sokkal nagyobb kapacitsak, mint az operatv tr, gy lnyegesen tbb adat
trolhat benne. A httrtrak azonban lnyegesen lassabbak is, mit az operatv tr. Tipikus
httrtrak a merevlemezek, a szilrdtest meghajtk (SSD meghajtk), vagy a CD s DVD
alap trolk. A httrtr szerepe teht az, hogy programjainkat s adatainkat arra az idre is
trolja, amikor azok nem az operatv trban vannak.
A httrtron kvl szmos perifrival tallkozhatunk a szmtgpnkn. Tipikus beme-
neti perifrik pl. a billentyzet vagy az egr, kimeneti perifrik a monitor vagy a nyomtat,
ki-bemeneti perifrik pldul a hangkrtyk vagy a hlzati csatol krtyk.
A perifrik gyakran maguk is bonyolult berendezsek, amelyek akr sajt beptett kis
szmtgppel is rendelkezhetnek. A perifrik kezelse nem egyszer feladat, ezrt ennek
terht az opercis rendszer s klnfle meghajt programok veszik le a vllunkrl, gy
programjainkbl knyelmesen tudjuk ezeket kezelni, fggetlenl attl, hogy ppen milyen
tpus s gyrtmny perifrit hasznlunk.
1.2. A programok
A szmtgpes program a szmtgp szmra rtelmezhet utastsok sorozata, melyek egy
adott feladat megoldsra szolglnak. Egy szmtgpes rendszerben szmos programmal
tallkozhatunk, ha figyelmesek vagyunk, de a legtbb felhasznl szerencsre tudomst
sem szerez a gpn fut programok tbbsgrl. A felhasznl ltalban az n. felhasznli
programok miatt hasznlja szmtgpt (ilyenek pl. a szvegszerkesztk, bngszk, mdia-
lejtszk, stb.), de esetenknt az opercis rendszer szolgltatsait is ignybe veszi (pl. prog-
ramokat elindt). Az alacsony szint eszkzkezel programokkal azonban szinte soha nem
kell foglalkoznia, ha egy jl bekonfigurlt rendszert hasznl.
_start:
mov edx,len
mov ecx,msg
mov ebx,1
mov eax,4
int 0x80
mov eax,1
int 0x80
section .data
C:
#include <stdio.h>
int main(void){
printf("Hello, World!");
return 0;
}
Java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Perl:
print "Hello, World!\n";
Aki nem tud a fenti nyelveken programozni, az is kis angol nyelvismerettel valsznleg
megrti a print szbl, hogy itt kirsrl van sz. Aki pedig mr ltott valamilyen programo-
zsi nyelvet, az az tadott paramterbl azt is kitallja, hogy itt a Hello, World karakterso-
rozatot ratjuk ki. Az egyes nyelvek tartalmaznak mg tbb-kevesebb, a feladat szempontjbl
felesleges kdrszletet (a Perl a legkevesebbet), de ezek rvid nyelvtan-tanuls utn rt-
hetv vlnak.
Eddig a programozsi nyelvek kapcsn rtekeztnk alacsonyabb s magasabb szintekrl.
Vizsgljuk meg most ezt a gondolatkrt egy meglehetsen htkznapi pldn keresztl:
A rettegett kalzvezr, Morc Misi elsott egy kincses ldt egy lakatlan szigeten. Egy trk-
pen bejelli a kincs lelhelyt. Vannak azonban kiss kpzetlen kalzai is, akik nem tudnak
trkpet olvasni. Ezrt egy paprra feljegyzst kszttet a kincskeress mikntjrl. Segdje s
bizalmasa, Fllb Ferk a trkp alapjn a kvetkez listt rja fel:
1. Szllj ki a tekns alak sziklnl
2. Haladj 50 mtert a part mentn kelet fel
3. Fordulj a sziget belseje fel
4. Haladj 30 mtert a plmafk irnyba
5. Fordulj nyugat fel 30 fokkal
6. Haladj 10 mtert elre
7. ss 5 mter mlyre
A lista elksztsekor Fllb Ferknak fontos szempont volt, hogy csak olyan elemi uta-
stsokat alkalmazzon, amit az egyszer kalzok is megrtenek s vgre is tudnak hajtani: pl.
haladj x mtert elre, fordulj el x fokkal, stb. A kincskeresst vgrehajt kalznak nem kell
gondolkodnia, csak pontosan egyms utn vgre kell hajtania az utastsokat.
Mivel a kalzok gondolkodsa a tetemes rumfogyaszts miatt elg cskevnyes, ezrt Fl-
lb Ferknak gyelnie kell arra, hogy az utastsokat pontosan, megfelel sorrendben rja le.
Nem kvethet el olyan hibt, hogy a haladj helyett azt rja, hogy adj halat, mert a buta
kalz nem tudja kitallni Ferk szndkt. Ugyancsak a kincs elvesztshez vezet, ha Ferk
5 mter mly ss helyett vletlenl 5 lb mly sst r el. Ha vletlenl felcserl kt utas-
tst, akkor a kincskeres kalz rossz helyen fog kutatni (nem mindegy, hogy Fordulj nyugat
fel 30 fokkal s utna Haladj 10 mtert elre, vagy Haladj 10 mtert elre s utna
Fordulj nyugat fel 30 fokkal).
Analgik (csak annyira snttanak, mint Fllb Ferk):
A paprra rt utastssorozat egy szmtgpes programra hasonlt.
Fllb Ferk programja a papron, a szmtgpes programok a memriban trold-
nak (amikor futtatjuk).
Fllb Ferk programjt egy egyszer kalz hajtja vgre, a szmtgpes programot
a CPU.
Az egyszer kalz felel meg a CPU-nak (egyik sem gondolkodik, csak parancsot hajt
vge). Itt azonban meg jegyezni, hogy mg a CPU mindig gyorsan s pontosan hajtja
vgre a parancsot (nem tved), addig a kalz az elfogyasztott rum mennyisgtl fg-
g sebessggel s minsgben hajtja vgre az utastsokat.
Fllb Ferk utastsai a CPU gpi nyelvnek utastsainak felelnek meg.
Ferk ltal a lista ksztsekor elkvetett hibk a programban szintaktikai vagy sze-
mantikai hibknak felelnek meg. A szintaktikai hibk kiszrse egyszerbb (akrki
lthatja, hogy az adj halat rtelmetlensg), mg a szemantika hibk (pl. a felcserlt
utastsok, mter-lb sszekeverse) csak gy lehetsges, ha Ferk sszeveti a listt
a trkppel s ellenrzi, hogy helyes-e a lert utastssorozat.
(pldnkban hello nven). A fordt a fordtsi folyamat sorn a forrskdunkat tbb lps-
ben alaktja t futtathat llomnny: elszr a preprocesszor egyszer elfeldolgozst vgez
a forrskdon (pl. a #define direktvkat behelyettesti), majd a fordt a C forrskdbl
assembly programot kszt. (Az assembly programot meg is nzhetjk, ha a fordtst
a gcc -S hello.c paranccsal vgezzk; ekkor pl. a hello.s llomnyban megtalljuk
az assembly kdot.) Az assembly llomnybl az assembler kszt trgykdot. (A trgykd
pldnkban a gcc -c hello.c paranccsal llthat el, de a hello.o llomny mr emberi
szemnek nem tl olvasmnyos.) Vgl a trgykdbl a felhasznlt knyvtri elemekkel
a szerkeszt (vagy linker) lltja el a vgleges futtathat llomnyt (pldnkban hello n-
ven). A fordts vagy szerkeszts kzben tallt hibkrl termszetesen hibazeneteket kapunk.
A fordts folyamatt az 1.3. bra illusztrlja.
1.3. Httrismeretek
Decimlis: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
hexadecimlis: 0 1 2 3 4 5 6 7 8 9 A B C D E F
gy egy bjtot kt hexadecimlis karakterrel lehet jellemezni, pl. 6A, vagy 44. A 6A-rl
azonnal sejtjk, hogy hexadecimlis szm, de a 44 karaktersorozatrl nem lehet eldnteni,
hogy az a negyvenngy decimlis szmot jelenti, vagy a ngy-ngy hexadecimlis szmot.
Ezrt a hexadecimlis szmokat megegyezs szerint valamilyen mdon jelljk, pl. rhatunk
mg egy h karaktert (6Ah, 44h) , vagy rhatunk el egy 0x karaktersorozatot (0x6A, 0x44).
Termszetesen nem csak bjtokat brzolhatunk hexadecimlis formban, hanem brmi-
lyen szmot is. A hexadecimlis szmbrzols nem ms, mint a szm 16-os szmrendszerbe-
li reprezentcija.
1.6. Plda:
3Eh = 0x3E = 3*16 + 14 = 62
E4CAh = 0xE4CA = 14*163 + 4*162 + 12*16 +10 = 58570
25h = 0x25 = 2 * 16 + 5 = 37 ( 25!)
FFh = 0xFF = 15*16 +15 = 255
FFFFh = = 0xFFFF = 15*163 + 15*162 +15*16 +15 =65535
1.3.2. Prefixumok
A mindennapi letben gyakran hasznlunk vltszmokat (prefixumokat). ltalban a boltban
egy kilogramm kenyeret krnk s nem ezer gramm kenyeret. Kt vros tvolsgt kilomter-
ben adjuk meg, a csavarok mrett millimterben, mg a fny hullmhosszt nanomterben.
Az SI prefixumok jelentst a legtbb ember alapfok tanulmnyaibl ismeri. Azt is tudjuk,
hogy az SI prefixumok a nagysgrendeket az ezer (103) hatvnyai szerint mdostjk. Teht
a milli jelentse egy ezred, a kilo ezerszeres, mg a mega egymilliszoros szorzt jelent.
Az informatika terletn sajnlatos mdon ugyanezeket a prefixumokat kicsit ms rte-
lemben hasznljuk, ami bizony flrertsekre adhat okot. Itt a tz (illetve az ezer) hatvnyai
helyett a kett (illetve a 210=1024) hatvnyait hasznljuk.
Az informatikai prefixumok az SI prefixumokhoz kzeli arnyokat jeleznek (pl. a kilo
1000 helyett 1024-et), de az eltrs a nagyobb prefixumok fel egyre nagyobb. A flrertsek
elkerlsre az IEC (International Electrotechnical Commission) 1998-ban javasolta, hogy az
SI prefixumokat kizrlag decimlis alap rtelemben hasznljuk. Binris rtelemben (2 hat-
vnyainak jellsre) j elnevezst s jellst javasolt. Ennek lnyege, hogy a jellsben az SI
prefixumhoz egy i bett illesztnk, a kiejtsben pedig az SI prefixum els kt betjt kieg-
sztjk a bi (binary) vgzdssel. Ezt a javaslatot az ISO/IEC szabvnygyi testlete 2000-
ben elfogadta, majd 2005-ben s 2008-ban megerstette s kiegsztette. A javaslatot a Ma-
gyar Szabvnygyi Testlet 2007-ben MSZ EN 60027-2 szm alatt honostotta.
Megjegyzs: az informatikban nem hasznlunk egynl kisebb prefixumokat, teht nincs millibjt, de van terabjt.
1.7. Plda:
Ha egy 4 GiB-os (4 gibi bjtos) memria modulunk van, akkor abban 4096 megabjt, azaz
4.194.304 kilobjt, azaz 4.294.967.296 bjt informcit tudunk trolni. Ezzel szemben 4 TB-
os httrtroln 4000 gigabjt, azaz 4.000.000 megabjt, azaz 4.000.000.000 kilobjt, azaz
4.000.000.000.000 bjt informcit tudunk trolni.
Feladatok:
1.1. Tltsk ki a kvetkez tblzat hinyz elemeit a plda szerint. Minden sorban ugyan-
azon szm klnbz szmrendszerbeli brzolsai szerepeljenek.
1.2. Prbljuk meg a fejezetben szerepl C, Java s Perl nyelv Hello World programok
valamelyikt (esetleg mindet) futtatni.
1.3. Fejtsk meg az albbi ASCII-kdolt szveget: 69h, 70h, 61h, 66h, 61h, 69h, 20h, 70h,
61h, 70h
1.4. Egy httrtron filmeket trolunk tlagosan 700MiB hossz llomnyokban. A httr-
tr mrete 20TiB. Hny filmet tudunk rajta eltrolni?
Algoritmusok s programok
kell a szigetig elhajzni s ott kisni a kincset. Kalz Karcsi is tisztban volt azzal, hogy ki az
a Lady Gaga s hogyan kell elrabolni t. Vak Viki pedig szakrtje a papagjetetsnek, gy
neki sem okoz gondot a parancs rtelmezse s vgrehajtsa.
Az egyszer matrzok szmra ezen utastsok nem elemi utastsok, teht ezeket tovbb
kell rszletezni szmukra. gy Gonosz Gza is egyszerbb parancsok sorozatra bontotta
a tevkenysget (Vitorlt fel, vagy Szllj ki a tekns alak sziklnl). Ezen parancsok
mr elemi parancsok a matrzok szmra, gy azokat pontosan vgre is tudjk hajtani.
Az alvezrek intelligensebb emberek, ezrt jobban is fizetik ket, mit a matrzokat. A vezr
ezrt el is vrja tlk, hogy legyenek kpesek bonyolultabb, magasabb szint feladatokat
megoldani.
Eddigi algoritmusainkat klnfle szemlyek hajtottk vgre. Ha az algoritmus vgrehaj-
tst egy gpre bzzuk, akkor elrkeznk a program fogalmhoz:
A szmtgpes program olyan algoritmus, amelynek minden elemi tevkenysge
a szmtgp szmra rtelmezhet.
Hasonlan a kalz alvezrekhez s egyszer matrzokhoz, programjaink vgrehajt esz-
kzei is lehetnek intelligensebbek vagy egyszerbbek. Amint lttuk, a szmtgp vgrehajt
egysge szmra rtelmezhet legelemibb utasts a gpi kd utasts. Egy ilyen utasts
assembly nyelvi megfelelje pl. a kvetkez utasts:
U1: mov ebx,1
Ez az utasts egy x86 architektrj processzoron az ebx nev regiszterbe mozgat 1-et.
Ez egy nagyon alacsony szint utasts, ilyenekbl elg fradsgos megrni a msodfok
egyenlet megold kplett. Az assembly nyelv alacsony szint programozsi nyelv.
A kvetkez utasts mr magasabb szint elemekbl ptkezik, a lert utasts hasonlt ahhoz,
amit matematikarn rnnk (az sqrt jelenti a gykvonst):
U2: x1=(-3+sqrt(3^2-4*2*1))/(2*2);
A gp a parancs vgrehajtsa utn az x1 vltozba betlti az egyenlet egyik gykt
(x1=-0.5). Ilyen tpus utastsokat szinte minden ltalnos cl programozsi nyelven
megadhatunk (pl. C-ben is). Ezeket a nyelveket magas szint programozsi nyelveknek ne-
vezzk. Persze a magas szint nyelvek kztt is vannak klnbsgek, egyes nyelvek bizonyos
problmkra igen magas szint utastsokat tartalmazhatnak. Pl. a kvetkez MATLAB pa-
rancsban csak a megoldand egyenletet kzljk a gppel, a megold kplettel mr nem kell
bajldnunk:
U3: x=solve('2*x^2+3*x+1=0')
A gp vlasza itt mr tartalmazza mindkt megoldst, st a -0.5 lebegpontos formtum
helyett az eredmnyt a pontos trt-formtumban kaptuk meg.
x =
-1/2
-1
Nyilvnvalan az U3 pldban jutottunk el a legmagasabb absztrakcis szintre, ahol az
adott feladat a msodfok egyenlet megoldsa kzvetlen megfogalmazsra alkalmas na-
gyon magas szint parancs is rendelkezsre llt. Ezen a nyelven nem kellett a megolds mi-
kntjn gondolkodni, csak a feladatot kellett az adott nyelven megfogalmazni (solve Oldd
meg a kvetkez egyenletet). Itt a program rsa kzbeni tvedsek lehetsge kicsi,
a program jl ttekinthet s egyrtelm. Az U2 pldban egy ltalnos matematikai appar-
tus llt rendelkezsnkre, ahol neknk kellett a megolds mikntjt a megold kpletet
leprogramozni, de mg mindig elg magas absztrakcis szinten: voltak vltozink, a matema-
tikai mveletek jellse ismers volt. A kd olvassa kzben viszonylag hamar rjvnk,
hogy mit is csinl a program, de mr a programunk bonyolultabb, terjengsebb, a hibk elk-
vetsre is tbb lehetsgnk van. A U1 pldban az absztrakcis szint nagyon alacsony volt,
a megolds sorn hasznlt appartusnak alig volt kze a feladathoz: nincsenek vltozk, az
aritmetikai mveletek nehezen ttekinthetk, a program nem olvasmnyos. Ilyen alacsony
szint nyelven nagyon knny hibkat vteni s ezen hibk megtallsa is nehzkes.
Tegyk fel, hogy egy szmtgpes rendszerben a kvetkez elemi utastsok lteznek:
beolvas: X: beolvassa az X nev vltoz rtkt
kir: X kirja az X nev vltoz rtkt
kir: szveg: kirja a szveg karaktersorozatot
Aritmetikai mveletek (sszeads, szorzs, gykvons, stb.) vltozk segtsgvel
Oldjuk meg ezzel a gppel a msodfok egyenletet (azaz adjunk olyan msodfok egyen-
let megoldsra alkalmas algoritmust, aminek elemei mveletei a gp elemi mveleteivel
egyeznek meg).
A felhasznlt vltozink legyenek a, b, c, D, x1 s x2, amelyeket rendre az egyenlet egytt-
hatinak, a diszkriminnsnak, valamint a kt gyk rtkeinek trolsra hasznlunk.
Az algoritmus pldul a kvetkez lehet:
beolvas: a
beolvas: b
beolvas: c
legyen D rtke b 2 4ac
ha D negatv akkor
kir: Nincs vals gyk
klnben
b+ D b D
legyen x1 rtke , legyen x 2 rtke
2a 2a
kir: az els gyk x1
kir: a msodik gyk x2
Az algoritmus fenti lersa az emberi nyelvhez kzeli, mgis formalizlt nyelven trtnt.
Pl. a ha ... akkor ... klnben ... fordulatot vltozatlan formban talljuk meg a lersban,
mg a beszlt nyelvi olvasd be a-t parancs helyett a ragozatlan, tmrebb beolvas: a pa-
rancsot alkalmaztuk. Az ilyen tpus lersokat pszeudo-kdnak nevezzk. A pszeudo-kd
tovbbi trgyalsra, a nyelvi szablyok rszletes ismertetsre s finomtsra a 3. fejezetben
kerl majd sor.
Algoritmusainkat gyakran szemlletes, grafikus formban is megfogalmazzuk. Az egyik
ilyen gyakran hasznlt lersi md a folyamatbra. A folyamatbra nhny egyszer elembl
amelyek klnfle tevkenysgeket szimbolizlnak , valamint ezen elemeket sszekt
nyilakbl llnak. A nyilak az elemek egyms utni vgrehajtsi sorrendjt mutatjk. Minden
tevkenysgbl pontosan egy nyl vezet a kvetkez vgrehajtand tevkenysghez kivve
szimbluma van, ezek az adatbevitel (trapz) s a kirs (lekerektett sark tglalap). A fo-
lyamatbrban ezen kvl hasznlhatunk elgazst is (rombusz). Az egyes elemek kztt
a vgrehajtsi sorrendet nyilak jelzik. A start szimblumbl csak kifel, mg a stop szimb-
lumba csak befel vezet nyl. Az utastsokba mindig egy nyl vezet befel s egy nyl vezet
kifel. Az elgazsba egy nyl vezet befel s kt nyl vezet kifel: a vgrehajts a felttel
kirtkelse fggvnyben folytatdhat az egyik vagy msik gon.
Megjegyzs: a folyamatbrk jellsre tbbfle irnyzat ltezik, ezekben kiss eltr
mdon jellik az egyes tevkenysgeket. Termszetesen brmelyik jells megfelel; mi most
hasznljuk a 2.1. brn lthat kszletet.
A msodfok egyenlet megoldst az 2.2. brn lthat folyamatbra rja le. A program
vgrehajtsa a start szimblumnl kezddik, majd a hrom beolvas utasts kvetkezik egy-
ms utn. Ezek utn a diszkriminns kiszmts trtnik meg, majd az elgazsnl folytatdik
a vgrehajts. Ha a felttel (D < 0) igaz, akkor program a felttel szimblum igaz felirat
nyilnl folytatdik az zenet kirsval. Ha a felttel hamis, akkor a vgrehajts a gykk
kiszmtsval s a kt gyk kirsval folytatdik. A program mindkt ga a stop szimb-
lumba torkollik, itt r vget a program vgrehajtsa.
A folyamatbrt termszetesen nem csak szmtgpes programok, hanem brmilyen al-
goritmus lersra is alkalmazhatjuk. Az ALG2.3 jel motorjavt algoritmus lersa a
2.3. brn lthat. A folyamatbra pontosan azokat a tevkenysgeket rja, mint az ALG2.3
szveges (pszeudo-kdos) vltozat, de a vizulisabb tpus emberek taln jobban tltjk a
tevkenysgeket s azok sorrendjt.
Feladatok:
2.1. rjuk fel a dleltti tevkenysgeinket szvegesen, majd folyamatbrval is.
A tevkenysgek az bredssel kezddjenek s az ebddel fejezdjenek be.
Vegyk figyelembe, hogy htkznapokon mst csinlunk, mint a htvgn.
Algoritmusainkat, programjainkat nem gpek, hanem emberek rjk, tartjk karban. Ezrt
a programok ksztsnl figyelembe kell venni emberi mivoltunkbl ered korltainkat. Ez
irnyba mutat nyilvnval trekvs a magas szint programozsi nyelvek hasznlata: az em-
berek sokkal knnyebben tltnak olyan tpus lersokat, amelyek kzelebb llnak az emberi
gondolkodshoz, kifejezsi formkhoz, mint mondjuk egy gpi kdban lert szmsorozatot.
Az emberi korltok kzl egy fontos tnyez korltozott memrink. Egyszer tesztekkel
igazolhat, hogy az emberek tlagosan egyszerre krlbell 7 dolgot tudnak szben tartani.
Ennl sokkal tbb elem rendszereket mr nehezen ltunk t. Ez a korlt termszetesen a
programozsra is igaz: ha egy olyan algoritmust ksztnk, amely igen sok alkotrszbl ll,
akkor ez elbb vagy utbb ttekinthetetlenn vlik, mind a ksztje, de klnsen ms olva-
sk szmra. Clszer teht trekedni arra, hogy algoritmusaink viszonylag kevs ptelem-
bl lljanak.
Az emberi gondolkods ersen smkon alapul, szeretnk jl ismert elemekbl ptkezni.
A programozsi tevkenysgek esetben ez azt jelenti, hogy egy jl kezelhet programban (az
egybknt kevs szm) rszegysg kapcsolata jl definilt smkon alapuljon. Ezen kapcso-
lati smkat tevkenysgszerkezeteknek nevezzk s sszesen hrom alapvet tevkenysg-
szerkezetet hasznlunk. Ezek a kvetkezk:
sorozat (vagy szekvencia),
elgazs (vagy szelekci),
ciklus (vagy iterci).
3.1. Tevkenysgsorozatok
A tevkenysgsorozat (szekvencia) a legegyszerbb tevkenysgszerkezet: egyszeren azt
jelenti, hogy klnfle tevkenysgeket vgznk, mgpedig egyiket a msik utn. Szekvenci-
k elfordulnak a leghtkznapibb helyzetekben: pl. vizet engedek a pohrba, majd belefacsa-
rom egy citrom levt, majd kevs cukorral zestem. Egy ilyen logikailag egysgbe tartoz
A 3.1. brn lthat folyamatbrnak nem rsze a kt kis kr: ezek azt hangslyozzk csu-
pn, hogy a szekvencinak, mint sszetett vezrlsi szerkezetnek egyetlen belpsi pontja
(bejrata) s egyetlen kilpsi pontja (kijrata) van, fggetlenl attl, hogy a szekvencia
belsejben mi trtnik. Mindig egyetlen ponton kezdjk a szekvencia vgrehajtst s mindig
egyetlen ponton fejezzk azt be, akrmennyi s akrmilyen tevkenysget is vgznk el egy-
ms utn a kezdet s befejezs kztt. Ez a tulajdonsg nagyon fontos kzs tulajdonsga lesz
valamennyi vezrlsi szerkezetnek: akrmilyen is a vezrlsi szerkezet, annak mindig egyet-
len belpsi s egyetlen kilpsi pontja lesz.
3.2. Elgazsok
Gyakran tevkenysgeink valamilyen felttel kirtkelsnek eredmnytl fggenek. Prog-
ramjainkban az elgazs (szelekci) tevkenysgszerkezet egy felttel kirtkelsnek fgg-
vnyben alternatv vgrehajtsi mdokat r le. A szelekci egyik fontos eleme a felttel, ame-
lyet kirtkelnk a szelekci vgrehajtsa eltt. Ennek eredmnytl fgg, hogy a lehetsges
tevkenysgek kzl melyik tevkenysget hajtsuk vgre. A szelekci tbbi eleme a lehets-
ges vgrehajtand tevkenysgek halmaza, amelybl mindig legfeljebb egy hajtdik vgre.
A htkznapi letben a vlasztsok, dntsek mind szelekcival rhatk le.
Pldk a mindennapi letben hasznlt elgazsokra:
Ha j meleg id lesz, rvid nadrgban s plban strandra megyek, klnben pedig
farmert s inget fogok viselni a kertszkedshez.
Ha jl sikerl a vizsga, a bartaimmal elmegynk megnnepelni. (Klnben nem me-
gynk...)
Htkznapokon fl htkor, szombaton nyolc rakor, vasrnap pedig fl kilenckor
kelek.
Ha a pincr bss borravalt kap, elveszi a legszebb mosolyt.
Ha a heti lott nyeremny 100 milli fltt van, a szenvedlyes jtkosok mg tbb
lottszelvnyt vesznek.
Ha ebd kzben cseng a telefon s valamelyik csaldtagom hv, akkor felveszem, k-
lnben nem.
Nyron meleg van, tlen hideg van.
Ha a vilg rig lenne, / ktnyemben ftylne, / jjel-nappal szpen szlna, / ha
a vilg rig volna.
listjt kicsit bvtjk majd a klnben kulcsszval. Azrt ppen ezeket a kulcsszavakat
vlasztottuk, mert ezek hasonltanak a beszlt nyelvben hasznlt fordulatokra, ezrt jl tte-
kinthetv, knnyen olvashatv teszik a pszeudo-kdot. Termszetesen hasznlhatnnk akr
angol kulcsszavakat is (pl. if, then, else, end), vagy akrmilyen megllapods szerinti
szimblumokat (pl. kismacit a ha helyett, egrkt az akkor helyett, stb.), de most marad-
junk ennl a logikus, magyar szavakbl ll kulcsszkszletnl. A tovbbi tevkenysgszer-
kezetek jellsre is magyar nyelv kulcsszavakat fogunk hasznlni a pszeudo-kdokban.
Az elgazsban hasznlt felttel egy logikai kifejezs, amelynek rtke igaz vagy hamis
lehet. Helyes felttel teht a pldban ltott jl sikerl a vizsga, hiszen egy vagy teljesl,
vagy nem. Tovbbi helyes felttelek lehetnek pl.: szp id lesz holnap, htkznap van, szom-
jas vagyok, az A vltoz rtke pros, a D vltoz rtke nagyobb nullnl, A nagyobb B-nl,
stb. Nem helyes felttelek a kvetkezk: hny ves Zoli (nem eldntend krds), R ngyzet
(ez sem eldntend krds).
Az elgazsok jellsre a folyamatbrban mr tallkoztunk egy specilis szimblummal
(rombusz), amely az egyetlen olyan szimblum a folyamatbrban, amelynek kt kimenete
van. A folyamatbra elgazs-szimbluma azonban nem azonos a elgazs tevkenysgszer-
kezettel! A folyamatbra elgazs-szimbluma csupn egy ptelem lesz az elgazs tev-
kenysgszerkezetben, s ugyanezt a szimblumot fogjuk alkalmazni majd a ciklusok jells-
re is. Teht a tevkenysgszerkezetet nem maga a szimblum, hanem a szimblumbl ptett
struktra hatrozza meg. A legegyszerbb elgazs tevkenysgszerkezet jellse a 3.2. b-
rn lthat: amennyiben a felttel igaz, vgrehajtjuk a tevkenysget, klnben pedig a prog-
ram vgrehajtsa a tevkenysg kihagysval folytatdik. Fontos megfigyelni egy nagyon
fontos ktttsget az brn: a hamis g nem akrhova vezet, hanem pontosan az igaz g befe-
jezse utni pontra mutat. Ms szavakkal: az elgazs tevkenysgszerkezet elejn a felttel
fggvnyben a vgrehajts elgazdik, de a tevkenysgszerkezet vgn a kt vgrehajtsi
szl ismt sszefondik. Az elgazs tevkenysgszerkezet kvlrl teht ismt a mr ismert
minden tevkenysgszerkezetre jellemz kpet mutatja: egy belpsi pontja s egy kilpsi
pontja van.
Megjegyzsek:
1. A tbbg elgazsra bevezetett jells nem felttlenl szksges, pl. ktg elgaz-
sokbl is mindent meg lehet oldani. Az ttekinthetbb kd miatt azonban mgis alkalmazzuk
a tbbg elgazsokra szolgl egyszerbb jellst. Nzzk meg, hogy nzne ki egy tbbg
elgazs egymsba gyazott ktg elgazsokkal megoldva:
A tbbg jellsmd szemmel lthatan tmrebb, jobban ttekinthet lerst tesz lehe-
tv. A ktg elgazsokkal megvalstott megolds plda arra, hogy egy elgazs tevkeny-
sge bonyolultabb tevkenysgszerkezet is lehet jelen esetben pl. a kls elgazs kln-
ben ga maga is egy elgazs, amelynek klnben ga szintn egy elgazs.
2. A tabultor (vagy szkzk) kvetkezetes alkalmazsa ugyan nem ktelez, de ennek
hinya egy kzepes nagysg programot is mr olvashatatlann tesz. A megfelelen tabullt
s jl olvashat kddal elssorban magunknak tesznk jt, de ha kdunkat kzz is akarjuk
tenni, akkor felttlenl alkalmazni kell. Ez vonatkozik minden rott kdra, akr pszeudo-
kdban rt algoritmusrl, akr valamilyen programozsi nyelven rott kdrl van sz. Ez
utbbi esetben az intelligensebb kdszerkeszt programok ltalban segtsget is adnak (au-
tomatikus kdformzs). Azonban brmely egyszer editorban rt kdnak is megfelelen
formzottnak kell lennie: a formzs alapveten a programoz feladata. ltalnos irnyelv:
egy formzatlan program olyan fok ignytelensgrl tanskodik, mintha egy tteremben
csorba, rzsos szl pohrban hoznk ki az 1982-es Chteau la Mission Haut-Brion-t.
A tbbg elgazsok folyamatbrs jellse a 3.4. brn lthat. ltalnossgban K g
megvalstshoz K 1 elgazs-szimblum hasznlata szksges.
vkenysget hajtjuk vgre, mg a hamis gon azt a tevkenysget, ami a szaggatott vonallal
jellt tglalapban van (emlkezznk r: megengedtk, hogy az elgazs tevkenysgei ssze-
tett tevkenysgek is lehessenek). Egy nagyon fontos momentum: a szaggatott vonallal jellt
tglalapba egy nyl vezet be s abbl egy nyl vezet tovbb. Ha most figyelmnket a szaggatott
vonallal jellt tglalap belsejre fordtjuk amelynek egyetlen belpsi pontja s egyetlen ki-
lpsi pontja van akkor itt most hasonl mdon a kisebbik, pont-vonalas tglalapot gondolat-
ban kitrlve ismt az ismers brt ltjuk: a szaggatott vonallal jelzett tglalap belseje nem
ms, mint egy ktg elgazs, felttele a Felttel2, igaz gn a Tevkenysg2, hamis gn
pedig a pont-vonallal jelzett (sszetett) tevkenysget hajtjuk vgre. Ismt fontos: a pont-
vonallal jelzett tglalapba egyetlen nyl vezet be s egyetlen nyl vezet ki, ezrt ezt kezelhetjk
egyetlen sszetett tevkenysgnek is. Az brt tovbb boncolgatva szrevesszk, hogy a pont-
vonallal jelzett tglalapban ismt egy ktg elgazs van elrejtve. Vagyis a ngyg elgazst
megvalst folyamatbrnk nem ms, mint hrom darab, egymsba gyazott ktg elgazs.
A kls (Felttel1 felttel) elgazs hamis gban van egy jabb elgazs (ennek felttele
Felttel2), amelynek hamis ga tartalmazza a harmadik elgazst (Felttel3 felttellel).
A struktra sz szerint tkrzi az 1. megjegyzsben lert pszeudo-kd szerkezett.
3.3. Ciklusok
A ciklusok szolglnak programjainkban az ismtld tevkenysgek lersra. Az egyszerbb
ismtld tevkenysgeket lerhatjuk ciklusok nlkl is, pl. szekvencia formjban (a kiltsd
tszr, hogy hah algoritmus helyett pl. rhatjuk azt is, hogy kiltsd, hogy hah, kiltsd,
hogy hah, kiltsd, hogy hah, kiltsd, hogy hah), de ez nem tl elegns megolds.
Radsul lehetnek bonyolultabb esetek, ahol ezzel az egyszer trkkel nem boldogulunk (ko-
pogtass, amg ajtt nem nyitnak).
Morc Misi, a rettegett kalzvezr egy sikeres zskmny utn a kvetkez sznoklattal indtja
a lakomt:
Cimbork, egyetek, amg hesek vagytok!
A fedlzetmester a kvetkezkppen fordtja le ezt rthetbb nyelven a matrzoknak:
Naplop npsg, ha jllaktatok, abbahagyni a zablst!
Mindkt utasts ugyanazt jelenti: amg hes a matrz, egyen, ha mr nem hes, ne egyen.
Morc Misi megfogalmazsban egy bennmaradsi felttelt hasznlt: addig kell az evs tev-
kenysget folytatni (vagyis a ciklusban maradni), amg az hsg llapota fennll. A fedlzet-
mester ezzel ellenttben azt fogalmazta meg, mikor kell abbahagyni a ciklust (az evs folya-
matt): akkor, ha a jllaks llapota bekvetkezik. Ezt kilpsi felttelnek nevezzk.
Ha megvizsgljuk a bennmaradsi s a kilpsi felttel kzti sszefggst, akkor azt tall-
juk, hogy ezek egyms logikai negltjai: hes vagyok = NEM vagyok jl lakva, vagy: jl va-
gyok lakva = NEM vagyok hes. A bennmaradsi s a kilpsi felttelek teht igen knnyen
talakthatk egymsba.
Az elltesztel ciklusokat pszeudo-kddal a kvetkez mdokon lehet lerni:
Elltesztel ciklus, bennmaradsi felttellel:
ciklus amg felttel1
tevkenysg
ciklus vge
Itt az amg kulcssz helyett a kilpsi felttel jelzsre a mgnem kulcsszt alkalmaztunk.
Ebben a ciklusban a ciklusmag mindaddig jra s jra vgrehajtdik, amg a felttel2 hamis
(a felttel kirtkelse itt is a ciklusmag vgrehajtsa eltt trtnik). Amint felttel2 igazz
vlik, a ciklusbl kilpnk. Termszetesen itt is igaz, hogy felttel1 = NEM felttel2.
Az elltesztel ciklusok folyamatbrs reprezentciit a 3.6. bra mutatja. Jl lthat,
hogy a bennmaradsi felttel esetben a felttel igaz ga mutat a ciklusmag fel, mg a kilp-
si felttel esetben a felttel igaz ga a ciklusbl val kilpsre mutat. A folyamatbra jl mu-
tatja, hogy a vgrehajts sorn elszr trtnik meg a felttel kirtkelse, majd ezutn kvet-
kezhet a ciklusmag vgrehajtsa vagy a ciklusbl val kilps. A folyamatbrbl az is vil-
gosan ltszik, hogy van olyan lehetsges vgrehajtsi t, ami elkerli a ciklusmagot:
A ciklus zrsa itt is a felttel megadsval trtnik, de itt mivel kilpsi felttelt hasz-
nlunk a mgnem kulcsszt hasznljuk. A ciklusban a ciklusmagot mindaddig jra s jra
vgrehajtjuk, amg a felttel2 hamis. A felttel kirtkelse itt is a ciklusmag vgrehajtsa
utn trtnik meg. Amint felttel2 igazz vlik, a ciklusbl kilpnk. Termszetesen itt is igaz
a bennmaradsi s kilpsi felttelek kztti felttel1 = NEM felttel2 sszefggs.
Az htultesztel ciklusok folyamatbrs lersai a 3.7. brn lthatk. Itt a ciklus vgrehaj-
tsa a ciklusmaggal kezddik, majd a felttel kirtkelsvel folytatdik. A bennmaradsi s
kilpsi felttelek itt is egyms negltjai: a bennmaradsi felttel igaz ga marad a ciklusban,
mg a kilpsi felttel igaz ga lp ki a ciklusbl. A jellsbl jl ltszik, hogy a ciklusmagot
mindig legalbb egyszer vgrehajtjuk, hiszen az els vizsglat csak a ciklusmag els vgre-
hajtsa utn trtnik meg, a ciklust elhagysra itt nylik elszr lehetsg.
Fontos ismtelten hangslyozni, hogy hasonlan a szekvencia s elgazs tevkenysg-
szerkezetekhez, a ciklusnak is egyetlen belpsi pontja s egyetlen kilpsi pontja van. Ezen
belpsi s kilpsi pontokat a folyamatbrn kis krk jelzik.
Felmerlhet a krds: mirt van szksg ennyifle ciklusra? Nem hasznlhatnnk a ngy-
fle ciklus helyett csak egyet, esetleg kettt? Ha igen, akkor melyik ciklust, vagy ciklusokat
vlaszuk ki a ngy kzl egy minimalista programozsi nyelvhez? Elszr vizsgljuk meg a
bennmaradsi-kilpsi felttelek krdst. Azt mr megllaptottuk, hogy ezek mindig egy-
ms negltjai. Teht ha programozsi nyelvnk ezek kzl pl. csak a bennmaradsi felttelt
alkalmazza, akkor azt olyan algoritmusokat, amikben kilpsi felttelt alkalmaz ciklus van,
knnyszerrel talakthatjuk bennmaradsi feltteles cikluss gy, hogy kzben a felttelt
negljuk. s ez fordtva is igaz. gy valjban elg vagy egyik, vagy msik felttel, s az is
mindegy, hogy melyiket alkalmazzuk.
Vajon az ell s htultesztel ciklusok kzl elg-e csak az egyik? Ha igen, melyiket kell
alkalmazni? A f klnbsg az, hogy hol trtnik a felttel vizsglata. Ennek egyik jl lthat
hatsa az volt, hogy a htultesztel ciklusnl mindig vgrehajtdik legalbb egyszer a ciklus-
mag, mg az elltesztel ciklusnl elfordulhat, hogy egyszer sem hajtjuk azt vgre. Ha csak
elltesztel ciklusunk van, akkor egy htultesztel ciklust knnyszerrel szimullhatunk gy
(pl. bennmaradsi felttellel):
tevkenysg
ciklus amg felttel1
tevkenysg
ciklus vge
ha felttel1 akkor
ciklus
tevkenysg
amg felttel1
elgazs vge
Teht az ell- vagy htultesztel ciklusokbl is elg lenne az egyik (a pldk tansga sze-
rint taln egyszerbb az let egy elltesztel ciklussal). Vagyis elegend egyetlen egy ciklust
megvalstani a programozsi nyelvben s ennek segtsgvel kis gyeskedssel az sszes
lehetsges ciklusfajtt mr meg tudjuk valstani. Ennek ellenre a legtbb programozsi
nyelv tipikusan nyjt egy elltesztel s egy htultesztel ciklust is, hogy a programoz a
feladathoz leginkbb illeszked fajtt vlaszthassa. Az albbi tblzat pldkat ad a ngy
lehetsges ciklusra klnfle programozsi nyelvekbl.
Elltesztel Htultesztel
Java: C:
Bennmaradsi while(felttel){ do{
felttel ciklusmag ciklusmag
} } while(felttel)
Scratch: Pascal:
Kilpsi felt- Repeat until Repeat
tel felttel ciklusmag
ciklusmag until felttel
Ebben a ciklusban a ciklusmag pontosan N-szer hajtdik vgre, ahol N egy nem-negatv
egsz szm, kzben pedig a ciklusszmll egyesvel nvekszik. Ezt a ciklusfajtt a progra-
mozsi nyelvek egy elltesztel ciklussal valstjk meg. Gyakorlsknt valstsuk meg mi is
ezt a ciklust egy elltesztel ciklussal, bennmaradsi felttel alkalmazsval:
szmll=0
ciklus amg szmll < N
tevkenysg
szmll = szmll + 1
ciklus vge
Figyeljk meg, hogy a folyamatbra nmagban lehetsget adott olyan algoritmusok ksz-
tsre is, amelyek nem csak a hrom alapvet tevkenysgszerkezetet tartalmazzk. Ha figye-
lnk a szablyokra, akkor termszetesen a folyamatbra segtsgvel is tudunk strukturlt prog-
ramot kszteni, de a folyamatbra nem knyszert r erre. Ha a hrom tevkenysgszerkezetet
tartalmaz pszeudo-kddal fogalmazzuk meg algoritmusunkat, akkor bizonyosan strukturlt
programot fogunk kapni, itt nem tudunk kilpni a szablyok kzl: a pszeudo-kd rknyszert
a strukturlt programozsra. Az a szabadsg azonban, amit a folyamatbra egyes ptelemei
kztti nyilak tetszleges hzogatsa jelent, egszen kusza programok megrst teszi lehetv.
Ez az elem, ami az ptelemek tetszleges sorrendbeli vgrehajtst teszi lehetv, sok nyelv-
ben valamilyen ugr (pl. goto) utastsknt van jelen. A goto hasznlata ha van ilyen az lta-
lunk hasznlt programozsi nyelvben egy strukturlt programban termszetesen tilos.
Az ALG2.1 algoritmus x s y szmok ( x y > 0 ) legnagyobb kzs osztjnak meghat-
rozsra szolgl. Az algoritmust a kvetkezkppen fogalmaztuk meg:
Legyen r az x s y maradkos osztsnak maradka.
Az x helybe tegyk az y-t, y helyre az r-t.
Ha y = 0 , akkor x a legnagyobb kzs oszt, klnben ismteljk az 1. lpstl.
Ksztsk most el ezen algoritmus lerst strukturlt programmal, pszeudo-kddal s fo-
lyamatbrval is. Ahhoz, hogy a program ne csak x y esetben mkdjn, a beolvass utn
szksg szerint cserljk meg a kt szmot.
Az algoritmus elszr beolvas kt szmot (A-t s B-t), majd ezeket az x s y vltozkba
tlti oly mdon, hogy immr x y igaz legyen. Ezutn kezddik a legnagyobb kzs oszt
szmtsa egy ciklus segtsgvel: a ciklus addig fut, amg y nullra nem cskken, ezen id
alatt minden iterciban a ciklus magjban elvgezzk a maradkos osztst, valamint az x s y
vltozk ttltst. Vgl a program kirja az eredmnyt.
Nmi talakts utn a 3.11. bra szerinti folyamatbrt kaphatjuk, amely pontosan ugyan-
azt csinlja, mint a 3.10. brn lthat, de ebben mr jl felismerhetk a tevkenysgszerkeze-
tek. A knnyebb lthatsg rdekben a folyamatbra hrom ciklust (C1, C2, C3) tglalap-
okkal hatroltuk. A C1 ciklus egy elltesztel ciklus, melynek magja az A tevkenysg. A C2
ciklus szintn elltesztel, ennek magja egy szekvencia, melynek elemei az A tevkenysg, a
C3 ciklus s a B tevkenysg. A C3 ciklus is elltesztel, magja pedig az A tevkenysg. Ma-
ga a program egy szekvencia, melynek elemei a C1 ciklus, a B tevkenysg, a C2 ciklus s
a C tevkenysg. A ciklusok kzl a C1 s C3 kilpsi felttellel, mg a C2 ciklus bennmara-
dsi felttellel rendelkezik.
3.11. bra. A 3.10. folyamatbra talaktva, a ciklusok (C1, C2, C3) kln jellve
3.12. bra. A 3.11. folyamatbra egyszerstve, a C3 ciklus s krnyezete a C3* cikluss alaktva
eljrs talaktott_program_2
ciklus mgnem felt1
vgrehajt A
ciklus vge
vgrehajt B
ciklus amg felt2
ciklus
vgrehajt A
mgnem felt1
vgrehajt B
ciklus vge
vgrehajt C
eljrs vge
Feladatok:
3.1. Tegyk fel, hogy mostantl csak a legegyszerbb elgazst hasznlhatjuk:
ha felttel akkor elgazs vge formban, a klnben kulcssz pedig
nem ltezik. rjuk meg a kvetkez algoritmust ebben a krnyezetben, pszeudo-kdban:
ha szp id van kirndulok, klnben olvasgatok.
Valstsuk meg a 3.4. brn lthat ngyg elgazst is ezzel a mdszerrel. rjuk fel az
algoritmust pszeudo-kddal, illetve rajzoljuk fel folyamatbrval is.
3.2. Gyakorlskppen rajzoljuk t a 3.8. brn lthat folyamatbrt gy, hogy bejelljk
rajta (pl. bekeretezzk) az egyes elgazsokhoz tartoz sszetett tevkenysgeket (ame-
lyeknek termszetesen egy belpsi pontja s egy kilpsi pontja lesz). A szp bra r-
dekben a 3.8. bra als rszt kicsit t kell rajzolni.
3.3. rjuk t az euklideszi algoritmust gy, hogy htultesztel ciklust hasznljon. Egsztsk
ki tovbb ellenrzssel is: csak pozitv egsz szmokat fogadjon el bemenetl.
3.4. Az euklideszi algoritmus egy alternatv megfogalmazsa a kvetkez:
Legyen r az x s y maradkos osztsnak maradka. Ha r = 0 , akkor y a legnagyobb k-
zs oszt, klnben x helybe tegyk az y-t, y helyre az r-t s ismteljk az els lpstl.
Valstsuk meg ezt az algoritmust is pszeudo-kddal s folyamatbrval is (strukturltan).
3.5. Alaktsuk t a 3.11. brn lthat algoritmus pszeudo-kdjt gy, hogy csak elltesztel
ciklust hasznljunk bennmaradsi felttellel.
Vgezzk el az talaktst gy is, hogy csak kilpsi felttelt hasznlunk.
3.6. Alaktsuk t a 3.12. brn lthat algoritmus pszeudo-kdjt gy, hogy csak elltesztel
ciklust hasznljunk bennmaradsi felttellel.
Vgezzk el az talaktst gy is, hogy csak kilpsi felttelt hasznlunk.
3.7. rjuk fel az albbi idzeteket formlisan pszeudo-kd s folyamatbra segtsgvel.
Ha a vilg rig lenne, / ktnyemben ftylne, / jjel-nappal szpen szlna, / ha
a vilg rig volna.
Konverzi pszeudo-kdok s
folyamatbrk kztt
Mint lttuk, a folyamatbra lehetsget ad nem strukturlt programok ksztsre, mg
a pszeudo-kd ltalunk definilt elemkszlete szigoran csak a hrom alapvet tevkenysg-
szerkezet hasznlatt teszi lehetv, gy garantlja, hogy csak strukturlt programot rjunk.
Ebbl azonnal kvetkezik, hogy nem ltezhet klcsnsen egyrtelm megfeleltets a folya-
matbrval s pszeudo-kddal lerhat algoritmusok kztt. Azonban ha a folyamatbra k-
sztsnl betartjuk a szablyt, hogy az elgazs-szimblumot csak szablyos tevkenysg-
szerkezetek (elgazs vagy ciklus) ksztsre hasznljuk, akkor ezen folyamatbra mr kl-
csnsen egyrtelmen hozzrendelhet egy pszeudo-kdhoz.
A pszeudo-kd trsa folyamatbrv egyszer feladat, hiszen a pszeudo-kdban egyr-
telmen jellve vannak a tevkenysgszerkezetek: ha azt olvassuk, hogy ha, akkor tudjuk,
hogy ez elgazs, mg a ciklus sz egy itercit jell, st a szintaxisbl azonnal ltjuk, hogy
ell- vagy htultesztel ciklusrl van-e sz, s kilpsi vagy bennmaradsi felttelt hasznl-e.
Ezen tevkenysgszerkezeteknek ltezik egyrtelm megfelelje a folyamatbrban is, az
trajzols tbb-kevsb mechanikus feladat. A folyamatbra trsa pszeudo-kdd nehezebb
feladat, hiszen a folyamatbra elgazs-szimbluma tbbfle tevkenysgszerkezetet jellhet;
elszr azonostani kell az elgazs-szimblum szerept (elgazst vagy ciklust valst-e meg,
cikluson bel pontosan melyik fajtt), majd ezutn a pszeudo-kd generlsa mr ismt egy-
szer tevkenysg.
tevkenysgbe befut s onnan kifut nyilat. Ezutn az sszetett tevkenysget ki kell fejteni
(lsd albb). A program mindig egy szekvencia (elfajul esetben csak egyetlen tevkenysgbl
ll, s ltalban ennek a szekvencinak a tevkenysgei sszetett tevkenysgek); ne feledkez-
znk el a folyamatbra elejre elhelyezni a start-, vgre pedig a stop szimblumot.
Elgazsok talaktsa. Az elgazsok talaktsa sorn elszr hatrozzuk meg, hny
g elgazsrl van sz s vlasszuk ki a megfelel struktrt (pl. a 3.2.3.4. brk szerint).
A pszeudo-kdban lev feltteleket rjuk be a folyamatbra elgazs-szimblumaiba s rjuk
fel az elgazsokra az igaz-hamis rtkeket is. Ezutn az elgazsok egyes gainak talaktsa
trtnik. Minden gat kezdetben helyettestsnk egyetlen sszetett tevkenysggel (tglalap-
pal), majd ezeket szksg szerint fejtsk ki (a kifejtst lsd albb).
Ciklusok talaktsa. A pszeudo-kd egyrtelmen azonostja, hogy ell- vagy htul-
tesztel ciklusrl, illetve kilpsi vagy bennmaradsi felttelrl van-e sz. Ezek alapjn v-
lasszuk ki a megfelel struktrt a ciklus folyamatbrs brzolsra (a 3.6. s 3.7. brk sze-
rint). rjuk be az elgazs szimblumba a (kilpsi vagy bennmaradsi) feltteleket s az igaz-
hamis rtkeket az elgazs szimblumra (gyeljnk arra, hogy kilpsi vagy bennmaradsi
felttelt hasznlunk-e). A ciklus magjt kezdetben helyettestsk egyetlen sszetett tevkeny-
sgknt (tglalappal). Ezutn a ciklus magjt, ha szksges, fejtsk ki (lsd albb).
sszetett tevkenysgek kifejtse. Az sszetett tevkenysg lehet szekvencia, elgazs,
vagy ciklus, illetve ezekben tovbbi sszetett tevkenysgek lehetnek. Az sszetett tevkeny-
sg kifejtse sorn elszr dntsk el, milyen tpus tevkenysgszerkezetrl van sz (szek-
vencia, elgazs, ciklus), majd a fentebb lertak szerint alaktsuk t az sszetett tevkenysget.
Itt elfordulhat, hogy ismtelten egy sszetett tevkenysgre bukkanunk, ezeket is fejtsk ki,
amg csupa elemi tevkenysget tartalmaz a folyamatbra. Ezen kifejtett sszetett tevkeny-
sg bizonyosan egyetlen belpsi s egyetlen kilpsi ponttal rendelkezik, azonostsuk ezeket.
A (mg ki nem fejtett) sszetett tevkenysgbe mutat nyilat a kifejtett sszetett tevkenysg
belpsi pontjra, illetve a (mg ki nem fejtett) sszetett tevkenysgbl kifel mutat nyilat
a kifejtett sszetett tevkenysg kilpsi pontjra kell trajzolni.
4.1. Plda: alaktsuk t az Euklideszi algoritmus pszeudo-kdos lerst folyamatbrv:
eljrs Euklideszi algoritmus
beolvas: A
beolvas: B
ha AB akkor
legyen x rtke A
legyen y rtke B
klnben
legyen x rtke B
legyen y rtke A
elgazs vge
ciklus amg y>0
legyen r x/y maradka
legyen x rtke y
legyen y rtke r
ciklus vge
kir A s B lnko-ja: x
eljrs vge
A ciklus magja egy sszetett tevkenysg (egy szekvencia), ez tovbb bonthat, ahogy
a jobb als szrke tglalapban ltszik. Ezt a kifejtett sorozatot az 5 s 6 pontok kz kell il-
leszteni gy, hogy az 5 s 6 pontok legyenek az illeszked be- s kilpsi pontok. A kifejtett
sszetett tevkenysgek behelyettestse utn a 3.9. brval megegyez eredmnyre jutunk.
psi pontja is lesz. Az elgazs-szimblum teht akkor s csak akkor jell elgazs tevkeny-
sgszerkezetet, ha az elgazs-szimblum mindkt kilpsi pontja utn tudunk azonostani
egy-egy olyan sszetett tevkenysgszerkezetet, amelyek vezrlse egyetlen pontban tallko-
zik. Ezen sszetett tevkenysgszerkezetek azonostsa trtnhet gy, hogy gondolatban beke-
retezzk a tevkenysgszerkezetet, amelynek egyetlen belpsi pontja van (amely az elgazs-
szimblumhoz csatlakozik) s egyetlen kilpsi pontja pedig a msik g kilpsi pontjhoz
csatlakozik. Fontos, hogy ezen azonostott sszetett tevkenysgeket hatrol (gondolatban)
felrajzolt tglalapot a belpsi pont s a kilpsi pont kivtelvel nem lpheti t ms nyl.
Elltesztel ciklusok azonostsa. Az elltesztel ciklusok smi a 3.6. brn lthatk.
Az elltesztel ciklus belpsi pontja agy elgazs-szimblum bemenete, kilpsi pontja pe-
dig ugyanezen elgazs-szimblum egyik kimenete. Az elgazs-szimblum msik kimenete
utn egy (sszetett) tevkenysg kvetkezik (ciklusmag), melynek kilpsi pontja a ciklus
belpsi pontjhoz csatlakozik. Egy elgazs-szimblum teht akkor s csak akkor jell
elltesztel ciklust, tudunk azonostani egy olyan sszetett tevkenysgszerkezetet (ciklusma-
got), amelynek belpsi pontja az elgazs-szimblum egyik kimenethez, kilpsi pontja
pedig az elgazs-szimblum bemenethez csatlakozik. Ekkor az elltesztel ciklus tevkeny-
sgszerkezet belpsi pontja az elgazs-szimblum bemenete, kilpsi pontja pedig az elga-
zs-szimblum msik (nem a ciklusmaghoz csatlakoz) kimenete lesz. Amennyiben a cik-
lusmagba az elgazs-szimblum igaz ga vezet, bennmaradsi, ellenkez esetben kilpsi
felttelrl van sz (lsd a 3.6. brt).
Htultesztel ciklusok azonostsa. Az htultesztel ciklusok smi a 3.7. brn lthatk.
A htultesztel ciklus belpsi pontja mindig egy (sszetett) tevkenysg, amelynek kilpsi
pontja egy elgazs-szimblum bemenethez csatlakozik. Ezen elgazs-szimblum egyik
kimenete a ciklus belpsi pontjhoz csatlakozik, a msik kimenete pedig a htultesztel cik-
lus tevkenysgszerkezet kilpsi pontja lesz. Egy elgazs-szimblum teht akkor s csak
akkor jell htultesztel ciklust, tudunk azonostani egy olyan sszetett tevkenysgszerkeze-
tet (ciklusmagot), amelynek kilpsi pontja az elgazs-szimblum bemenethez, belpsi
pontja pedig az elgazs-szimblum egyik kimenethez csatlakozik. Ekkor a htultesztel
ciklus tevkenysgszerkezet belpsi pontja a ciklusmag belpsi pontja lesz, a tevkenysg-
szerkezet kilpsi pontja pedig az elgazs-szimblum msik (a ciklusmaghoz nem csatlako-
z) kimenete lesz. Amennyiben a ciklusmaghoz az elgazs-szimblum igaz ga csatlakozik,
akkor bennmaradsi, ellenkez esetben pedig kilpsi felttelt hasznlunk (lsd a 3.7. brt).
Szekvencik trsa. A szekvencia elemei lehetnek elemi tevkenysgek (ide rtve a beol-
vasst, a kirst, vagy a folyamatbra tglalap szimblumaiba rt egyb tevkenysgeket),
vagy lehetnek ciklusok s elgazsok. A szekvencia trsa sorn egyszeren az egyes tev-
ciklus vge
ciklus vge
amg felttel
mgnem felttel
Ebben a lersban egy ciklus vza tallhat, de a ciklus magja mg hinyzik. A ciklusmag
ismt egy szekvencia, melynek elemei egy kirs, egy beolvass, egy elgazs s egy rtk-
ads (C jel tglalap a 4.3. brn). Ezzel a ciklusmaggal bvtett pszeudo-kd a kvetkez:
eljrs Minimumkeres (3. lps)
kir: Adja meg N rtkt
beolvas: N
ha N > 0 akkor
i:=1
ciklus
kir adja meg az i . szmot
beolvas: A
ha A < MIN vagy i = 1 akkor
ELGAZS KIFEJTEND
elgazs vge
i := i + 1
mgnem i > N
kir: A legkisebb szm: MIN
klnben
kir: N pozitv kell legyen
elgazs vge
eljrs vge
Vgl az elgazs hinyz (egyetlen) gt kell kifejteni, ami egy egyelem szekvencia
(egy rtkad utasts). Ezen tevkenysggel az utols hinyos tevkenysgszerkezet is teljes-
s vlik, a program teljes pszeudo-kdos lersa a kvetkez:
eljrs Minimumkeres
kir: Adja meg N rtkt
beolvas: N
ha N > 0 akkor
i=1
ciklus
kir adja meg az i . szmot
beolvas: A
ha A < MIN vagy i = 1 akkor
MIN = A
elgazs vge
i := i + 1
mgnem i > N
kir: A legkisebb szm: MIN
klnben
kir: N pozitv kell legyen
elgazs vge
eljrs vge
Feladatok:
4.1. Alaktsuk t lpsenknt az Euklideszi algoritmus 3.9. brn lthat folyambrs repre-
zentcijt pszeudo-kdd.
4.2. Alaktsuk t lpsenknt a Minimumkeres program pszeudo-kdjt folyamatbrv.
4.3. Alaktsuk t lpsenknt a 3.11. s 3.12. brkon lthat folyambrkat pszeudo-
kdokk.
4.4. Alaktsuk t a kvetkez pszeudo-kdot folyamatbrv:
Eljrs sszegz
i := 0
Ciklus
S := 0
vge := hamis
Ciklus amg vge = hamis
Beolvas: k
Ha k > 0 akkor
S:=S+k
Klnben
vge := igaz
elgazs vge
Ciklus vge
Kir: S
i := i + 1
Mgnem i = 10
Eljrs vge
5.2. Jackson-brk
A Jackson-bra Michael A. Jackson nevhez fzdik, aki az 1970-es vekben a strukturlt
programtervezs krdseivel foglalkozott: ehhez a mdszertanhoz dolgozta ki a Jackson-
A tpust tovbb definiltuk: ez lehet elads vagy gyakorlat, de csak az egyik (szelekci).
A hallgat adatai a hallgat nevbl s kdjbl llnak (szekvencia). A zrvizsgrl az in-
dex kt zrvizsga trgy adatait trolja (szekvencia). Ezek a trgy nevt s a kapott osztlyza-
tot tartalmazzk (szekvencia). Figyeljk meg, hogy a zrvizsga kt azonos tpus entitst
tartalmaz (pontosan kettt az bra szerint). Ezen ZV trgy nev entitsok azonos szerkezet-
ek, ezrt elg, ha azt egyszer definiljuk. A pldban az egyik ZV trgy entitst definiltuk
tovbb, de megtehettk volna azt is, hogy a zrvizsga defincija utn flbehagyjuk az brt,
majd a ZV trgy entitst mshol megismtelve folytatjuk a defincit.
Fontos megjegyezni, hogy az egyes entitsok definilsakor mindig a fell tallhat tgla-
lapban megnevezett entitst definiljuk: egyrtelm pldul, hogy az 5.2. brn a flvek jel-
zs tglalap alatt tallhat a flvek nev entits defincija. Flrertsre adhat okot viszont
a flv defincija: a flv felirat tglalap alatt a flv (s nem a flv*) defincija tallhat.
Ez jl lthat a tantrgy defincijnl: a jells szerint egyrtelm, hogy a definci a tan-
trgy entitsra vonatkozik; azonban ha alternatv mdon a tantrgy defincijt annak els
elfordulsa alatt folytattuk volna, akkor abban a tglalapban tantrgy* felirat llna: a defin-
ci termszetesen ekkor is a tantrgy entitsra (s nem a tantrgy*-ra) vonatkozna. Hasonl
megllapts igaz a szelekci elemeinek definilsra is: ha az brnkon pl. az elads entitst
tovbb definilnnk gy, hogy tovbb rszletezzk az brn lthat entitst, akkor a definci
rtelemszeren az elads entitsra s nem az eladso-ra vonatkozna.
5.1. Plda: Rajzoljuk fel Jackson-brval az egyszer knyv szerkezett. Ennek a knyvnek
van egy ellapja s egy htlapja, kzte pedig a knyv oldalai tallhatk. Minden oldalon so-
rok, a sorokban pedig szavak vannak. Minden oldal aljn egy oldalszm is tallhat.
A knyv nyilvn egy szekvencia formjban tartalmazza az ellapot, az oldalakat s a ht-
lapot (ebben a sorrendben). Az oldalak nev entits tbb oldalt tartalmaz, ez egy iterci lesz.
Az oldal nev entitson sorok tallhat s egy oldalszm (szekvencia). A sorok tbb sorbl
llnak (iterci), a sorok pedig szavakbl (iterci). A knyv Jackson-brja az 5.3. brn
lthat.
A Jackson-brk rajzolsa kzben tbb tpushibt el lehet kvetni: a els a szintaktikus hi-
ba, amikor a lerajzolt bra nem felel meg a Jackson-bra szablyainak; a msodik a szemanti-
kus hiba, amikor a lerajzolt bra nem a modellezend objektumot rja le. Mindkt hibra mu-
tat pldt az 5.4. bra. Ha pusztn a rajzol szndkt vizsgljuk s pillanatnyilag eltekintnk
a szintaktikus hibktl, a kvetkez jelentst fedezhetjk fel: a knyv cmlapbl, oldalakbl
s htlapbl ll, ahol az oldalak sorokbl llnak, a sorok pedig szavakbl (tbb szbl) s egy
oldalszmbl. Ez utbbi definci nagy valsznsggel hibs: a knyvek ltalban nem tar-
talmazzk minden sor vgn az oldalszmot. Ez rossz modellje a valsgnak. Vizsgljuk most
meg az alkalmazott szintaxist. A knyv entits defincija veti fel az els krdst: milyen
szerkezet ez? Szekvencinak nem alkalmas, mert az egyik tglalapban csillag jelzs tallhat,
itercinak szintgy nem j, mert a definciban tbb tglalap is szerepel, radsul csillag
nlkliek is. Ez teht hibs jells: a helyes megolds az lenne, hogy az oldalakat (oldal*)
kln szinonimaknt (oldalak) jelljk, majd ezt definiljuk oldal*-knt, amint azt az erede-
ti megoldsban az 5.3. brn tettk. Hasonl jelleg hiba tallhat a sor defincijban is, ahol
a sz* helytelenl szerepel: itt is kellene egy szavak nev szinonima, amelyet aztn lehet
sz*-knt tovbb rszletezni.
5.2. Plda: Egy hromszget tbbfle adatszerkezettel is lerhatunk: megadhatjuk pl. a h-
romszg hrom oldalnak hosszt (A, B, C), vagy megadhatjuk kt oldalnak hosszt (A, B) s
az azok ltal kzbezrt szget (Gamma). Mindkt adatszerkezet egy egyszer szekvencia,
ahogy azt az 5.5. bra mutatja. Ksztsnk egy programot, amely kiszmtja a hromszg te-
rlett az els brzolsi mdot alkalmazva. A terletet Hron kpletvel szmthatjuk ki
a kvetkezkppen:
T = S (S A)(S B )(S C ) , ahol S a kerlet fele: S = ( A + B + C ) / 2 .
5.7. bra. A karakterszmol program bemeneti s kimeneti adatszerkezeteinek, valamint a program vezr-
lsi szerkezetnek lersa Jackson-brk segtsgvel.
Feladatok:
5.1. Rajzoljuk fel a leckeknyv lerst, az albbi mdostsokkal:
Egy tantrgyhoz tartozhat elads s gyakorlat is (egyszerre is)
A tantrgyak eladsainak s gyakorlatainak raszmt s meg kell adni (pl. egy trgy
lehet elads heti 4 rban, a msik gyakorlat heti 2 kt rban, egy harmadik heti kt
eladst s kt gyakorlatot tartalmaz).
A tantrgyakhoz rendeljnk oktatt (minden trgyhoz egyet).
Az oktatknak legyen neve.
Az oktatk s hallgatk nevt definiljuk tovbb: a nv vezetknvbl s egy vagy kt
keresztnvbl lljon.
Egsztsk ki a tantrgyat egy alrs rovattal, amelynek rtke lehet alrva, megta-
gadva, vagy nincs kitltve. Az osztlyzat lehet elgtelen, elgsges, kzepes,
j, jeles, vagy nincs kitltve.
5.2. Ksztsk el a terletszmt program Jackson-brs lerst arra az esetre, amikor
a hromszg kt oldalt (A s B), valamint az ltaluk kzbezrt szget ( ) troljuk.
AB sin
(A terlet ekkor a T = kplettel szmthat.)
2
A programot ksztsk el oly mdon is, hogy a szget fokban olvassuk be, de azt a szi-
nusz fggvny szmtshoz szksges radinba talaktjuk ( rad = fok ).
180
Mdostsuk a programot gy, hogy a bemen adatok beolvassa eltt rja ki, hogy mi-
lyen adatot vr (pl.: Krem az A oldal rtkt: ).
5.3. Javtsunk az egsz szmokat definil regulris defincinkon gy, hogy a szmok ne
kezddhessenek nullval kivve magt a 0 szmot.
5.4. A vltozk neve egy programozsi nyelvben olyan karaktersorozat lehet, ami betvel
kezddik s utna tetszleges szm bett s szmot tartalmazhat (a bet nem lehet ke-
zetes). Pl. leglis vltoznevek: ALMA12, tmp, i, ZiZi12. Nem leglis vltoznevek pl.
a kvetkezk: 12, 4musketas, plpusztaisajt, macska:nyelv, stb. Definiljuk a vltoz-
nv fogalmt regulris defincikkal a fentiek szerint.
5.5. Az albbi defincik egy egyszer, fORDT nev programozsi nyelv hasznlatt mutat-
jk be. A definci alapjn rajzoljuk fel a fORDT program Jackson-brs megfeleljt.
fORDT program Fejlc Programtrzs Bcs
Fejlc fORDT Program_neve start
Bcs TDROf
Programtrzs Vltozk_deklarlsa Utastsok
Vltozk_deklarlsa USING Vltozk GNISU
Vltozk Vltoz*
Utastsok Utasts*
Utasts Beolvass | Kirs | Mvelet | Ciklus
Beolvass READ vltoz
MIN MAX
Hny SU van a ZBULU-ban?
Hny CE van a ZBULU-ban?
Hny KA van a ZBULU-ban?
Hny BIL van a ZBULU-ban?
Hny MELB van a ZBULU-ban?
Hny SMUL van a ZBULU-ban?
Hny BIL van a MELB-ben?
Hny CE van a SMUL-ban?
6.1. bra. A kerlet- s terletszmt program bemeneti s kimeneti adatszerkezeteinek, valamint a prog-
ram vezrlsi szerkezetnek lersa Jackson-brk segtsgvel.
Simon Gyula, PE www.tankonyvtar.hu
78 A PROGRAMOZS ALAPJAI
double A, B, C, T, S, K;
int main(){
printf("Az A oldal hossza:");
scanf("%lf", &A);
printf("A B oldal hossza:");
scanf("%lf", &B);
printf("A C oldal hossza:");
scanf("%lf", &C);
K=(A+B+C);
S=K/2;
T=sqrt(S*(S-A)*(S-B)*(S-C));
printf("\nA terlet: %lf\n", T);
printf("\nA kerlet: %lf\n", K);
return 0; /* sikeres vgrehajts jelzse */
}
ez a T lebegpontos szm. A fenti parancs teht elszr sort emel, majd kirja az A terlet:
karaktersorozatot, majd a T lebegpontos szm rtkt, amit egy jabb soremels kvet.
A printf fggvny vezrl mezjben tetszleges szm formtumvezrl helyezhet el, ter-
mszetesen ennek megfelel szm paramtert kell a formtumvezrl mez utn mg tadni
a printf() fggvnynek. Pl. a printf(" Ide jn egy egsz: %d, ide egy karak-
ter: %c, ide meg egy karaktersorozat: %s ", 3, 'Q', "ALMA") fggvnyh-
vs a kvetkez szveget rja ki:
Ide jn egy egsz: 3, ide egy karakter: Q, ide meg egy karaktersorozat: ALMA.
A printf fggvny szmos egyb lehetsggel rendelkezik, ezek rszletes lersa megtallhat
a [4] irodalomban. A leggyakrabban hasznlt formtumvezrlk ismertetse az F2. fggelk-
ben tallhat.
A C nyelvben a scanf() fggvny szolgl formzott beolvassra. Els paramtere a formtum-
vezrl karaktersorozat, a tbbi paramtere a beolvasand vltozk cmeit tartalmazza. Pld-
ul a scanf("%lf", &A) parancsban a formtumvezrl egy darab lebegpontos szm beol-
vasst kri, amelyet az A vltozba kell tlteni, amit a fggvny msodik paramtere jelez:
a & cmkpz opertorral jelezzk, hogy nem az A vltoz rtkt adjuk t a fggvnynek,
hanem a vltoz cmt. A printf() fggvnyhez hasonlan ms vezrl karakterek is hasznl-
hatk, gy pldul a scanf("%d", &X) parancs egy egsz szmot olvas be az X vltozba,
a scanf("%c", &c) paranccsal egy karakter olvasunk be a c vltozba, mg
a scanf("%s", str) parancs egy karakterlncot olvas be a str nev vltozba. (Vigyzat:
a C nyelvben a karaktertmbk neve a vltoz cmt (s nem rtkt) jelzi, gy az utols pl-
dban a str vltoz neve el mr nem kell a cmkpz opertor.)
A C nyelvben a matematikai mveletek jellse a szoksos mdon trtnik, az rtkadst az
egyenlsgjel jelzi. A ngyzetgyk szmtsra hasznlatos fggvny a sqrt.
A programot a return utasts zrja, amely a main fggvny visszatrsi rtkt lltja be
nullra, amely a programot hv szmra jelzi, hogy a vgrehajts rendben lezajlott.
A C nyelvben az utastsokat pontosvesszvel kell lezrni.
struct haromszog{
double A; /* a oldal hossza */
double B; /* b oldal hossza */
double C; /* c oldal hossza */
};
struct eredmeny{
double K; /* kerlet */
double T; /* terlet */
};
int main(){
/* Az A oldal bekrse: */
printf("Az A oldal hossza:");
scanf("%lf", &Haromszog.A);
/* A B oldal bekrse: */
printf("A B oldal hossza:");
scanf("%lf", &Haromszog.B);
/* A C oldal bekrse: */
printf("A C oldal hossza:");
scanf("%lf", &Haromszog.C);
Eredmeny.K=(Haromszog.A+Haromszog.B+Haromszog.C); /* kerlet */
S=Eredmeny.K/2; /* a fl kerlet Hron albbi kplethez */
Eredmeny.T=sqrt(S*(S-Haromszog.A)*(S-Haromszog.B)*(S-
Haromszog.C));
/* Az eredmnyek kirsa: */
printf("\nA terulet: %lf\n", Eredmeny.T);
printf("\nA kerulet: %lf\n", Eredmeny.K);
return 0;
}
A struktrk j tpusokat hoznak ltre a beptett tpusok (pl. double, int) mell. Ezeket a tpu-
sokat elszr definilni kell. A fenti pldban ltrehozunk kt j struktra tpust, amelyeket
haromszog s eredmeny neveken definilunk. A haromszog struktra tpus mezinek neve
rendre A, B s C, a mezk mindegyike double tpus. A struktrk defincija a struct
kulcsszval kezddik, majd a struktra tpus neve kvetkezik. Ezutn kapcsos zrjelek k-
ztt megadjuk egyenknt a mezk tpust s nevt pontosvesszvel lezrva (hasonlan a vl-
tozdeklarcihoz). A struktra defincijt pontosvessz zrja.
A haromszog struktra tpushoz hasonlan definiljuk az eredmeny struktratpust is,
amelynek kt mezje a K s T s ezek szintn double tpusok.
Figyelem: a haromszog s eredmeny mg nem vltozk, ezek csak vltoz tpusokat defi-
nilnak. Ezek segtsgvel definilhatunk olyan vltozkat, amelynek szerkezete megegyezik
a tpusdefinciban lertakkal. A struktrk ltrehozsa a program kvetkez kt sorban tr-
tnik. A vltoz deklarcik szablyai szerint a tpust kveti a vltoz neve: jelen esetben
a tpus struct haromszog, mg a vltoz neve Haromszog (a C nyelv megklnbzteti
a kis- s nagybetket). Hasonlan a struct eredmeny tpusbl ltrehozunk egy Eredmeny
nev vltozt. (Figyelem: a C nyelvben a struktrk tpusa el mindig oda kell rni a struct
kulcsszt is!)
A struktra mezire a vltoz nevvel, majd a pont opertor utn a mez nevvel hivatkoz-
nunk. Pl. a Haromszog.C a Haromszog nev struktra C nev mezjt jelenti.
Figyelem: csakgy, mint brmely vltoznak, a struktra mezjnek is van tpusa. Jelen pl-
dnkban mindkt struktra valamennyi mezje double tpus volt.
A pldban lthat mdon a struktra mezinek ugyangy adunk rtket, mint a hasonl tpu-
s vltozknak. A hivatkozott mezket pedig ugyangy hasznlhatjuk (pl. aritmetikai oper-
cikban), mint a hasonl tpus vltozkat.
s vgl egy szomor hr: a C nyelvben a vltozk, tpusok, (s ksbb a fggvnyek) nevei
sajnos nem tartalmazhatnak kezetes karaktereket. Ezrt hasznltunk pl. Eredmeny nev vl-
tozt a szebb de hibs Eredmny helyett.
A kalzok nagy lvezettel s gyakran adjk-veszik egyms kztt a zskmnyolt hajkat. Saj-
nos a rum hatsa alatt kttetett szbeli megllapodsokra msnap mr gyakran nem emlkeznek
a felek, ami sokszor komoly, st vrre men vitkat eredmnyez. Morc Misi ezrt korszerste-
ni akarja a haj-adsvtelek adminisztrcijt: szmtgpes programot akar kszttetni e clra,
amellyel szp formtumban lehet hivatalos szerzdseket gyrtani. Egy haj adsvteli szerz-
dse tartalmazza az elad, a vev, valamint a haj adatait, valamint a vtelrat s az adsvtel
dtumt. Az eladrl s a vevrl troljuk a nevt, szletsi idejt s a titkos kalz-azonost
(KAZ) szmt, a hajrl pedig a nevt, tpust, hosszt s rbocszmt.
6.3. plda: rjunk egy egyszer programot Morc Misinek, amely beolvassa egy szerzds
adatait, majd kirja azokat a standard kimenetre (ez ltalban a kperny). (Innen Misi tuds
alrendeltjei mr tudnak paprra is nyomtatni) [6.adasvetel1.c].
A 6.2. bra mutatja a feladat megfogalmazsa szerinti adatszerkezeteket. Az adsvteli
szerzds szekvenciaknt tartalmazza az elad adatokat, a vev adatokat, a haj adatait,
a vtelrat s a keltezst. Szintn szekvenciaknt brzolhatk a vev s elad adatai, radsul
ezek ugyanolyan szerkezetek, hiszen kalzokat rnak le: tartalmazzk a nevket, szletsi
dtumukat s a titkos KAZ-szmukat. A haj adatai szintn szekvencit alkotnak, melynek
elemei a haj neve, tpusa, hossza s rbocainak szma. Megfigyelhetjk tovbb, hogy a d-
tum tbb helyen is szerepel: mind a szerzds keltezse, mind a szletsi idk dtumok.
A feladat megfogalmazsa ugyan nem tartalmazza, de mg a hajsinasok is tudjk, hogy
a dtum egy vszmbl, egy hnapbl s egy napbl ll (ami ismt egy szekvencia).
A program szerkezete nagyon egyszer, ahogyan az a 6.3. brn lthat: egy beolvasst s
egy kirst tartalmaz, ahol mindkt tevkenysg pontosan tkrzi az adatszerkezetet (hiszen
mind a beolvass, mind a kirs pontosan ezt az adatszerkezetet jrja be).
6.3. bra. A hajk adsvteli szerzdst kezel program lersa Jackson-bra segtsgvel.
A 6.2. bra szerinti adatszerkezet lersra ismt a struktrk adnak termszetes lehets-
get. Az bra szerint egy struktrban brzolhatjuk magt a Szerzdst, amelynek mezi
az Elad, Vev, Haj, Vtelr, Keltezs lesznek. Az eladt s a vevt szintn egy-egy strukt-
ra rja le, melynek mezi a Nv, a Szletsi id s a KAZ-szm. A haj is struktrval br-
zolhat, amely a Nv, Tpus, Hossz s rbocszm mezket tartalmazza. A dtumokat is br-
zolhatjuk egy-egy struktrval, amelynek mezi az vszm, a Hnap s a Nap lesznek. Fi-
gyeljk meg, hogy a fenti adatszerkezetben vannak olyan struktrk, amelyek tartalmaznak
struktrkat (pl. a Szerzds Elad, Vev s Keltezs mezi szintn struktrk). Ez termsze-
tes, hiszen a szekvencik elemei lehetnek elgazsok, itercik, vagy akr szekvencik is:
jelen esetben a szekvencik tovbbi szekvencikat tartalmaznak, amelyek struktrkat tartal-
maz struktrkk kpzdnek le adatszerkezeteinkben.
A C nyelv programban az elzekhez hasonlan elszr definiljuk a struktrk tpusait,
majd ezekbl hozunk ltre vltozkat. A struktrk tpusainak a kvetkez neveket vlasztot-
tunk: szerzodes, kaloz, hajo, datum. A struktrk mezinek nevei a fenti, de kezetek
nlkli meznevekkel egyeznek meg. A programban ezen tpusok alapjn ltrehozzuk s
hasznljuk a Szerzodes, Kaloz, Hajo s Datum nev vltozkat:
/*
* Haj adsvteli szerzds adatainak bekrse s kirsa.
*/
#include <stdio.h>
#define _MAX_HOSSZ 20
struct datum{
unsigned int Evszam; /* a dtum vszm mezje */
unsigned int Honap; /* a dtum hnap mezje */
unsigned int Nap; /* a dtum nap mezje */
};
struct kaloz{
char Nev[_MAX_HOSSZ+1]; /* a kalz neve */
struct datum Szuletesi_ido; /* a kalz szletsi ideje */
unsigned int KAZ_szam; /* a kalz KAZ-szma */
};
struct hajo{
char Nev[_MAX_HOSSZ+1]; /* a haj neve */
char Tipus[_MAX_HOSSZ+1]; /* a haj tpusa */
unsigned int Hossz; /* a haj hossza */
unsigned int Arbocszam; /* a haj rbocainak szma */
};
struct szerzodes{
struct kaloz Elado; /* az elad adatai */
struct kaloz Vevo; /* a vev adatai */
int main(){
printf("Kaloz adasveteli szerzodes bevitele\n");
printf("\t\tTipus: ");
scanf("%s", Hajo.Tipus);
printf("\t\tHajo hossza: ");
scanf("%d", &Hajo.Hossz);
printf("\t\tHajo arbocszama: ");
scanf("%d", &Hajo.Arbocszam);
Szerzodes.Hajo=Hajo; /* trols a szerzdsben */
printf("\n\tElado adatai:\n");
Kaloz=Szerzodes.Elado;
/* elad adatainak kirsa meznknt*/
printf("\t\tNev: %s\n", Kaloz.Nev);
Datum=Kaloz.Szuletesi_ido;
printf("\t\tSzuletesi ido: %d.%d.%d.\n", Datum.Evszam,
Datum.Honap, Datum.Nap);
printf("\t\tTitkos kaloz azonosito: %d\n", Kaloz.KAZ_szam);
printf("\n\tVevo adatai:\n");
Kaloz=Szerzodes.Vevo;
/* vev adatainak kirsa meznknt*/
printf("\t\tNev: %s\n", Kaloz.Nev);
Datum=Kaloz.Szuletesi_ido;
printf("\t\tSzuletesi ido: %d.%d.%d.\n", Datum.Evszam,
Datum.Honap, Datum.Nap);
printf("\t\tTitkos kaloz azonosito: %d\n", Kaloz.KAZ_szam);
printf("\n\tHajo adatai:\n");
Hajo=Szerzodes.Hajo;
/* a haj adatainak kirsa meznknt*/
printf("\t\tNev: %s\n", Hajo.Nev);
/* vtelr kirsa */
printf("\n\tHajo vetelara: %d\n", Szerzodes.Vetelar);
/* keltezs kirsa */
Datum=Szerzodes.Keltezes;
printf("\n\tSzerzodeskotes idopontja %d.%d.%d.", Datum.Evszam,
Datum.Honap, Datum.Nap);
return 0;
}
A program elejn tallhat #define direktva a C nyelvben gyakran hasznlatos, ennek se-
gtsgvel lehet pldul konstansokat is ltrehozni, ahogy azt programunkban tettk is.
A #define _MAX_HOSSZ 20 jelentse a fordtprogram szmra a kvetkez: a program-
ban tallhat sszes _MAX_HOSSZ karaktersorozatot a 20 karaktersorozattal kell helyet-
testeni. Rossz programozsi gyakorlat, ha bvs szmokat hagyunk a programunkban (pl.
char Nev[_MAX_HOSSZ+1] helyett char Nev[21]), a konstansokat mindig lssuk el be-
szdes nvvel s azokat hasznljuk. Ezzel programunk sokkal ttekinthetbb, rthetbb lesz
s sok munkt s kellemetlensget sprolhatunk meg magunknak a ksbbiekben. (Kpzeljk
el pl. hogy valamilyen okbl meg kell nvelnnk a programunkban _MAX_HOSSZ rtkt 20-
rl 40-re: ekkor egyetlen sort kell csak mdostanunk s clunkat elrtk. Ha a bvs 21 sz-
mot alkalmaztuk volna a programban, akkor tbb helyen is mdostani kellene a 21 rtkt
41-re. De vajon minden programunkban elfordul 21-est mdostani kell? Jelen progra-
munkban igen, de ez nincs mindig gy...)
A program a struktratpusok defincijval folytatdik. A struktrk defincijnl gyelni
kell a defincik sorrendjre. Pldul a szerzodes tpus struktrk egyes mezi struktrk
(kaloz s datum tpusak), gy a szerzodes struktratpus defincijakor a fordtnak mr
tudni kell, hogy ezek a tpusok lteznek. Ehhez a kaloz s a datum struktratpusokat
a szerzodes struktratpus eltt kell definilni. Hasonlan a datum struktratpus definci-
jnak meg kell elznie a kaloz struktratpus defincijt.
A datum struktra tpus hrom mezt tartalmaz (Evszam, Honap, Nap), melyek mindegyike
unsigned int tpus: ez a C nyelvben az eljel nlkli egsz szmot jelenti (az int lehet
negatv szm is, az unsigned int nem). A kaloz struktratpus mezi a Nev karakter-
tmb, a Szuletesi_ido, ami egy datum tpus struktra, valamint az eljel nlkli egsz
tpus KAZ_szam. A C nyelvben a tmbket gy deklarljuk, mint a tmb elemeinek megfe-
lel tpust, csak a vltoz neve (vagy jelen esetben a mez neve) mgtt szgletes zrjelben
megadjuk a tmb mrett is. A programban a char Nev[_MAX_HOSSZ+1] jelentse teht az,
hogy a Nev egy _MAX_HOSSZ+1 mret tmb, amelynek elemei karakterek. A tmbk hasz-
nlatval rszletesen majd a 8. fejezetben foglalkozunk. Most mg egy hasznos tudnival: a C
nyelvben a karakterlncok vgt egy specilis zr karakter (melynek kdja a 0) jelzi, ezrt
a karaktertmbben ennek egy helyet clszer fenntartani. Ha a _MAX_HOSSZ a nevek maxi-
mlis hosszt jelenti, akkor a tmbnek _MAX_HOSSZ+1 hossznak kell lennie, hogy a leg-
hosszabb nv is elfrjen benne a zr karakterrel egytt.
A hajo struktratpus mezi a Nev s a Tipus karaktertmbk (mindegyik hossza itt is
_MAX_HOSSZ+1), valamint a Hossz s Arbocszam eljel nlkli egszek. A szerzodes
tpus struktrk tartalmaznak egy Elado s egy Vevo nev mezt, amelyek struct kaloz
tpusak, egy Hajo nev mezt, ami strukt hajo tpus, egy eljel nlkli egsz tpus
Vetelar mezt, valamint egy Keltezes nev mezt, ami struct datum tpus.
A fenti struktrkbl ezutn ltrehozunk egy-egy vltozt, amelyek neve rendre Datum,
Kaloz, Hajo s Szerzodes.
A main fggvnyben a program elszr az elad adatait kri be oly mdon, hogy a felhaszn-
l szmra elszr mindig kirja a bekrend adat nevt, majd bekri az adatot. A nv egy
karakterlnc, ezrt a scanf fggvnyben %s formtumvezrlt hasznljuk (s nincs & cm-
kpz opertor a vltoz neve eltt). A nevet a Kaloz struktra Nev mezjben troljuk, teht
a bekrs sorn a Kaloz.Nev hivatkozst hasznljuk, ide fogja a scanf fggvny betlteni
a begpelt nevet (egy zr karakterrel a vgn). Figyelem: a scanf fggvny csak szkzig
olvas, gy a nv nem tartalmazhat szkzt: ezzel a megoldssal csak egytag neveket lehet
hasznlni. Ms fggvnyek (pl. fgets) felhasznlsval lehetsges egsz sorok kezelse,
amelyek mr szkzket is tartalmazhatnak.
A szletsi id bekrsnl a formzott bemenet kezelsre ltunk pldt. A dtumot v-
szm.hnap.nap. formtumban krjk be. Ezt a formtumot tartalmazza a scanf fggvny
formtumvezrl mezje: hrom egsz szmot krnk be, amiket pont karakterek vlasztanak
el egymstl. A scanf fggvny a hrom egsz szmot rendre a Datum struktra Evszam,
Honap s Nap mezibe tlti. A Datum struktrt a kvetkez rtkad utasts
(Kaloz.Szuletesi_ido=Datum) tlti be a Kaloz struktra Szuletesi_ido mezjbe.
Figyeljk meg, hogy itt az egsz struktrt (minden egyes mezjvel) egyetlen utastssal
adjuk rtkl a msik struktrnak, nem szksges ezt meznknt vgezni. A KAZ-szm be-
tltse egsz szmknt trtnik a mr ismert mdon. Az elad adatainak beolvassa utn
a kalz struktrt rtkl adjuk a Szerzodes struktra Elado mezjnek.
A printf utastsokban a mr ismert \n (j sor) mellett egy jabb vezrl karakterrel tall-
kozhatunk: a \t a tabultor karaktert jelenti.
A vev adatait hasonl mdon olvassuk be ismt a Kaloz vltozba, majd onnan
a Szerzodes struktra Vevo mezjbe.
Az elad s vev adatait alternatv mdon, a Kaloz vltoz hasznlata nlkl is be lehet ol-
vasni. Ekkor minden adatot kzvetlenl a Szerzodes struktra Elado vagy Vevo mezj-
nek megfelel mezjbe kell beolvasni. Pldul az elad nevt gy is beolvashatjuk:
scanf("%s", Szerzodes.Elado.Nev)
A haj adatait hasonl mdon olvassuk be a Hajo vltozba, majd ezt adjuk rtkl
a Szerzodes vltoz Hajo mezjnek. A vtelrat a egyenesen a Szerzodes Vetelar
mezjbe olvassuk be, mg a szerzdskts idpontja elszr a Datum segdvltozba, majd
onnan a Szerzodes struktra Keltezes mezjbe kerl.
A szerzds kirsakor a Szerzodes struktra megfelel mezit rjuk ki, a megfelel szve-
ges krtssel. Az elad s vev adatait elszr a Kaloz vltozba tltjk, majd annak mezit
rjuk ki. Termszetesen itt lehetne a Szerzodes struktra Elado vagy Vevo mezjnek
megfelel mezit egybl, segdvltoz hasznlata nlkl is kirni, pl.:
printf("\t\tNev: %s\n", Szerzodes.Elado.Nev);
A szerzds tbbi adatnak kirsa hasonl mdon trtnik.
Feladatok:
6.1. Ksztsnk tekns-grafika segtsgvel olyan programot, amely kirajzol egy ngyzetet
a kpernyre, ahol a ngyzet kt tellenes pontjnak koordinti (10,10) s (90,90).
A tekns-grafika elemi mveletei a kvetkezk:
Tollat letesz: a tekns a paprra ereszti a toll hegyt, gy ha a tovbbiakban mo-
zog, akkor vonalat hz maga utn.
Tollat felvesz: a tekns felemeli a tollat, gy nem hz maga utn vonalat akkor
sem, ha mozog.
Odamegy(x,y): A tekns az (x,y) koordintj pontba ballag a jelenlegi pozci-
jbl, mgpedig egy egyenes mentn haladva.
Elre megy(d): a tekns a jelenlegi irnyban halad elre d egysget.
Irnyba ll(alfa): A tekns az alfa irnyba fordul (de nem halad). Az alfa szget
az x tengely pozitv irnyhoz kpest mrjk (0 fok a pozitv x irny, 90 fok
a pozitv y irny, 180 fok a negatv x irny, stb.)
Elfordul(delta): A tekns a jelenlegi irnyhoz kpest elfordul delta fokot.
(A programot rhatjuk pszeudo-kdban, vagy akr implementlhatjuk pl. Scratch alatt is:
http://scratch.mit.edu/)
6.2. Ksztsnk el a 6.1. feladat tekns-grafikja segtsgvel azt a programot, amely hrom
darab ngyzetet rajzol ki, amelyek bal als sarknak koordinti rendre (10,10), (20,20)
s (30,50). A ngyzetek oldalai legyenek 20 egysg hosszak s prhuzamosak a koor-
dinta-rendszer tengelyeivel.
rjuk meg gy a programot, hogy a lehet legkevesebb gondolkodssal legyen mdost-
hat a kd, ha mshov szeretnnk a ngyzeteket helyezni. (Tipp: csak a ngyzet els
cscsnak elhelyezshez hasznljuk az Odamegy s Irnyba ll parancsokat, a tbbi
oldalt a relatv mozgsokat ler Elfordul s Elre megy parancsokkal rajzoljuk meg.)
6.3. Rajzoljunk a 6.1. feladat tekns-grafikja segtsgvel egy szablyos hatszget, melynek
kzppontja az origban van, oldalai pedig 50 egysg hosszak. A hatszg kt oldala
legyen prhuzamos az x tengellyel.
Rajzoljunk hasonl mdon 12-szget. (Tipp: hasznljunk relatv mozgsokat ler pa-
rancsokat.)
6.4. Morc Misi a szerzdsekre ezentl nem csak az elad s a vev, de az gyvd s a kt
tan adatait rgzteni akarja (termszetesen ezek is kalzok).
Mdostsuk az adatszerkezetek tervt alkalmas mdon.
Mdostsuk a program tervt alkalmas mdon.
Mdostsuk a C nyelv programot is.
6.5. A kalzok ltalban arany dukttal fizetnek egymssal kttt zleteik sorn, gy Morc
Misi eredeti szerzds programjt is csak erre ksztettk fel (a vtelr arany duktban
volt rtend). Az utbbi idben azonban felmerlt az igny, hogy ms fizeteszkzket
is lehessen a hajk adsvtelnl hasznlni (Fllb Ferk a mlt hten pldul egy tu-
cat vak papagjrt vett meg egy elsllyedt ktrbocos szknert Szagos Szilrdtl).
int main(){
double a, b, c; /* a hromszg oldalai */
printf("Adja meg az elso szakasz hosszat: ");
scanf("%lf", &a);
printf("Adja meg a masodik szakasz hosszat: ");
scanf("%lf", &b);
printf("Adja meg a harmadik szakasz hosszat: ");
scanf("%lf", &c);
/* Hromszg akkor szerkeszthet, ha brmely kt szakasz
hossznak sszege nagyobb, mint a harmadik szakasz hossza. */
if (a+b>c && a+c>b && b+c>a) {
printf("A megadott szakaszokbol szerkesztheto haromszog.\n");
printf("Gratulalok.\n");
}else
printf("Sajnos nem szerkesztheto haromszog.\n");
return 0;
}
A fenti program a C nyelvben hasznlatos elgazs hasznlatt mutatja be. Az egyg elga-
zs a C nyelvben a kvetkez formj:
if (felttel) utasts
Az utasts akkor hajtdik vgre, ha a felttel igaz. (A C nyelvben egy kifejezs hamis, ha
annak rtke nulla, ellenkez esetben igaznak minsl). Pl. ilyen egyszer felttelek lehetnek:
A>0 (A nagyobb nullnl),
A==B (A egyenl-e B-vel. Figyelem: logikai kifejezsekben kt egyenlsgjel szksges,
a szimpla egyenlsgjel rtkadskor hasznlatos.)
B!=5 (B nem egyenl ttel)
A>=B (A nagyobb, vagy egyenl, mint B)
A<=3 (A kisebb, vagy egyenl, mint 3)
Figyelem: gyakori hiba, hogy az egyenlsg vizsglatakor a B=5 formt hasznljuk. Ilyen
esetekben ugyan szintaktikailag helyes kdot rtunk, hiszen a B=5 egy kifejezs, gy rtke is
van (jelen esetben az rtkads eredmnye, azaz 5 lesz a kifejezs rtke), ami nem nulla,
teht a felttel igaz, fggetlenl B korbbi rtktl. Radsul a B vltoz rtkt fell is r-
tuk... Halad C programozk az if(A=B) formt hasznljk a kvetkez kdszekvencia kife-
jezs rvid jellsre:
A=B;
if(A)utasts.
Az utasts lehet egyetlen vagy tbb utasts is, ez utbbi esetben az utastsokat kapcsos
zrjelek kz kell tenni (ezt a C nyelvben blokk, vagy sszetett utastsnak nevezik), mint az
a pldban is lthat.
A ktg elgazsok formja a C nyelvben a kvetez:
if(felttel)
utasts1
else
utasts2.
Ha a felttel igaz (nem nulla), akkor az utasts1, ellenkez esetben pedig az utas-
ts2 hajtdik vgre.
Tbbg elgazsokat rtelemszeren lehet kszteni ktg elgazsokba gyazott elgaz-
sok segtsgvel. Pl. a 3.4. bra szerinti elgazs C nyelven a kvetkez alak lesz:
if(felttel1)
tevkenysg1
else if(felttel2)
tevkenysg2
else if(felttel3)
tevkenysg3
else
tevkenysg4
7.1. bra. A hajk s papagjok adsvtelt adminisztrl program adatszerkezetnek lersa. Az brn nem
rszletezett elemek tovbbi defincija a 6.2. brn tallhat.
Az enum a C nyelvben olyan tpusok definilsra szolgl, ahol a vltozk rtkkszlete egy
vges halmaz elemeibl ll. Jelen esetben az enum arutipus{HAJO, PAPAGAJ} utasts
egy olyan arutipus nev tpust definil, amelyben a vltozk rtke vagy HAJO, vagy
PAPAGAJ lehet (ezeket a fordt egy egsz szmm konvertlja, teht a HAJO helyett pl. nul-
lt, a PAPAGAJ helyett pedig 1-et trol, de ezzel neknk nem kell trdnnk).
7.2. bra. A hajk s papagjok adsvtelt adminisztrl program lersa. Az brn nem rszletezett tev-
kenysgek defincija meggyezik a 6.3. brn tallhat defincikkal.
vagy papagj (s csak az egyik), itt mgis mindkett szmra helyet foglaltunk (radsul
az rutpust is el kellett trolnunk), teht a struktrban a szelekci helyett egy szekvencit
valstottunk meg. Ennek oka az, hogy a C nyelv (s ltalban a programozsi nyelvek tbb-
sge) nem biztost elegns lehetsget a szelekcik megvalstsra adatszerkezetek szintjn.
Egy kicsit fejlettebb megoldst azonban erre a problmra is hamarosan adunk.
A szerzodes struktratpusban megjelenik az Arucikk mez (a korbbi Hajo helyett):
struct szerzodes{
struct kaloz Elado; /* az elad adatai */
struct kaloz Vevo; /* a vev adatai */
struct aru Arucikk; /* az ru adatai */
unsigned int Vetelar; /* a haj vtelra */
struct datum Keltezes; /* a szerzds kelte */
};
Nhny j vltozt is hasznlunk: ltrehozunk egy papagaj tpus Papagaj nev vlto-
zt, amiben tmenetileg a papagjok adatait troljuk (bekrskor s kirskor), hasonlan
az aru tpus Arucikk nev struktrt az rucikk tmeneti trolsra fogjuk hasznlni, mg
az arutipus_input nev ktelem karaktertmbben a felhasznl ltal begpelt, az ru
tpust azonost karaktert (haj esetn h bett, papagj esetn p bett) fogjuk trolni:
struct papagaj Papagaj;
struct aru Arucikk;
char arutipus_input[2]; /* tpus jelzse: (h)aj vagy (p)apagj*/
A program tovbbi rszben az adatok bekrse s kirsa a korbbiak szerint zajlik, csak
az ruk kezelse vltozott. Az rucikk bekrsekor elszr bekrjk az ru tpust
az arutipus_input nev vltozba a scanf fggvnnyel. Ha ez egy h bet, akkor egy
haj adatait krjk be (a korbbiak szerint), ha ez egy p bet, akkor egy papagjt, ms eset-
ben pedig hibajelzst adunk.
printf("\n\tAru adatai:\n");
printf("\t\tAru tipusa:\n\t\t\t(h)ajo vagy (p)apagaj?");
scanf("%1s", arutipus_input);
if(arutipus_input[0]=='h'){
/* haj adatainak bekrse */
...
Arucikk.Arutipus=HAJO;
Arucikk.Hajo=Hajo;}
else if(arutipus_input[0]=='p'){
/* papagj adatainak bekrse */
printf("\t\tPapagaj adatai:\n");
printf("\t\t\tNev: ");
scanf("%s", Papagaj.Nev);
printf("\t\t\tSzuletesi ido [e.h.n.]: ");
scanf("%d.%d.%d.", &Datum.Evszam, &Datum.Honap, &Datum.Nap);
Papagaj.Szuletesi_ido=Datum;
Arucikk.Arutipus=PAPAGAJ;
Arucikk.Papagaj=Papagaj;
}
else{
printf("Ismeretlen arutipus: %s\n ", arutipus_input);
return -1;
}
Szerzodes.Arucikk=Arucikk;
if(Arucikk.Arutipus==HAJO){
/* haj adatainak kirsa */
...
}
else{
/* papagj adatainak kirsa */
printf("\n\tPapagaj adatai:\n");
Papagaj=Arucikk.Papagaj;
printf("\t\tNev: %s\n", Papagaj.Nev);
Datum=Papagaj.Szuletesi_ido;
printf("\t\tSzuletesi ido: %d.%d.%d.\n",
Datum.Evszam, Datum.Honap, Datum.Nap);
printf("\n\tPapagaj ");
}
Okos Ottokr, aki a kalzok informatikai rendszereit (vagyis a mlt vben zskmnyolt lapto-
pot s nyomtatt) zemelteti s felgyeli, megkrdezte a szerzdskezel program ksztjt,
Sunyi Sanyit, stni vigyorral a bajusza alatt:
Ha a jv hten szksges lenne, hogy a programot pisztolyok adsvtelhez is mdostsuk,
akkor az aru struktratpus gy nzne ki, ugye? s Sunyi Sanyi orra al dugott egy kiss
viseltes paprfecnit a kvetkez iromnnyal:
struct aru{
enum arutipus Arutipus;
struct hajo Hajo;
struct papagaj Papagaj;
struct pisztoly Pisztoly;
};
Igen, jl ltod Okos Ottokr, ebbl is ltszik, hogy nomen est omen, tnyleg okos vagy
hzelgett a program ksztje, bajt szimatolva a levegben.
De persze a hrom mezbl (Hajo, Papagaj, Pisztoly) csak az egyiket hasznljuk,
a msik kett res marad, ugye? krdezte Ottokr, s vigyora egyre szlesebbre hzdott.
Hogyne, nagyon jl ltod Okos Ottokr, csak az egyiket hasznljuk, mgpedig az ru tpu-
stl fggen, amit az Arutipus mezben el is trolunk blogatott buzgn Sanyi, a prog-
ram ksztje, amely blogats egyre inkbb reszketsre emlkeztetett.
s ha majd hsz fajta rut is fog kezelni a programunk, akkor mind a hsz runak ott lesz
a helye, de csak mindig egyet hasznlunk, ugyebr? krdezte vszjsl hangon Ottokr, s
vigyora mr flig rt.
Igen, mindig csak az egyiket hasznljuk, a tbbit nem, ahogy mondod, Okos Ottokr re-
begte Sanyi, s kzben apr lpsekkel a kajt ajtaja fel igyekezett.
s ha majd szzfle rut kezelnk a programmal, akkor szz runak lesz lefoglalva a helye,
de csak egyet hasznlunk, kilencvenkilencet pedig elpazarolunk, nemde? ordtotta Ottokr s
vigyora mr grimassz torzult.
Igen, de gyis van elg memria suttogta alig hallhatan Sunyi Sanyi, htt a bezrt ajt-
nak vetve.
Jssz itt nekem a Jackson-briddal, felrajzolod nekem a szelekcit az adatszerkezetbe,
majd utna ki akarod szrni a szemem egy szekvencival, te nyavalys szrazfldi patkny?
Az n memrimat akarod te pazarolni, mi? tajtkzott Ottokr.
A beszlgets itt flbeszakadt, majd fl ra mlva folytattk, miutn a legnysg nagy rm-
re Sunyi Sanyit thztk a haj alatt.
Nos, tudsz-e valami okosabb megolds? krdezte negdesen Ottokr.
Union prszklte Sanyi.
Juni micsoda? Beszlj rtelmesen s ne vizezd ssze a perzsa sznyegemet mordult fel
Ottokr.
Union krkogta a program ksztje. Ezzel fogon megoldani az rucikk trolst s nem
pazarlom majd a memridat. s jobban fogja tkrzni a Jackson-brn felrajzolt tervet is.
Ez a beszd! veregette meg Sanyi vllt Ottokr. De mirt vagy ilyen vizes? Menj, t-
rlkzz meg, mg megfzol itt nekem.
A problma struktrval trtn megoldsa valban nem elegns. A szelekcik adatszer-
kezetek szintjn trtn szebb megvalstst tmogatja a C nyelvben a union.
Az union a C nyelvben a szelekci megvalstsra szolgl adatszerkezet. A unionban, ha-
sonlan a struktrhoz, mezket definilhatunk, amelyekre ugyangy hivatkozhatunk, mint
a struktrk esetben:
union u_tipus { struct s_tipus {
int egesz; int egesz;
float tort; float tort;
char karakter; char karakter;
}; };
union u_tipus U_pelda; struct s_tipus S_pelda;
A fenti pldban az u_tipus tpus U_pelda nev unionban trolt adat vagy int, vagy float,
vagy char tpus lehet, amelyekhez rendre az egesz, tort s karakter meznevek tartoz-
nak. Az egsz rtkads pl. a kvetkez lehet: U_pelda.egesz=168. Ha trtszmot sze-
retnnk trolni benne, akkor az U_pelda.tort=3.1415, mg a karakter trolsra
a U_pelda.karakter=W parancsot hasznlhatjuk.
A union, a struktrtl eltren nem foglalja le az sszes meznek megfelel helyet, az egyes
mezk ugyanazon a memriaterleten foglalnak helyet. A fenti pldban az S_pelda strukt-
ra mrete akkora, mint a struktra mezinek mretnek sszege, teht pl. egy C fordt
4+4+1=9 bjtot foglal le az S-pelda vltoznak (hiszen ltalban az int, a float s a char tpu-
sok rendre 4, 4, s 1 bjtot foglalnak el). Ezzel ellenttben az U_pelda vltoz mrete csak
akkora lesz, mint a legnagyobb mezjnek mrete, teht esetnkben 4 bjt: ebbl az int s float
mezk lefoglaljk mind a 4 bjtot, mg ha karaktert trolunk a unionban, az csak 1 bjtot fog
hasznlni (a msik hrom lefoglalt bjt ilyenkor krba vsz). A struktrk s unionok mem-
riafoglalst a 7.3. bra szemllteti egy hrom mezt tartalmaz adatszerkezetben.
A uniont vagy az emltett helytakarkossgi okokbl, vagy trkks megoldsok (pl. adatkon-
verzik) cljra szoks hasznlni. Pl. a union u{int szam; char bajtok[4];}; dekla-
rci lehetv teszi, hogy az egszknt bert szmot bjtonknt olvassuk vissza.
7.3. plda: Segtsnk Sunyi Sanyinak a korbbi adsvteli programot gy trni, hogy az ruk
adatait most union segtsgvel trolja.
A union segtsgvel programunk adatszerkezete a kvetkezkppen definilhat:
union aruadatok{ /*az ru adatainak trolsa*/
struct hajo Hajo; /* a haj adatai */
struct papagaj Papagaj; /* a papagj adatai */
};
struct aru{
enum arutipus Arutipus; /* az ru tpusa */
union aruadatok Aruadatok; /* az ru adatai */
};
Feladatok:
7.1. Melyek az igaz logikai kifejezsek a kvetkezk kzl?
1
28
-2
3.14
0
1+1
3-4
1==3
-3+2+1
3>4
2>=2
!(1 || !(1 && 0))
!(0 || !0 && 1)
!(1 && !(1 || 0))
7.2. Mit r ki a kvetkez program a vltozk kvetkez belltsainl?
a=3; b=4; c=-1; d=3;
a=3; b=3; c=0; d=0;
a=0; b=4; c=0; d=1;
a=1; b=0; c=1; d=0;
if ((a==b) || c && d)
printf("%d\n", a+b-c);
else if (b || a && d)
printf("%d\n", b+c-d);
else
printf("%d\n", a+c-d);
7.3. Mit r ki a kvetkez program a vltozk kvetkez belltsainl? (Vigyzat!)
a=3; b=2;
a=3; b=3;
a=1; b=5;
printf("start - ");
if(a==b)
printf("%d", a);
else if (b > 4)
printf("%d", b-a);
else
printf("%d", a+b);
printf("%d", a+b);
printf(" stop\n");
7.4. Mdostsuk az adsvtel adminisztrl programot gy, hogy tudjon kezelni pisztolyokat
is. A pisztolynak van tpusa, kalibere s kalz fegyver engedly szma (KFE szm).
7.5. Mdostsuk az adsvtel adminisztrl programot gy, hogy tudjon kezelni fegyvereket.
A fegyver lehet ks, pisztoly vagy borzkivonat. A ksnek hossza van, a pisztolynak t-
pusa s kalibere, a borzkivonatnak intenzitsa s mennyisge (milliliterben). Valameny-
nyi fegyvernek van ezen kvl kalz fegyver engedly (KFE) szma.
7.5. Ksztsnk szmkitall jtkot. A jtkos gondol egy szmot 1 s 10 kztt,a program
pedig igyekszik minl kevesebb krdsbl ezt kitallni.
7.6. Mdostsuk az adsvtel adminisztrl programot gy, hogy tudjon kezelni fegyvereket.
A fegyver lehet ks, pisztoly vagy borzkivonat. A ksnek hossza van, a pisztolynak t-
pusa s kalibere, a borzkivonatnak intenzitsa s mennyisge (milliliterben). Valameny-
nyi fegyvernek van ezen kvl kalz fegyver engedly (KFE) szma.
7.7. Ksztsnk programot, amely kirja, hogy a megadott v szkv-e.
7.8. Egsztsk ki a hromszg programot gy, hogy el tudja dnteni egy hromszgrl azt
is, hogy egyenl szr vagy egyenl oldal-e, valamint azt is hogy derkszg hrom-
szg-e.
7.9. Ksztsk el a msodfok egyenlet megold programjt. A program klnbztesse meg,
ha nincs, ha csak egy, illetve ha kt vals gyk van.
7.10. Ksztsnk programot, amely bekr egy dtumot (pl. a scanf("%d.%d.%d.", &Evszam,
& Honap, &Nap) paranccsal), majd ellenrzi, hogy a dtum leglis dtum-e.
A program gyeljnk arra, hogy mely hnapokban hny nap lehet.
Egsztsk ki a programot a szkvek helyes kezelsvel is.
8.1. plda: Ksztsnk egy programot Kalz Karcsinak, ami beolvassa a ktelek adatait, elt-
rolja azokat, majd ebbl kiszmtja a statisztikai jellemzket. Egyelre a ktelek sszes hosz-
szsgt szmtsuk ki. A beolvass sorn az utols ktl adatai utn adjunk meg 0 hosszs-
got, ezzel jelezzk a programnak, hogy az adatbevitel vget rt [8.kotel1.c].
A hajn sok ktl van, ezekrl mind el kell trolni a hosszt. Ezek ugyanolyan tpus ada-
tok s sok van bellk. Jackson-brs brzolssal a 8.1. brn lthat mdon brzolhatjuk
a ktelek adatait trol adatszerkezetet.
A programunk hrom nagy rszbl ll: beolvass, amelynek sorn minden ktl adatt
egyenknt beolvassuk s eltroljuk, szmols, ahol a statisztikai jellemzket (egyelre a kte-
lek sszes hosszt) kiszmtjuk, majd az eredmnyek kirsa kvetkezik. Mind a beolvass,
mind a szmts iteratv tevkenysg lesz: a beolvass sorn sokszor vgezzk ugyanazt
a tevkenysget: beolvassuk egy ktl adatait. A szmts sorn vgigmegynk az eltrolt ada-
tokon s sszeadjuk a ktelek eltrolt hosszt. Ezt a programszerkezetet illusztrlja a 8.2. bra.
float kotel[ELEMSZAM];
float summa; /* ebbe kerl a vgeredmny*/
float hossz; /* az aktulis ktl hossza*/
int ix; /* a tmb indexelsre hasznljuk */
int main(){
/* beolvass*/
/* szmts*/
/* kirs*/
return 0;
}
Az ELEMSZAM makr definilja a ktelek maximlis szmt (200), ennek segtsgvel ad-
juk meg a kotel nev float tpus tmb mrett is. Az adatok beolvasshoz s feldolgo-
zshoz szksgnk lesz a C nyelv ciklusszervez utastsaira is.
A C nyelvben a kvetkez ciklusszervez utastsok tallhatk:
Elltesztel, bennmaradsi felttellel. Ennek szintaxisa a kvetkez.
while (felttel) utasts
Termszetesen az utasts lehet kapcsos zrjelek kztt megadott blokk utasts is.
A ciklus vgrehajtsa sorn elszr a felttel rtkeldik ki: ha igaz, akkor vgrehajtjuk
a ciklusmagot (s kezdjk ellrl a felttel kirtkelsnl), klnben kilpnk a ciklus-
bl. A kvetkez plda a while ciklus hasznlatt mutatja be:
c=a;
while (c < g) {
printf("%c ", c);
c++;
}
printf("vege: %c ", c);
A pldabeli programban a ciklus eltt a c (karakter tpus) vltoznak kezdeti rtket
adunk: az a karaktert. A ciklus bennmaradsi felttele, hogy az c vltoz rtke kisebb le-
gyen a g betnl. Mivel a karaktereket az ASCII kdjukkal reprezentljuk (lsd az
F1 fggelket), kt bet kisebb-nagyobb relcija ez alapjn dnthet el. Mivel az ASCII
tblban a kdokat betrendben rendeltk a karakterekhez, gy egy karakter akkor kisebb
a g betnl, ha eltte van a betrendben (ez a kis betkre igaz, de pl. az sszes nagy bet
kdja mr kisebb, mit a kis betk, lsd az ASCII tblt).
A kdban lthat c++ utasts a c=c+1 utasts rvid formja. A ++ opertorhoz hasonl-
an ltezik mg a opertor is: a c-- kifejezs a c=c-1 rvidtse. 1
A ciklus magjban teht egyesvel lptetjk a karaktereket (a, b, c, d, stb.), amg a c vltoz
rtke g nem lesz; ekkor kilpnk a ciklusbl. A futsi eredmny teht a kvetkez lesz:
a b c d e f vege: g
Htultesztel, bennmaradsi felttellel. Ennek szintaxisa a kvetkez.
do utasts while (felttel);
Az utasts itt is lehet blokk utasts is. Ennl a ciklusnl elszr vgrehajtdik a ciklus-
mag, majd kirtkeldik a felttel. Amennyiben a felttel igaz, jra kezddik a ciklus
a ciklusmag vgrehajtsval, ellenkez esetben kilpnk a ciklusbl. Hasznlatra egy plda:
do {
scanf("%d", &s);
printf("%d negyzete: %d\n", s, s*s);
} while (s >= 0);
1
Az ilyen gynevezett mellkhatsos opertorok kezelse krltekintst ignyel. A c=1; b=c++; szek-
venciban pldul a c++ (poszt-inkremens) utasts f hatsa, hogy a kifejezs rtke a b vltozba tltdik
(b=1), majd mellkhatsknt c rtke inkrementldik (c=2). Ezzel ellenttben a ++c pre-inkremens opertor
hasznlatnl elszr a mellkhats kvetkezik be (c inkrementldik), majd a kifejezs kirtkeldik (f hats),
gy a c=1; b=++c; szekvencia utn b=2 s c=2. Sokszor csupn mellkhatsukrt hasznljuk ezen opertoro-
kat, ilyenkor termszetesen hatsuk azonos. Gyakran hasznljuk mg a poszt-dekremens (c--) s pre-
dekremens (--c) opertorokat is. Lsd mg az F3. fggelket.
A fenti programrszlet a ciklus magjban beolvas egy egsz szmot majd kirja a ngyze-
tt. Teszi ezt mindaddig, amg a beolvasott szm nem negatv. Itt a ciklus magja mindig
vgrehajtdik legalbb egyszer, hiszen a felttel ellenrzse csak a ciklus vgn trtnik
meg.
Szmllvezrelt.
for(inicializls; felttel; lptets) utasts
Ez a ciklusforma egy specilis elltesztel ciklus, amelynek felttele a ciklus fejben
megadott felttel kifejezs. Ennl a ciklusnl a ciklus vgrehajtsa eltt mg vgrehaj-
tdik az inicializls kifejezs, illetve a ciklusmag (az utasts) minden vgrehaj-
tsa utn vgrehajtdik a lptets is. A ciklusmag itt (utasts) is lehet blokk utas-
ts. Tipikus hasznlatra plda:
for (i = 0; i < 10; i++) {
printf("%d ", i);
}
printf("vege: %d ", i);
Itt elszr az i vltoz kezdeti rtke lltdik be nullra (inicializls), majd a ciklusmag
hajtdik vgre, ha az i vltoz rtke kisebb, mint 10 (felttel). A ciklusmag vgrehajtsa
utn vgrehajtdik a lptets, ami jelen esetben az i++ kifejezs: ez az i rtkt eggyel
megnveli. Majd ismt a felttel ellenrzse, ciklusmag vgrehajtsa s a lptets, stb.
kvetkezik mindaddig, amg a felttel igaz. Amint a felttel hamiss vlik, kilpnk a cik-
lusbl. Jelen pldnkban az i rtke nullrl indul s egyesvel n a ciklusmag minden
vgrehajtsa utn. A tizedik vgrehajts utn i rtke 10 lesz, vagyis a felttel hamiss v-
lik. Ekkor kilpnk a ciklusbl. Programunk teht a kvetkez kimenetet produklja:
0 1 2 3 4 5 6 7 8 9 vege: 10
Mivel legalbb egy adatot be kell olvasnunk (ami az els ktl hossza, vagy ha egyetlen
ktl sincs, akkor a zr nulla), ezrt a beolvasshoz hasznljunk elszr htultesztel ciklust:
A ciklusmagban beolvassuk az aktulis ktl hosszt a hossz vltozba, majd ezt eltrol-
juk a kotel tmb ix index elembe. Ezutn az indexet nveljk. A ciklus akkor folytatdik
(bennmaradsi felttel!), ha a legutbb beolvasott hossz nagyobb, mint 0 s mg nem lptk
tl a maximlis elemszmot.
Figyelem:
A beolvas rutin eltrolja a tmbbe az utoljra beolvasott zr nulla rtket is. Ezt fel-
hasznlhatjuk a szmts sorn arra, hogy a tmbben megtalljuk az utols rvnyes
adatot.
Amennyiben a ktelek szma elri a maximlis (ELEMSZAM) rtket, az utols eltrolt
adat nem a zr nulla rtk lesz. Erre gyelnnk kell majd a szmts vgzsekor.
A szmts sorn vgiglpkednk a tmb elemein, amg a zr elemig, vagy a tmb vg-
ig el nem jutunk. A ciklusmagban az egyes eltrolt ktlhosszakkal nveljk a summa vltoz
rtkt, ami a ciklus vgn a teljes ktlhosszt tartalmazza. Itt clszeren egy elltesztel cik-
lust hasznlhatunk:
/* szmts*/
ix=0; /* az aktulis tmbindex */
summa=0; /* rszeredmnyek trolja */
while (kotel[ix]!=0 && ix<ELEMSZAM){
summa += kotel[ix]; /* aktulis ktlhossz hozzadsa*/
ix++; /* index nvelse */
}
A ciklus felttelben a kotel[ix]!=0 kifejezs csak a zr 0 rtkig engedi futni a cik-
lust, mg az ix<ELEMSZAM azt az esetet kezeli, amikor a teljes tmb tele van rvnyes adattal
s nincs zr nulla. A ciklus addig fut, amg mindkt felttel igaz: nem rtnk el zr nullt s
nem rtnk a tmb vgre sem.
A programban hasznlt summa+=kotel[ix] kifejezs a summa=summa+kotel[ix] rvi-
debb rsmdja. A C nyelvben mg szmos ilyen tmr rtkad opertor ltezik:
+= -= *= /= %= >>= <<= &= ^= |=
Az opertorok jelentse az F3. fggelkben tallhat.
/* kirs*/
printf("a kotelek teljes hossza: %f\n", summa);
Kalz Karcsi mdostotta a kvetelmnyt: elszr megszmoljk, hogy hny darab ktl van
a hajn s ezt az adatot bekri a program. Utna a program egyenknt bekri minden ktl
hosszt (nem szksges az adatbevitel vgt jelezni).
A beolvass sorn elszr a ktelek szmt kell beolvasni, majd egyenknt a ktelek ada-
tait, ahogy a 8.3. bra mutatja.
Mivel a beolvasand ktelek szma ismert, itt clszeren szmllvezrelt ciklust alkal-
mazhatunk:
/* beolvass*/
/* - ktelek szmnak beolvassa*/
printf("Hany kotel van? ");
scanf("%d", &N);
Kalz Karcsi a ktelek hosszn kvl szeretn tudni azt is, hogy mennyi a leghosszabb ktl
hossza.
8.3. plda: rjuk t a ktlnyilvntart programot gy, hogy a bekrt adatokbl a leghosszabb
ktl hosszt is meghatrozza [8.kotelmax.c].
A legnagyobb elem keresshez a bekrt tmbt fogjuk hasznlni. A keress sorn vgig-
megynk a tmb elemein egy ix tmbindex segtsgvel s az eddig tallt legnagyobb elem
indext a maxix vltozban troljuk. A legnagyobb elem indexe kezdetben a tmb els ele-
mnek indexe lesz, ami C-ben 0, a tmb bejrst pedig a msodik (1 index) elemtl kezdjk
el. A ciklusban sszehasonltjuk, hogy az aktulisan vizsglt elem nagyobb-e, mint az eddigi
legnagyobb rtk: ha igen, akkor mdostjuk a legnagyobb elem indext. (A tmb bejrst
kezdhetnnk a 0. index elemnl is, de gy a ciklust egyszer feleslegesen hajtannk vgre,
hiszen az tmb els elemt nmagval hasonltannk ssze. A program termszetesen helye-
sen mkdne gy is.) A C nyelv kd szmllvezrelt ciklussal a kvetkez lehet:
int maxix; /* a legnagyobb elem indext troljuk itt*/
/* maximum szmts*/
maxix=0; /* az eddigi legnagyobb elem indexe */
for (ix=1; ix<N; ix++){
if (kotel[ix] > kotel[maxix]) /* ha az uj elem nagyobb... */
maxix=ix; /* ... akkor troljuk el annak indext*/
}
Figyeljk meg, hogy ennl a megoldsnl valjban nem a legnagyobb ktlhosszt keres-
tk meg, hanem a leghosszabb ktl indext (maxix), a leghosszabb ktl hosszt nem trol-
tuk el. Ezrt a kirsnl is a tmb megfelel indexelsvel (kotel[maxix]) rtk el a kere-
sett hosszt.
Amennyiben az eredeti megoldst vlasztjuk, ahol is a trolt elemek szma nem ismert, de
egy vgjel mutatja a tmbben az rvnyes adatok vgt, akkor is egy hasonl elv megoldst
alkalmazhatunk, de a ciklus (pl. elltesztel) klnbz lesz. A tmb bejrsa azonos mdon
trtnik, mint azt az sszegz programnl lttuk, de itt most csak az 1. indextl indulunk.
Elltesztel ciklussal pl. gy oldhat meg a feladat:
/* maximum szmts*/
ix=1; maxix=0;
while (kotel[ix]!=0 && ix<ELEMSZAM){
if (kotel[ix] > kotel[maxix])
maxix=ix;
ix++;
}
Mivel programunkban legalbb egy karaktert be kell olvasni, prbljunk meg egy
htultesztel ciklust hasznlni:
/*
* karaktermsol a standard bemenetrl a standard kimenetre
*/
#include <stdio.h>
main(){
int ch; /* a karakter tmeneti trolja */
do {
ch=getchar(); /* beolvass a standard bemenetrl */
putchar(ch); /* kirs a standard kimenetre */
} while (ch != EOF); /* a fjl vgig */
}
Az fjlok vgt valjban nem zrja le EOF karakter, fizikailag nem trolunk ilyen karaktert
a fjlok vgn. A fjlok vgt az opercis rendszer szleli s ezt jelzend adja vissza a speci-
lis EOF karaktert programunknak.
Amikor fjl helyett billentyzetrl olvasunk, akkor viszont neknk kell jeleznnk a bemenet
vgt, az utasts szmra a fjl vgt. Ezt Linux alap rendszereken a CTR-D karakter
megnyomsval tehetjk meg, mg Windows alatt a CTR-Z karakter s az ENTER megnyo-
msa generlja az EOF karaktert.
A fenti megolds mkdik ugyan, de nem szp: programunk az EOF karaktert is megpr-
blja kirni a tbbi karakterhez hasonlan, ami rtelmetlen. Szebb megolds, ha ezt nem tesz-
szk: egy elgazs segtsgvel akadlyozzuk meg az EOF kirst. Ekkor a ciklus a kvetke-
zkppen nz ki:
do {
ch=getchar();
if (ch != EOF) putchar(ch);
} while (ch != EOF);
A C nyelvben az rtkad is kifejezsnek is van rtke: a kifejezs rtke maga a jobb oldal
rtkvel egyezik meg. Teht az x = 1 kifejezs rtke 1. Pldnkban a ch = getchar()
kifejezs rtke a getchar() ltal visszaadott rtk (a beolvasott karakter) lesz.
Programunk ciklusnak felttel rszben teht beolvassuk a karaktert, ezt rtkl adjuk a ch
vltoznak, majd megvizsgljuk, hogy a beolvasott rtk nem EOF-e.
Vigyzat: az opertorok precedencija miatt az egyenltlensg vizsglat hamarabb kirtke-
ldne, mint az rtkads, ezrt a kvetkez kd rossz eredmnyt ad:
while (ch = getchar() != EOF) /* ROSSZ */
8.6. plda: Az 5.7. bra egy karakterszmol program felptst mutatja, amely egy beme-
netknt megadott szvegben megszmolja a kisbetket, nagybetket s egyb karaktereket.
Implementljuk a programot C nyelven [8.karakterszamol.c].
#include <stdio.h>
int ch;
int K; /* kisbetk szmllja */
int N; /* nagybetk szmllja */
int E; /* egyb karakterek szmllja */
main()
{
K=N=E=0; /* inicializls */
ch=getchar(); /* els karakter beolvassa */
while (ch != EOF)
{
if('A'<=ch && ch <='Z'){
N++; /* nagybetk szmolsa */
} else if ('a'<=ch && ch <='z'){
K++; /* kisbetk szmolsa */
} else {
E++; /* egyb karakterek szmolsa */
}
ch=getchar(); /* kvetkez karakter beolvassa */
}
/* eredmnyek kirsa */
printf("A kis betuk szama: %d\n", K);
printf("A nagy betuk szama: %d\n", N);
printf("Az egyeb karakterek szama: %d\n", E);
}
Mivel a ciklusban legalbb egy tippet fel kell dolgozni, j vlaszts a htultesztel ciklus.
A ciklus magjban egy elgazs segtsgvel rtkeljk ki a tippet. A program C nyelv imp-
lementcija a kvetkez lehet:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
int main(){
int szam; /* a gondolt szm */
int tipp; /* a tippelt szm */
srand(time(NULL)); /* a vletlenszm-genertor inicializlsa */
szam=rand()%MAX+1; /* vletlenszm 1 s MAX kztt */
printf("Gondoltam egy szamot 1 es %d kozott, talald ki!\n",
MAX);
do {
printf("Tipped? ");
scanf("%d", &tipp); /* tipp bekrse */
/* tipp kirtkelse */
if(tipp<szam){
printf("A szam nagyobb. ");
}
else if(tipp>szam){
printf("A szam kisebb. ");
}
else{
printf("Kitalaltad, gratulalok!\n");
}
} while(tipp!=szam); /* ismtls, mg ki nem talljuk... */
return 0;
}
Vletlen szmok generlsra a rand fggvny hasznlatos, amely 0 s egy nagy rtk (lta-
lban 32765) kztti egsz szmot ad vissza. Programunkban a szam=rand()%MAX+1 utas-
ts maradkos oszts segtsgvel egy 0 s MAX+1 kztti tartomnyra transzformlja a v-
letlen szmot. Mivel a rand fggvny valjban egy lvletlen genertorral mkdik, gy
a generlt vletlen szm a program minden futtatsakor ugyanaz lenne. Ezrt a genertor kez-
deti rtkt ltalban az aktulis id fggvnyben lltjuk be az srand fggvnnyel, a prog-
ramban pl. a srand(time(NULL)) parancsot hasznltuk erre a clra. A time fggvny az
1970 janur 1, 0:00 ra ta eltelt msodpercek szmt adja vissza.
Feladatok:
8.1. rjuk t a karakterszmll programot (5.7. bra) htultesztel ciklus hasznlatval.
8.2. rjuk t a karakterszmll programot, hogy a szmokat is kln szmolja meg, ezen
kvl az egyb karakterek kztt csak a lthat karaktereket szmolja. A lthat karakte-
rek a felkiltjel (0x21) s a hullmvonal (0x7E) kztt vannak (lsd az ASCII tblt az
F1. fggelkben).
8.3. rjunk programot, ami kirja a ngyzetszmokat 1-tl 1000-ig.
8.4. rjunk programot, ami bekr egy szmot, majd kirja a ngyzetszmokat 1-tl a bekrt
szm ngyzetig.
8.5. rjunk programot, ami tblzatot kszt a Celsius-Fahrenheit rtkprokrl. A tblzat-
ban ell lljon a Celsius rtk (-40 foktl +40 fokig terjed intervallumban, egyesvel),
majd mgtte az ekvivalens Fahrenheitrtk lljon. Fahrenheit fokba a kvetkez kp-
lettel lehet tvltani a Celsiusban megadott rtket: X F = 5 / 9( X C 32) .
8.6. rjuk t a Gondoltam egy szmot programot gy, hogy elltesztel ciklust hasznljon.
8.7. rjuk t a Gondoltam egy szmot programot gy, hogy szmolja meg a tippelsek sz-
mt s ennek fggvnyben gratulljon.
8.8. rjuk t a Gondoltam egy szmot programot gy, hogy szmolja meg a logikus s nem
logikus tippek szmt s ezek fggvnyben gratulljon. Logikus a tipp, ha az eddigi
ismert minimum s maximum kztt van, ellenkez esetben nem logikus.
8.9. Ksztsnk egy hisztogramrajzol programot. A program generl 100 darab vletlen
szmot az 1-10 intervallumban, majd ezen vletlen szmok elfordulsi gyakorisgt
megjelenti egy fekv hisztogram formjban. A fggleges tengelyen az elfordul r-
tkek, mg a vzszintes tengelyen ezek gyakorisga szerepel. A gyakorisgot annyi csil-
lag karakter mutatja, ahnyszor az adott rtk elfordult. gyeljnk arra, hogy a gyako-
risg tengely a legnagyobb gyakorisgig legyen beszmozva. A program futsi eredm-
nye pl. gy nzhet ki:
1 * * * * * * * * * *
2 * * * * * * * * * * *
3 * * * * * * * * * * * * *
4 * * * * * * * *
5 * * * * * * * *
6 * * * * * * *
7 * * * * * * *
8 * * * * * * * * * *
9 * * * * * * * * * * * *
10 * * * * * * * * * * * * * *
1 2 3 4 5 6 7 8 9 10 11 12 13 14
8.10. Ksztsnk egy szebb hisztogramrajzol programot. A program generl 100 darab vlet-
len szmot az 1-10 intervallumban, majd ezen vletlen szmok elfordulsi gyakorisgt
megjelenti egy ll hisztogram formjban. A vzszintes tengelyen az elfordul rt-
kek, mg a fggleges tengelyen ezek gyakorisga szerepel. A gyakorisgot annyi csil-
lag karakter mutatja, ahnyszor az adott rtk elfordult. A program futsi eredmnye
pl. gy nzhet ki:
14 *
13 * *
12 * * *
11 * * * *
10 * * * * * *
9 * * * * * *
8 * * * * * * * *
7 * * * * * * * * * *
6 * * * * * * * * * *
5 * * * * * * * * * *
4 * * * * * * * * * *
3 * * * * * * * * * *
2 * * * * * * * * * *
1 * * * * * * * * * *
1 2 3 4 5 6 7 8 9 10
8.11. rjuk t leghosszabb ktelet keres programot gy, hogy a legrvidebb ktl hosszt is
megadja.
8.12. rjunk egy programot, ami egy bemenetknt megadott pozitv egsz szmrl eldnti,
hogy prmszm-e vagy nem.
Tipp1: Ellenrizzk, hogy a szm oszthat-e valamelyik nla kisebb, egynl nagyobb
szmmal. Ha semelyik ilyen szmmal nem oszthat, akkor biztosan prmszm.
Tipp2: Elegend csupn a szm gyknl kisebb szmokat ellenrizni, gy sokkal gyor-
sabb lesz a programunk. Indokoljuk: mirt elegend a szktett tartomnyon trtn el-
lenrzs?
8.13. Az elz prmszm-ellenrz program felhasznlsval rjunk olyan programot, ami egy
adott szmtartomnyban (pl. 10000-tl 50000-ig) kirja a prmszmokat.
8.14. Ksztsnk programot, ami egy sakktblt kirajzol az bra szerinti mdon, a stt mez-
ket XX, a vilgosakat kt szkz karakterrel jellve, a mezk kzti hatrokat jellve.
A program rja fel a tbla szlre a sorok indexeit szmokkal, az oszlopokt betkkel,
a sakkban szoksos mdon (az A1 mez stt legyen). A tbla mrett a program olvas-
sa be.
mdja. Nem kell teht tudni azt, hogy az sszeads a fggvnyben mi mdon lett implemen-
tlva, szmunkra csak az a fontos, hogy hny darab s milyen tpus szmot tud a fggvny
sszeadni s az eredmny milyen tpus lesz. Pl. az sszead fggvny hrom darab egsz
szmot tud sszeadni s az eredmny is egsz lesz.
Az eljrsok olyan specilis fggvnyek, amelyeknek nincs visszatrsi rtkk. Pl. egy
eljrs lehet egy eredmny formzott kirsa.
Gyakran elfordul az is, hogy egy fggvny vagy eljrs nem ignyel bemen paramtert.
Pl. ilyen lehet az a fggvny, ami visszaadja az aktulis hmrskletet. Bemen paramter
nlkli eljrs lehet pldul az aktulis idt kir eljrs.
A C nyelvben a fggvny deklarcija azt mondja meg, hogy a fggvnyt hogyan kell hasz-
nlni: tartalmazza a fggvny tpust, nevt, valamit formlis paramterlistjt. Pl. a hrom
egsz szmot sszead fggvny deklarcija gy nz ki:
int add(int a, int b, int c);
A pldban a fggvny neve add, a fggvny visszatrsi rtknek tpusa (rviden: a fgg-
vny tpusa) int, amit a vltozk tpusdefincijnl megszokott mdon a fggvny neve
eltt definilunk. A fggvny formlis paramterlistja hrom bemen paramtert tartalmaz,
az a, b s c paramtereket, esetnkben valamennyi int tpus. A deklarci akkor hasznla-
tos, ha egy fggvnyt mshol mr definiltunk, vagy definilni fogjuk (egyszer esetekben
nem lesz r szksgnk).
Ahhoz, hogy a fggvny valban vgre tudja hajtani feladatt, definilni kell, hogy milyen
mveleteket hajt vgre (ez a fggvny trzse). Ezt a fggvny defincijban adjuk meg.
Az sszead fggvnyt gy definilhatjuk:
int add(int a, int b, int c){
return a+b+c;
}
A fggvny defincija a deklarcihoz hasonlan tartalmazza a fggvny fejrszt (tpus,
nv, bemen paramterek), valamint a fggvny ezt kvet trzsben azt is, hogy milyen te-
vkenysgeket hajt vgre a fggvny. Pldnkban a fggvny kt sszeads mveletet hajt
vgre, visszatrsi rtke a hrom bemen paramter sszege lesz. A legtbb esetben a ma-
gunk ltal ksztett fggvnyeket csupn definiljuk, ilyenkor a deklarcira ltalban nincs
szksg.
A fggvnyt hasznlatakor nevre hivatkozva kell meghvni, a szksges bemen paramte-
reket zrjelek kztt kell felsorolni, a visszatrsi rtket pedig tpusnak megfelelen kell
felhasznlni (pl. rtkadshoz, kirshoz). A fenti sszead fggvnyt pl. gy lehet hasznlni:
int s1, s2, s3, sum;
s1=1; s2=2; s3=3;
sum=add(s1,s2,s3);
printf("4+8+7=%d\n", add(4,8,7));
Az tadott aktulis paramterlistn szerepl paramterek (s1, s2, s3) tpusa pldnkban
megegyezik a fggvny paramterlistjn lthat tpusokkal. A visszaadott egsz tpus rt-
ket a pldban egy egsz tpus vltozba tltttk, illetve egsz szmknt rtuk ki. Ameny-
nyiben a paramterek tadsakor az aktulis paramter tpusa klnbzik a formlis paramter
tpustl, akkor a fordt megprbl egy sszer konverzit vgrehajtani. Pl. ha egy lebe-
gpontos szmot adunk t egsz helyett, akkor csonkolja azt (pl. 3.1415-bl 3 lesz). Ez a me-
chanizmus az rtkads mveletekre is hasonlan mkdik.
Ms programozsi nyelvekben azon fggvnyeket, amelyek nem adnak vissza visszatrsi
rtket, eljrsnak nevezik. A C nyelvben is vannak ilyen tulajdonsg fggvnyek, ezeknek
tpust a void kulcssz jelli: a void fggvnyek ekvivalensek az eljrsokkal.
9.1. plda: rjuk t a hromszg terlett s kerlett szmt programot fggvnyek haszn-
latval [9.haromszog_fv.c].
A 6.1. brn lthat terlet s kerletszmt programot egyszer szekvencilis tevkeny-
sgszerkezettel mr megoldottuk. Az a program azonban nem tkrzte az brn jl lthat
logikai sszefggseket az egyes tevkenysgek kztt. Nem klnltek el a beolvass,
a szmts s a kirs mveletek egymstl. A programkdban hacsak megjegyzseket nem
helyeznk el benne nem jelennek ezek a fogalmak, ott csak az elemi mveleteket talljuk
meg egyms utn. Valjban az egyszer szekvencilis programunk a 6.1. brn lthat fa-
struktra vgpontjait, leveleit tartalmazza, a kzbls pontokon megjelen fogalmakat nem
(nincs a programban pl. Adatok beolvassa, csak az egyes lek hosszainak beolvassnak
szekvencijt talljuk meg a kdban egyb utastsok kztt, hasonlan nincs Szmts, csak
a beolvas utastsokat kveti nhny elemi aritmetikai mvelet, stb.). A 9.1. bra mutatja
a 6.1. bra kiss trajzolt vezrlsi szerkezeteit, kln jellve a faszerkezet leveleit, amelyek
az egyszer programban elemi utastsknt jelentek meg. A program utastsainak sorrendje
a Jackson-bra leveleinek sorrendjvel egyezik meg, balrl jobbra olvasva.
9.1. bra. A terlet- s kerletszmol program szerkezete, ahol az elemi mveleteket (a fa leveleit) vastag kere-
tek jellik. Az egyszer szekvencilis program ezen utastsokat tartalmazza (balrl jobbra olvasva).
Alaktsuk t ezt a programot most gy, hogy abban megjelenjenek a magasabb szint fo-
galmak, melyek logikailag sszefgg tevkenysgeket fognak ssze. A programot ler
Jackson-brt kiss trajzolt vltozatt mutatja a 9.2. bra, ahol most minden fontos sszetett
tevkenysg kifejtst kln felrajzoltuk. Az egyes sszetett tevkenysgek lesznek majd az
eljrsok vagy fggvnyek, ezek kifejtse pedig az eljrs/fggvny defincija. Pl. a Kirs
eljrs defincija tartalmazza, hogy ez az eljrs kt tovbbi (sszetett) mvelet szekvenci-
jt tartalmazza: a Kerlet kirsa s a Terlet kirsa mveleteket, amelyek maguk is eljrsok
lesznek.
9.2. bra. A terlet- s kerletszmol program szerkezete, ahol az eljrsok defincija most elklnlten ltha-
t. Az eljrsok defincii a sznes sarkokkal jell tglalapoknl kezddnek.
Mieltt egy C programban egy fggvnyt hasznlni lehetne egy msik fggvny defincij-
ban, a felhasznlt fggvnyt definilni vagy legalbb deklarlni kell. Ezrt az egyszerbb C
programokban htul ll a main fggvny, s a fggvnyek defincijt olyan sorrendben k-
sztjk el, hogy a hivatkozott fggvnyek eltte mr definilva legyenek. Teht ha A fgg-
vnyben hasznljuk B fggvnyt, akkor B fggvnyt elbb definiljuk, mint A-t. Ha a fgg-
sgek nem tartalmaznak krt (pl. A hasznlja B-t s B hasznlja A-t), akkor ez az t mindig
jrhat. Abban az esetben, ha nem tudunk megfelel sorrendet tallni, akkor a C fordt azt is
megengedi, hogy a fggvnyt elszr deklarljuk, ezzel hivatkozhatv vlik, majd ksbb
definiljuk. Pl. deklarljuk A-t, definiljuk B-t (itt mr hivatkozhatunk A-ra), majd definiljuk
A-t (itt pedig mr hivatkozhatunk B-re). Egyszer pldinkban erre nem lesz szksg.
A C nyelv standard fggvnyeinek deklarcii az include sorokban megadott llomnyokban
vannak (pl. a printf fggvny deklarcijt az stdio.h fjl tartalmazza). Ezrt az #include di-
rektvkat a program elejre rva biztostjuk, hogy az sszes standard fggvny a progra-
munkban hivatkozhat lesz.
Megjegyzs: A fordt (compiler) szmra csak a felhasznlt fggvnyek deklarcija fontos,
hiszen ennek segtsgvel ellenrizni tudja, hogy helyesen hasznljuk-e a fggvnyt, illetve
a hvsi s visszatrsi paramterek tadst (esetleges tpuskonverzikkal egytt) meg tudja
valstani. Termszetesen a futtathat kd elksztshez szksg lesz valamennyi fggvny
defincijra is: ezt az informcit a szerkeszt (linker) hasznlja. Ezrt kaphatunk mind
a fordttl, mind a szerkeszttl hibazeneteket a program fordtsi folyamata kzben.
Lssuk teht programunkat most fggvnyek hasznlatval megvalstva gy, hogy nem
hasznlunk globlis vltozkat [9.haromszog_fv.c]:
#include <stdio.h>
#include <math.h>
/*
Adatok beolvassa
bemenet: standard input
kimenet: visszatrsi rtk hromszg adatai
*/
struct haromszog AdatokBeolvasasa(){
struct haromszog H;
printf("Az A oldal hossza:");
scanf("%lf", &H.A);
printf("A B oldal hossza:");
scanf("%lf", &H.B);
printf("A C oldal hossza:");
scanf("%lf", &H.C);
return(H);
}
/*
Kerlet s terlet szmtsa
bemenet: paramter - hromszg adatai
kimenet: visszatrsi rtk eredmny (kerlet s terlet)
*/
struct eredmeny Szamitas(struct haromszog H){
double S;
struct eredmeny E;
E.K=(H.A+H.B+H.C); /* kerlet */
S=E.K/2; /* fl kerlet */
E.T=sqrt(S*(S-H.A)*(S-H.B)*(S-H.C)); /* terlet */
return E;
}
/*
Kerlet kirsa
bemenet: paramter - hromszg kerlete
kimenet: standard kimenet
*/
void KeruletKiirasa(double K){
printf("\nA kerulet: %lf\n", K);
}
/*
Terlet kirsa
bemenet: paramter - hromszg terlete
kimenet: standard kimenet
*/
void TeruletKiirasa(double T){
printf("\nA terulet: %lf\n", T);
}
/*
Hromszg kerletnek s terletnek kirsa
bemenet: paramter - eredmny adatok
kimenet: standard kimenet
*/
void Kiiras(struct eredmeny E){
KeruletKiirasa(E.K);
TeruletKiirasa(E.T);
}
/*
Hromszg adatainak bekrse, kerlet s terlet szmtsa s
kirsa
bemenet: standard bemenet
kimenet: standard kimenet
*/
int main(){
struct haromszog Haromszog;
struct eredmeny Eredmeny;
Haromszog=AdatokBeolvasasa();
Eredmeny=Szamitas(Haromszog);
Kiiras(Eredmeny);
return 0;
}
Pldnkban nincsenek globlis vltozk, minden vltoz csak ott ltezik s lthat, ahol
arra szksg van. A main fggvnyben deklarljuk a Haromszog s az Eredmeny vltoz-
kat. Az AdatokBeolvasasa fggvny belsejben ltrehozunk egy H nev haromszog tpus
struktrt, amelybe a beolvas fggvny meghvsa utn a korbbi mdon betlti a hrom-
szg adatait. (Ez a H nev vltoz csak ebben a fggvnyben ltezik s csak itt lthat: amikor
a fggvnyt meghvjuk, ltrejn a vltoz, amikor a fggvny vget r, a vltoz megsznik.)
A fggvny vgn a H rtkt visszaadjuk, gy az a main fggvny Haromszog nev vltoz-
jnak addik rtkl. Ezutn a main fggvny a Szamitas fggvnyt hvja meg
a Haromszog paramterrel, majd a szmts eredmnye az Eredmeny vltozba tltdik be.
A Szamitas fggvny indtsakor a Haromszog vltoz rtke (bemen paramter) a fggvny
belsejben a H nev paramternek addik rtkl. (Ez a H paramter termszetesen nem
azonos az AdatokBeolvasasa fggvny hasonl nev paramtervel: mivel mindkett
loklis paramter, ezek egymsrl mit sem tudnak, csupn a nevk azonos. Hogy ppen
melyik vltozrl van sz, azt az dnti el, hogy melyik fggvnyben hivatkozunk erre
a nvre). A Szamitas fggvny a szmtst a H adatainak segtsgvel vgzi el, majd az
eredmnyt egy eredmeny tpus, E nev vltozba tlti. A fggvny ennek a vltoznak az
rtkt adja vissza a return utastssal. A main fggvnyben ekkor az Eredmeny nev vl-
toznak rtkl addik az E rtke (majd a Szamitas fggvny befejezse utn E megsz-
nik). Hasonlan a Kiiras fggvny tveszi az Eredmeny rtkt, amire a fggvnyen bell
E nvvel hivatkozik (ami termszetesen ms E nev vltoz, mint a Szamitas fggvnybeli).
A kirs meghvja a terletet s kerletet kir fggvnyeket, mindegyiket a megfelel lebe-
gpontos bemen adattal. Figyeljk meg, hogy minden fggvnyt a neki relevns bemen
adattal hvunk meg: pldul a KeruletKiirasa fggvnyt a Kiiras fggvny meghvhatta
volna a teljes E eredmny struktrval is, aminek K mezjt kirhatta volna
a KeruletKiirasa, de ez helytelen megolds lett volna: a KeruletKiirasa fggvny
szmra a kerlet (egy szm) a relevns adat s nem a terletet is tartalmaz teljes eredmny
(ami egy struktra).
Vizsgljuk meg programunkban a fggvnyek defincijnak sorrendjt. A Kiiras fgg-
vny tartalmazza a kerlet s a terlet kirst vgz fggvny hvst, mg a tbbi fggvny
csak a standard fggvnyknyvtrakat alkalmazza. Figyeljk meg, hogy a pldban a main
fggvny defincija ll a kd vgn (hiszen az hasznlja az AdatokBeolvasasa, Szamitas, s
Kiiras fggvnyeket), mg a Kiiras fggvny defincijt meg kell elzze a KeruletKiirasa s
a TeruletKiirasa fggvnyek defincija.
9.2. plda: Prbljuk meg a kdban felcserlni pl. a Kiiras s TeruletKiirasa fggvnyek
defincijnak sorrendjt. A fordt hibazenetet ad. Most helyezzk el a Kiiras defincija
el a TeruletKiirasa fggvny deklarcijt. Kdunk ezen rszlete teht gy fog kinzni:
/* itt deklarljuk a TeruletKiirasa fggvnyt: */
void TeruletKiirasa(double T);
9.3. bra. A hajk adsvteli szerzdst kezel program 6.3. brn lthat lersnak kiss mdostott vltoza-
ta. A sznes sark tglalapok az eljrsok defincijnak kezdett mutatjk.
Az brn sszesen kilenc eljrst ltunk, ezek az Adsvteli szerzds program, Beolva-
ss, Kirs, Kalz beolvassa, Haj beolvassa, Dtum beolvassa, Kalz kirsa, Haj kirsa
s Dtum kirsa. A C nyelv programban is ezek a fggvnyek jelennek meg, hasonl neve-
ken. Az Adsvteli szerzds program szerept a main fggvny veszi t. A C nyelv prog-
ram fggvnyekkel megvalstott vltozata teht gy nzhet ki [9.adasvetel_fv.c]:
/*
* Haj adsvteli szerzds adatainak bekrse s kirsa fggv-
nyekkel.
*/
#include <stdio.h>
#define _MAX_HOSSZ 20
struct datum{
unsigned int Evszam; /* a dtum vszm mezje */
unsigned int Honap; /* a dtum hnap mezje */
unsigned int Nap; /* a dtum nap mezje */
};
struct kaloz{
char Nev[_MAX_HOSSZ+1]; /* a kalz neve */
struct datum Szuletesi_ido; /* a kalz szletsi ideje */
unsigned int KAZ_szam; /* a kalz KAZ-szma */
};
struct hajo{
char Nev[_MAX_HOSSZ+1]; /* a haj neve */
char Tipus[_MAX_HOSSZ+1]; /* a haj tpusa */
unsigned int Hossz; /* a haj hossza */
unsigned int Arbocszam; /* a haj rbocainak szma */
};
struct szerzodes{
struct kaloz Elado; /* az elad adatai */
struct kaloz Vevo; /* a vev adatai */
struct hajo Hajo; /* a haj adatai */
unsigned int Vetelar; /* a haj vtelra */
struct datum Keltezes; /* a szerzds kelte */
};
/*
Dtum beolvassa
bemenet: standard input
kimenet: visszatrsi rtk dtum
*/
struct datum DatumBeolvas(char szoveg[]){
struct datum Datum;
printf("%s", szoveg);
scanf("%d.%d.%d.", &Datum.Evszam, &Datum.Honap, &Datum.Nap);
return Datum;
}
/*
Dtum kirsa
bemenet: paramter - dtum
kimenet: standard kimenet
*/
void DatumKiir(char szoveg[], struct datum Datum){
printf("%s%d.%d.%d.\n", szoveg, Datum.Evszam, Datum.Honap,
Datum.Nap);
}
/*
Kalz adatainak beolvassa
bemenet: standard input
kimenet: visszatrsi rtk kalz adatai
*/
struct kaloz KalozBeolvas(char szoveg[]){
struct kaloz Kaloz;
printf("%s\t\tNev: ", szoveg);
scanf("%s", Kaloz.Nev);
Kaloz.Szuletesi_ido=DatumBeolvas("\t\tSzuletesi ido [e.h.n.]: ");
printf("\t\tTitkos kaloz azonosito: ");
scanf("%d", &Kaloz.KAZ_szam);
return Kaloz;
}
/*
Kalz adatainak kirsa
bemenet: paramter - kalz adatai
kimenet: standard kimenet
*/
void KalozKiir(char szoveg[], struct kaloz Kaloz){
printf("%s\t\tNev: %s\n", szoveg, Kaloz.Nev);
DatumKiir("\t\tSzuletesi ido: ", Kaloz.Szuletesi_ido);
printf("\t\tTitkos kaloz azonosito: %d\n", Kaloz.KAZ_szam);
}
/*
Haj adatainak beolvassa
bemenet: standard input
kimenet: visszatrsi rtk haj adatai
*/
struct hajo HajoBeolvas(){
struct hajo Hajo;
printf("\n\tHajo adatai:\n");
printf("\t\tNev: ");
scanf("%s", Hajo.Nev);
printf("\t\tTipus: ");
scanf("%s", Hajo.Tipus);
printf("\t\tHajo hossza: ");
scanf("%d", &Hajo.Hossz);
printf("\t\tHajo arbocszama: ");
scanf("%d", &Hajo.Arbocszam);
return Hajo;
}
/*
Haj adatainak kirsa
bemenet: paramter - haj adatai
kimenet: standard kimenet
*/
void HajoKiir(struct hajo Hajo){
printf("\n\tHajo adatai:\n");
printf("\t\tNev: %s\n", Hajo.Nev);
printf("\t\tTipus: %s\n", Hajo.Tipus);
printf("\t\tHajo hossza: %d\n", Hajo.Hossz);
printf("\t\tHajo arbocszama: %d\n", Hajo.Arbocszam);
}
/*
Vtelr beolvassa
bemenet: standard input
kimenet: visszatrsi rtk vtelr
*/
unsigned int ArBeolvas(){
unsigned int Ar;
printf("\n\tHajo vetelara: ");
scanf("%u", &Ar);
return Ar;
}
/*
Vtelr kirsa
bemenet: paramter - vtelr
kimenet: standard kimenet
*/
void ArKiir(unsigned int Ar){
printf("\n\tHajo vetelara: %d\n", Ar);
}
/*
Szerzds sszes adatnak beolvassa
bemenet: standard input
kimenet: visszatrsi rtk szerzds adatai
*/
struct szerzodes Beolvas(){
struct szerzodes Szerzodes;
printf("Kaloz adasveteli szerzodes bevitele\n");
Szerzodes.Elado=KalozBeolvas("\n\tElado adatai:\n");
Szerzodes.Vevo=KalozBeolvas("\n\tVevo adatai:\n");
Szerzodes.Hajo=HajoBeolvas();
Szerzodes.Vetelar=ArBeolvas();
Szerzodes.Keltezes=
DatumBeolvas("\n\tSzerzodeskotes idopontja [e.h.n.]: ");
return Szerzodes;
}
/*
Szerzds sszes adatnak kirsa
bemenet: paramter - szerzds adatai
kimenet: standard kimenet
*/
void Kiir(struct szerzodes Szerzodes){
printf("\n\nKaloz adasveteli szerzodes adatainak listazasa\n");
KalozKiir("\n\tElado adatai:\n", Szerzodes.Elado);
KalozKiir("\n\tVevo adatai:\n", Szerzodes.Vevo);
HajoKiir(Szerzodes.Hajo);
ArKiir(Szerzodes.Vetelar);
DatumKiir("\n\tSzerzodeskotes idopontja: ",
Szerzodes.Keltezes);
}
/*
Szerzds adatainak beolvassa s kirsa
bemenet: paramter - szerzds adatai
kimenet: standard kimenet
*/
int main(){
struct szerzodes Szerzodes;
Szerzodes=Beolvas();
Kiir(Szerzodes);
return 0;
}
A main fggvny mos csak egy loklis vltozt, a Szerzodes nev struktrt
tartalmazza, valamint a Beolvas s a Kiir fggvnyek hvst. A beolvasott szerzds
adatait a Beolvas fggvny a Szerzodes valtozba tlti, majd ezen vltozval, mint
bemen paramterrel hvjuk meg a Kiir fggvnyt.
A fggvnyek egyms kztti fggsgeit a 9.4. brn lthat fggsgi grfon
brzolhatjuk: a felhasznlt fggvnyekbl nyl mutat a hasznl fggvny fel. Pl. a Dtum
beolvassa fggvnyt hasznlja mind a Kalz Beolvassa, mind a Beolvass fggvny. Ebbl
a fggvnyek defincijnak sorrendje meghatrozhat: olyan sorrendet kell hasznlni,
amelyben a felhasznlt fggvnyt mindig a hasznlat eltt elszr kell definilni. Pldul a C
forrskdban a Beolvas s Kiir fggvnyeknek a main fggvny eltt kell llnia, a Beol-
vas fggvnyt meg kell elzzk a KalozBeolvas, HajoBeolvas, ArBeolvas s DatumBeolvas
fggvnyek, stb. A fenti program szerkezete figyelembe veszi ezen ezen fggsgeket.
Termszetesen ezzel a problmval nem kell foglalkoznunk, ha a fggvnyeket hasznlatuk
eltt (tipikusan a kd elejn) deklarljuk: ekkor a fggvnyek defincii tetszleges
sorrendben llhatnak.
9.4. bra. A hajk adsvteli szerzdst kezel program fggvnyeinek fggsgi grfja. A nyilak a hasznlt
fggvnybl mutatnak a hasznl fggvny fel
A C nyelvben a vltozkat rtk szerint adjuk t. A Kiir fggvnyben pl. gy hvjuk meg az
ArKiir fggvnyt:
ArKiir(Szerzodes.Vetelar);
Az Arkiir fggvny deklarcija pedig gy nz ki:
void ArKiir(unsigned int Ar)
Az ArKiir fggvny meghvsakor a Szerzodes.Vetelar (egsz tpus) vltoz rtke
tmsoldik az ArKiir fggvny bemen paramterbe, aminek neve Ar. Az ArKiir fgg-
vnyen bell nem ltszik a Szerzodes.Vetelar vltoz, csak annak Ar nev msolata. (Ha
pl. az ArKiir fggvnyben trnnk az Ar rtkt, annak termszetesen semmi hatsa nem
lenne a hv fggvnyben tallhat Szerzodes.Vetelar vltoz rtkre.) Ezt a mdszert
hvjuk rtk szerinti paramtertadsnak.
Ez all a mechanizmus all egy kivtel van a C nyelvben: a tmbket nem rtk szerint adjuk
t, hanem csupn a tmbk cmei kerlnek (rtk szerinti) tadsra. Ezt a megoldst ms
nyelvekben cm szerinti tadsnak nevezik. Ebben az esetben nem msoldik t a vltoz
tartalma a meghvott fggvny loklis paramterbe, hanem csupn a vltoz cmt adjuk t.
Ezzel klnsen a nagy mret paramterek tadsa sorn idt s memrit lehet sprolni.
Fontos jellemzje a cm szerinti tadsnak, hogy minden vltoztats, amit a hvott fggvny-
ben a cm szerint tadott vltozn vgrehajtunk, termszetesen a hv fggvnyben is megje-
lenik hiszen ugyanarrl a vltozrl van sz, nem jtt ltre msolat. Teht a
Szerzodes.Vevo=KalozBeolvas("\n\tVevo adatai:\n");
fggvnyhvs sorn a karakterlnc a hv Beolvas nev fggvnyben troldik s csak
ezen karakterlnc cme addik t, nem pedig a teljes karakterlnc.
A fentebb lertak nem csak a paramterek tadsra, hanem ltalban az rtkadsra is jellem-
zk. Az a = b utasts ltalban azt jelenti, hogy az a vltozba tmsoldik a b rtke. Ez
a tmbk kivtelvel valban j kpia ltrejttt jelenti, a tmbk esetn azonban maga
a tmb nem msoldik t, csupn annak cme.
A tmbk eme furcsa viselkedsre mr lttunk pldt a scanf fggvny hasznlatakor is:
ha pl. egy egsz tpus vltozt olvasunk be, akkor a vltoz neve el kell a & cmopertor,
mg a tmbk neve el nem kell (ill. nem szabad) kitenni a cmopertort. A C nyelvben teht
a tmb neve nem a tmb rtkt jelenti, hanem a tmb kezdcmt, ellenttben az egyszer
vltozkkal s a struktrkkal, ahol a vltoz neve a vltoz rtkt jelli. A klnleges b-
nsmdot a nyelv tervezi azrt alkalmaztk, hogy a potencilis nagy mret tmbk t-
adsa, rtkadsa is gyors mvelet legyen. Ez a legtbb esetben valban j megolds, ha pe-
dig tmbket mgis msolni szeretnnk, akkor erre kln fggvnyeket kell alkalmazni.
Mivel tmbt nem lehet rtk szerint tadni, gy a fggvnyek sem tudnak tmbt visszaadni.
Ennek megoldsa a C nyelvben ktflekppen trtnhet:
1. A visszaadni kvnt tmbt egyszeren egy struktrba gyazzuk.
2. A visszaadni kvnt tmbt a fggvny hvsa eltt, a hv fggvnyben ltrehozzuk, ezt
a tmbt bemen paramterknt tadjuk (amely tads a tmb cmt jelenti), majd a fgg-
vny belsejben kitltjk a tmbt. Ekkor a fggvnynek nem kell valdi visszatrsi
rtket adnia, hiszen az egyik bemen paramteren megjelen mellkhats a visszatrsi
rtk.
9.4. plda: rjunk programot, amelyben egy fggvny tvesz egy karaktertmbt, majd min-
den elemt megnveli eggyel. A visszaadott tmb legyen struktrba gyazva [9.tombfv1.c].
struct tombstruct{
char tomb[10]; /*egyetlen tmbt tartalmaz struktra*/
};
/*
Tmbn operl pldafggvny (tmb minden elemt megnveli)
bemeneti paramterek:
X: bemen string cme
N: a string hossza
kimenet: visszatrsi rtk stringet tartalmaz struktra
*/
struct tombstruct f1(char X[], int N){
int i;
struct tombstruct Y; /* ebben troljuk a szmtott rtket*/
for (i=0; i<N;i++){
Y.tomb[i]=X[i]+1; /* tmbn vgzett mvelet */
}
Y.tomb[N-1]=0; /* stringet lezr 0 hozzadsa*/
return Y; /* visszatrsi rtk */
}
int main(){
char T[10]="ABCDEFGHI"; /* ez lesz a bemen paramter*/
struct tombstruct A; /* ebben troljuk a kimenetet*/
9.5. plda: rjuk t a fenti programot gy, hogy a visszaadott tmb cme egy bemen param-
ter legyen [9.tombfv2.c].
Az f2 void fggvnynek bemen paramterl megadjuk az X tmbt (illetve annak c-
mt), amely a bemen karaktersorozatot tartalmazza, az Y tmbt, amelyben az eredmnyt
adjuk vissza, valamint a tmbben tallhat karakterek N szmt. Figyeljk meg, hogy a hv
main fggvnyben ltrehozzuk mind a bemen T, mind a kimen W tmbt. Ezeket (illetve,
mint tudjuk: cmket) adjuk t az f2 fggvnynek. Az eredmny a W tmbben kpzdik:
#include <stdio.h>
/*
Tmbn operl pldafggvny (tmb minden elemt megnveli)
bemeneti paramterek:
X: bemen string cme
X: eredmny string cme
N: a string hossza
kimenet: -
*/
void f2(char X[], char Y[], int N){
int i;
for (i=0; i<N;i++){
Y[i]=X[i]+1;
}
Y[N-1]=0; /*stringet lezr 0*/
}
int main(){
char T[10]="ABCDEFGHI"; /* bemen karaktersorozat */
char W[10]; /* ez lesz a kimenet*/
nyelvek megengedik, hogy fggvnyek/eljrsok egyes csoportjaiban legyen lthat egy vl-
toz, a C nyelvben azonban ennl egyszerbb modellt alkalmazunk: egy vltoz vagy globlis
(az adott program minden fggvnyben lthat), vagy egyetlen fggvnyben lthat csupn
(loklis az adott fggvnyben, mgpedig abban a fggvnyben, ahol deklarltuk). A loklis
vltozk eltakarhatnak globlis vltozkat, ha azokat ugyanolyan nven jradeklarljuk.
A fggvnyek bemen paramterei is loklis vltozknt foghatk fel. A C nyelv ezen kvl
lehetv teszi, hogy a fggvnyeken belli blokkokban is definilhassunk csak az adott
blokkban lthat vltozkat.
9.6. plda: Az albbi programban az i, j s a vltozneveket hasznljuk mind globlis, mind
loklis vltozknt, st paramtertadskor is. Vizsgljuk meg a program mkdst
[9.valtozok1.c].
1. #include <stdio.h>
2. int i=1, j=5;
3.
4. int f1(int j){
5. printf("f1: i=%d, j=%d\n", i, j); /* itt i=1 s j= 3*/
6. j=7;
7. printf("f2: i=%d, j=%d\n", i, j); /* itt i=1 s j= 7*/
8. return(j);
9. }
10.
11. int main(){
12. int i=2, j=3;
13. printf("m1: i=%d, j=%d\n", i, j); /* itt i=2 s j=3*/
14. { /* a blokk kezdete */
15. int i=4;
16. printf("m2: i=%d, j=%d\n", i, j); /* itt i=4 s j=3*/
17. i=f1(j);
18. printf("m3: i=%d, j=%d\n", i, j); /* itt i=7 s j=3*/
19. } /* a blokk vge */
20. printf("m4: i=%d, j=%d\n", i, j); /* itt i=2 s j=3*/
21. return 0;
22. }
dik), amint a fggvny befejezi mkdst. A blokkokban definilt vltozk trhelye meg-
sznik, amint a blokk befejezdik, teht a 15. sorban definilt i vltoz a 19. sornl megsz-
nik (br a gyakorlatban a fordtk a vltoz tnyleges megszntetst gyakran csak a fgg-
vny befejezsekor vgzik el de erre termszetesen nem szabad alapozni).
Megjegyzs: A programozsi nyelvek ltalban lehetsget adnak r, hogy elkerljk a lok-
lis vltozk megszntetst. Krhetjk a fordtt arra, hogy loklis lthatsg vltozink
rtkt is rizze meg, gy a fggvny kvetkez hvsakor a korbban hasznlt vltoz rtke
jra elrhet. Erre a C nyelvben a statikus vltozk hasznlhatk (pl. static int i).
int main(){
/* vltozk mretnek s cmnek kiratsa */
printf("x : meret=%2d, &x =0x%p \n", sizeof(x), &x);
printf("c1: meret=%2d, &c1=0x%p \n", sizeof(c1), &c1);
printf("c2: meret=%2d, &c2=0x%p \n", sizeof(c2), &c2);
printf("Q : meret=%2d, &Q =0x%p \n", sizeof(Q), &Q);
printf("K : meret=%2d, &K =0x%p \n", sizeof(K), K);
printf("S : meret=%2d, &S =0x%p \n", sizeof(S), &S);
printf("T : meret=%2d, &T =0x%p \n", sizeof(T), &T);
return 0;
}
Figyeljk meg, hogy a vltozk cmeit az & cmopertor segtsgvel kaptuk meg, kivve
a tmbt, ahol nem volt erre szksg, hiszen a tmb neve a C nyelvben a tmb cmt jelenti.
Egy PC-s krnyezetben Windows alatt gcc fordtval a program a kvetkez kimenetet adta:
x : meret= 4, &x =0x00402000
c1: meret= 1, &c1=0x00402004
c2: meret= 1, &c2=0x00402005
Q : meret= 8, &Q =0x00402008
K : meret=20, &K =0x00402010
S : meret= 8, &S =0x00404080
T : meret= 4, &T =0x00402024
Ebben a krnyezetben az int tpus 4, a char 1, a double 8, mg a float 4 bjtos mret volt.
A tmb mrete megegyezik az alaptpus (char) mretnek s a tmb hossznak szorzatval,
jelen esetben ez 20 bjt volt, mg a struktra mrett a fordt az alaptpusokbl add 1+4=5
bjt helyett 8 bjtra kerektette fel. A fordt program a fenti pldban a vltozkat a memria
0x00402000 cmtl kezdve helyezte el. Az els vltoz (x) mrete 4 bjt, ez utn kzvetlenl
kvetkezik a kt egybjtos karakter (c1 s c2). A c2 s Q kztt 2 bjt res helyet tallunk,
majd kezddik a 8 bjtos Q, kzvetlenl utna a 20 bjt mret K tmb, vgl ez utn a 4
bjtos T. Az S struktrt a memriban jval feljebb helyezte el a fordt.
9.9. plda: Vizsgljuk meg, hogyan troldnak a memriban az egy bjtnl nagyobb mret
vltozk. A programunk tartalmazza az x nev egsz tpus vltozt s a K nev, 20 elem
karaktertmbt [9.valtozok3.c].
Az albbi program kirja az x egsz tpus vltoz rtkt bjtonknt, valamint a karakter-
tmb elemeit karakterknt s hexadecimlis szmknt is. Figyeljk meg az union hasznlatt:
a 4 bjtos egsz szm mell definiltunk ugyanarra a memriaterletre egy 4 elem karakter-
tmbt. Mivel a karaktertmb elemei 1 bjtosak, ennek segtsgvel vgig tudunk haladni
a szm bjtjain s ki tudjuk azokat ratni. A tmb esetn szintn egy ciklussal vgigmegynk
a tmbn s kiratjuk a karaktereket, majd egy jabb ciklusban az ASCII karaktereket rjuk ki.
#include <stdio.h>
union teszt{
int x; /* Egy egsz szm */
unsigned char c[4]; /* u.a. a szm, de most bjtonknt kezelve*/
} U;
unsigned char K[20] ="Az ipafai papnak..."; /* tmb */
int main(){
U.x=0xC1CABAB1; /* plda egsz szm*/
int i;
printf("int x:\n");
for (i=0; i<sizeof(U.x); i++){
printf("%x ", U.c[i]); /* egsz szm kirsa bjtonknt */
}
printf("\n\nchar K[20]:\n");
for (i=0; i<sizeof(K); i++){
printf("%c ", K[i]); /* karaktertmb kir, karakterenknt */
}
printf("\n");
for (i=0; i<sizeof(K); i++){
printf("%2x ", K[i]); /* u.a. a tmb, most ASCII kddal */
}
return 0;
}
char K[20]:
A z i p a f a i p a p n a k . . .
41 7a 20 69 70 61 66 61 69 20 70 61 70 6e 61 6b 2e 2e 2e 0
Lthatjuk, hogy az egsz szmot (C1CABAB1) gy trolja a program, hogy a legkisebb
helyirtk bjt (B1) van a legalacsonyabb cmen. Ezt a trolsi mdot nevezzk Little
Endian trolsnak. Lteznek n. Big Endian rendszerek is, ahol a legnagyobb helyirtk bjt
van a legalacsonyabb cmen: egy ilyen rendszerben az x vltozt a fenti mdon kiratva a c1
ca ba b1 karaktersorozatot kaptuk volna.
A futsi eredmnybl jl ltszik, hogy a tmbk trolsakor a legalacsonyabb cmen
a tmb els (nulladik index) eleme foglal helyet, majd utna kvetkeznek sorban a tmb
tbbi elemei. Ez fggetlen attl, hogy a rendszer Litte Endian vagy Big Endian trolsi mdot
hasznl.
Feladatok:
9.1. Mdostsuk a kalzok fggvnyeket hasznl adsvteli programjt gy, hogy a kirs
sorn a dtumok formtuma a kvetkez pldnak megfelel legyen:
Az r 1848. vnek 3. havnak 15. napjn
9.2. Mdostsuk a fenti programot gy, hogy a hnapokat nevkkel rja ki. pl.:
Az r 1848. vnek mrcius havnak 15. napjn
9.3. Mdostsuk a kalzok fggvnyeket hasznl adsvteli programjt gy, hogy tetszle-
ges fizeteszkzt lehessen az adsvtelnl hasznlni (6.5. feladat mintjra). Mely
fggvnyeket kell mdostani? Mit kell ezen kvl a programban mdostani? rjuk meg
a C nyelv programot.
9.4. rjunk egy int CF(int x) s egy int FC(int x) fggvnyt, melyek tszmoljk a bemeneti
Celsius fokban megadott rtket Fahrenheit fokra (CF), illetve a Fahrenheit fokot Celsi-
us fokra(FC). rjunk programot, ami tblzatot kszt vagy a Celsius-Fahrenheit, s
a Fahrenheit-Celsius rtkprokrl. A tblzatban ell ll rtk a -40 foktl +40 fokig
terjed intervallumban, egyesvel vltozzon. A Celsiusrl Fahrenheitre tvlt kplet
a kvetkez X F = 5 / 9( X C 32)
9.5. rjunk egy int prim(int x) fggvnyt, amely a bemeneti vltozrl eldnti, hogy
prmszm-e: ha igen, akkor visszatrsi rtke 1, klnben pedig 0.
A prim fggvny segtsgvel rjunk programot, amely egy megadott (bekrt) szmtar-
tomnyban kirja az sszes prmszmot.
9.6. Ksztsk el a 8.10. feladatban szerepl hisztogram-rajzol programot gy, hogy a hisz-
togramot egy void hisztogram(int x[]) fggvny rajzolja ki.
9.7. Egsztsk ki az elz programot gy, hogy egyms utn 10 vletlenszm-sorozatot
generljon, majd mind a 10 hisztogramot kirajzolja. Figyelem: a vletlenszm-genertor
inicializlst csak egyszer kell elvgezni.
9.8. Egsztsk ki az elz programot gy, hogy a szmok generlst is egy struct
veletlenszamok generator(int N) fggvny vgezze: a bemeneti paramterknt
kapott szmnak megfelel szm vletlen szmbl ll sorozatot generljon, majd ezt
egy olyan struktrban adja vissza, amelyben a sorozat egy MAXSZAM mret (pl.
10000) tmbben szerepel, mellette pedig a sorozat mrete egy egsz szmban troldik.
9.9. Alaktsuk t a 9. fejezet 9.5. pldjban rt f2 fggvnyt gy, hogy egyetlen tmbt s
annak hosszt vegye t, majd ugyanebben a tmbben adja vissza az eredmnyeket.
9.10. Ksztsnk programot, amelyben tbb fggvnyben is loklis vltozkat hozunk ltre.
rassuk ki a loklis vltozk cmt s mrett. Nzzk meg, mit tapasztalunk, ha vannak
loklis s globlis vltozink is.
9.11. Ksztsnk programot, amelyben egy bjtnl hosszabb elemekbl, pl. egsz szmokbl
ll tmbt hozunk ltre. rassuk ki a tmb tartalmt bjtonknt.
9.12. Ksztsnk programot, amelyben egy struktrkbl ll tmbt hozunk ltre. A strukt-
rban egy karakter s egy egsz szm legyen. rassuk ki a tmb tartalmt bjtonknt.
Iskolk Iskola*
vodk voda*
Iskola Iskolaigazgat Tanrok_szma Tanrok Dikok_szma Dikok
voda vodaigazgat vnk_szma vnk Dadusok_szma Dadusok Gye-
rekek_szma Gyerekek
Tanrok Tanr*
vnk vn*
Dikok Dik*
Gyerekek Gyerek*
Igazgat Tanr
vodaigazgat vn
Tanr Szemly
vn Szemly
Dik Szemly
Gyerek Szemly
Szemly Nv Szletsi_hely
A fenti adatszerkezet brzolsakor a vros egy struktra lesz, amelynek mezi egy isko-
lkat tartalmaz s egy vodkat tartalmaz tmb. Az iskola maga is egy struktra, amelynek
mezi az igazgat (egy szemly tpus struktra), egy tanrokat tartalmaz tmb (melynek
elemei szemly tpus struktrk), egy dikokat tartalmaz tmb (melynek elemei szintn
szemly tpus struktrk), valamint kt egsz, amely a tanrok s dikok szmt tartalmazza.
Hasonlan az voda is egy struktra, melynek mezi az igazgat (egy szemly tpus strukt-
ra), egy vnket tartalmaz tmb (melynek elemei szemly tpus struktrk), egy daduso-
kat tartalmaz tmb (melynek elemei szemly tpus struktrk), egy gyerekeket tartalmaz
tmb (melynek elemei szemly tpus struktrk), valamint hrom egsz, amely az vnk,
dadusok s gyerekek szmt tartalmazza.
10.2. plda: Hozzuk ltre a fenti adatszerkezeteket C nyelven.
Definiljuk elszr a szemlyeket ler struktrkat. A nevek maximlis hossza legyen
MAXHOSSZ:
struct t_szemely{
char nev[MAXHOSSZ];
char szuletesi_hely[MAXHOSSZ];
};
struct t_ovoda{
struct t_szemely igazgato;
int ovonokszama;
struct t_szemely ovono[MAXSZEMELY];
int dadusokszama;
struct t_szemely dadus[MAXSZEMELY];
int gyerekekszama;
struct t_szemely gyerek[MAXSZEMELY];
};
struct t_varos{
int iskolakszama;
struct t_iskola iskola[MAXINTEZMENY];
int ovodakszama;
struct t_ovoda ovoda[MAXINTEZMENY];
};
#include <stdio.h>
#define ELEMSZAM 200
#define MAXNEV 20
/*
Egy ktl adatainak beolvassa
bemenet: standard input
kimenet: visszatrsi rtk ktl adatok
*/
struct t_kotel KotelBeker(){
struct t_kotel kotel;
printf("adja meg a kovetkezo kotel hosszat: ");
scanf("%lf", &kotel.hossz);
printf("adja meg a kotel felelosenek nevet: ");
/* Ez csak egytag nevekkel mkdik:*/
scanf("%s", kotel.felelos);
return kotel;
}
/*
Egy ktl adatainak kirsa
bemeneti paramter: - ktl adatok
kimenet: standard kimenet
*/
void KotelKiir(struct t_kotel kotel){
printf("a kotel hossza: %lf, ", kotel.hossz);
printf("a kotel felelose: %s \n", kotel.felelos);
}
/*
sszes ktl adatainak beolvassa, a KotelBeker fv-t hasznlja
bemenet: standard input
kimenet: visszatrsi rtk ktl adatok
*/
struct t_koteladatok Beolvas(){
struct t_kotel kotel; /* egy ktl adatai */
struct t_koteladatok kotelek; /* ktelek adatai */
int N; /* ktelek szma */
int i;
printf("Hany kotel van? "); /* ktelek szmnak bekrse */
scanf("%d", &N);
kotelek.N=N; /* ktelek szmnak trolsa */
for (i=0; i<N; i++){
kotel=KotelBeker(); /* egy ktl adatainak bekrse */
kotelek.kotel[i]=kotel; /* s trolsa */
}
return kotelek;
}
/*
ktelek kzl adott hossznl hosszabbak adatait kirja
KotelKiir fv-t hasznlja
bemeneti paramter: ktelek adatai
kimenet: standard kimenet
*/
void Keres(struct t_koteladatok kotelek){
int ix;
double x;
printf("Hany meternel hosszabb kotelet keresunk? ");
scanf("%lf", &x);
for (ix=0; ix<kotelek.N; ix++){
if (kotelek.kotel[ix].hossz > x)
KotelKiir(kotelek.kotel[ix]);
}
}
/*
ktelek adatait bekri s adott hossznl hosszabbak adatait kirja
bemeneti: standard input
kimenet: standard kimenet
*/
int main(){
struct t_koteladatok hajokotelek;
hajokotelek=Beolvas();
Keres(hajokotelek);
return 0;
}
A fenti program sajnos csak olyan neveket tud trolni, amelyben nem szerepel szkz:
a scanf fggvny a szkzt hatrol karakternek tekinti s a bevitelt megszaktja. Ha valdi
neveket akarunk trolni, akkor ilyen esetekben a teljes sort beolvas fgets fggvnyt lehet
hasznlni. Ez a fggvny visszaadja a bemenetn tadott karaktertmbbe a teljes beolvasott
sort, szkzkkel egytt. A beolvas fggvnyt a kvetkezkppen kell mdostani:
10.4. plda: rjunk a ktlkezel programhoz egy KotelekKiir nev fggvnyt, ami egy
t_koteladatok tpus struktrban trolt sszes ktl adatt ki tudja rni [10.kotel2.c].
A fggvny a kvetkez lehet:
/*
sszes ktl adatainak kirsa - KotelKiir fv-t hasznlja
bemeneti paramter: - ktelek adatai
kimenet: standard kimenet
*/
void KotelekKiir(struct t_koteladatok kotelek){
int ix;
for(ix=0; ix<kotelek.N; ix++){
KotelKiir(kotelek.kotel[ix]);
}
}
10.5. plda: rjunk a ktlkezel programhoz egy Valogat nev fggvnyt, ami egy
t_koteladatok tpus struktrban trol ktelek kzl ki tudja vlogatni azokat, amelyek
hossza egy megadott tartomnyban van. Ezen ktelek adatait egy t_koteladatok tpus
struktrban adja vissza [10.kotel2.c].
A megolds pldul a kvetkez lehet:
/*
ktelek kzl adott hossz-tartomnyba esket kivlogatja
bemeneti paramterek:
kotelek: sszes ktl adata
min: minimlis ktlhossz
max: maximlis ktlhossz
kimenet: vlogatott ktelek adatai
*/
struct t_koteladatok Valogat(struct t_koteladatok kotelek,
double min,
double max){
struct t_koteladatok valogatas;
int i; /* a bemen tmb indexe */
int j=0; /* a kimen tmb indexe */
for (i=0; i<kotelek.N; i++){
if(kotelek.kotel[i].hossz > min &&
kotelek.kotel[i].hossz<max){
valogatas.kotel[j]=kotelek.kotel[i];
j++;
}
}
valogatas.N=j;
return valogatas;
}
10.6. plda: rjunk fggvnyt, ami tmbben trolt egsz szmokat sorrendbe rendez. A fgg-
vny bemenete egy tmb, amelyben helyben elvgzi a rendezst s a kimenet a bemeneti
trendezett tmb lesz [10.rendez.c].
Szmos rendezsi algoritmus ismert, ezek kzl most az egyik legegyszerbbet,
a minimumkivlasztsos rendezst valstjuk meg. Az algoritmus a kvetkez:
Az els menetben vlasszuk ki a teljes tmb legkisebb elemt, majd helyezzk ezt a tmb
elejre (gy, hogy megcserljk a legkisebb elemet az els elemmel).
A msodik menetben vlasszuk ki a tmb legkisebb elemt a msodik elemtl kezdve,
majd helyezzk ezt a tmb msodik helyre (szintn cservel: megcserljk a legkisebb
elemet az msodik elemmel).
Ezt folytassuk annyiszor, ahny elem a tmb. Az i-edik krben a minimumkeresst az i-
edik elemtl (i-edik indextl) kell kezdeni s a legkisebb tallt elemet ide kell tenni.
A fggvnynek tadjuk a rendezni kvnt tmbt s a tmb mrett. A C nyelven megva-
lstott fggvny pl. a kvetkez lehet:
/*
szmokat hossz szerint rendez (helyben)
bemeneti paramterek:
T: szmok tmbje
N: tmb hossza
kimenet: a T tmbben keletkezik a rendezett szmhalmaz
*/
void szamrendez(int T[], int N){
int i, j; /* segdvltozk */
int minix; /* legkisebb elem indexe */
int csere; /* segdvltoz a cserhez */
for (i=0; i<N; i++){/* az i. rendezett elemet keressk, ellrl */
minix=i; /* a legkisebb, mg nem rendezett elem indexe */
/* min. keresse a mg nem rendezett elemekben:*/
for (j=i+1; j<N; j++){
if (T[j]<T[minix]) /* ha kisebb elemet talltunk */
minix=j; /* megjegyezzk az indext */
}
/* a kvetkez i. elem a legkisebb mg nem rendezett elem lesz */
/* elemek cserje: T[i] <--> T[minix]*/
csere=T[i];
T[i]=T[minix];
T[minix]=csere;
}
}
Kalz Karcsi szeretn a programjba bevitt ktelek adatait gy ltni, hogy azok nagysg sze-
rinti sorrendben legyenek rendezve.
10.7. plda: rjuk t a szmokat rendez fggvnyt gy, hogy az alkalmas legyen a ktelek
adatainak kezelsre [10.kotel2.c].
A ktl adatai kztt termszetesen a hossz jellemz lesz a rendezsi szempont, de a ktl
ennl tbb adatot is tartalmaz (jelen esetben a felels nevt is). Clszer teht a ktelet, mint
egysget kezelni. Ahogy a szmrendez szmok tmbjt, gy a ktlrendez ktelek tmbjt
fogja rendezni:
void KotelRendez(struct t_kotel T[], int N){
int i, j, minix;
struct t_kotel csere;
for (i=0; i<N; i++){
minix=i;
for (j=i+1; j<N; j++){ /* minimum keresse */
if (T[j].hossz<T[minix].hossz)
minix=j;
}
Kalz Karcsi szereti a sakkot s a szmtgpeket is. Szeretne egy egyszer sakkprogramot,
de mg egyik zskmnyban sem tallt ilyent. Venni meg nem akar...
10.8. plda: rjunk egy egyszer programot, ami kirajzol egy sakktblt, amire bbukat lehet
elhelyezni. A bbukat a sakkban szoksos mdon adjuk meg, teht pl. ha a kirly B2 mezn
ll, akkor Kb2. Az egyszersg kedvrt a vilgos bbukat nagy, a stt bbukat kis betkkel
jelljk [10.sakktabla.c].
A sakktbla egy mtrixnak foghat fel, amit programjainkban egy ktdimenzis tmbknt
kezelhetnk. A ktdimenzis tmb valjban egy olyan tmb, amelynek elemei tmbk. Ha-
sonlan az egydimenzis tmbhz, a tmb elemeit indexelssel rjk el, itt termszetesen kt
index (oszlop s sor) segtsgvel. A tmb elemeire pldul a kvetkez mdon hivatkozha-
tunk:
T[1][3]=3; A=T[2][1];
A tmb elemei termszetesen brmilyen tpusak lehetnek. Pldnkban az egyszersg
kedvrt minden bbu jellsre hasznljunk egy karaktert (pl. k-kirly, h-huszr). A tbla
minden mezjt feleltessk meg a ktdimenzis tmb egy elemnek: az A1 mez legyen a
(0,0) index elem, az A2 mez a (0,1), ..., a B1 mez az (1,0), a B2 mez az (1,1), ..., a C3
mez a (2,2), ... stb. index legyen.
Ha a tbla adott mezjn ll egy bbu, akkor a tmb megfelel pozcijn troljuk el a bbu
jellsre szolgl karaktert. Teht pl. a D2 mezre egy vilgos kirlyt a kvetkez mdon
helyezhetnk el: Tabla[3][1] = 'K'.
#include <stdio.h>
#define MAXMERET 25
/*
sakktbla mretnek beolvassaa
bemenet: standard bemenet
kimenet: visszatrsi rtk - tbla mrete
*/
int beker_N(){
int N;
printf("Tabla merete: ");
scanf("%d", &N);
return N;
}
/*
sakktbla kirajzolsa
bemeneti paramterek:
tabla: sakktbla
N: sakktbla mrete
kimenet:
standard kimenet
*/
void kirajzol(char tabla[MAXMERET][MAXMERET], int N){
int i, j;
char babu, szin;
printf(" ");
for (i=0;i<N; i++) printf(" %c", 'A'+i); /* oszlopindexek*/
printf("\n +");
for (i=0;i<N; i++) printf("--+", 'A'+i); /* fels vonal */
printf("\n");
for(i=N-1;i>=0; i--){
printf("%2d|", i+1); /* sorindex */
for(j=0;j<N; j++){
if ((i+j)%2) /* vilgos vagy stt mez? */
szin=' ';
else
szin='X';
if (babu=tabla[j][i]) /* ha van a mezn bbu */
printf("%c%c|", szin, babu);
else /* ha nincs a mezn bbu */
printf("%c |", szin);
};
printf("\n +"); /* sor vge */
for(j=0;j<N; j++) printf("--+", 'A'+j); /* als vonal */
printf("\n");
}
/*
Egy bbu pozcijnak beolvassa s eltrolsa
bemenet:
paramter: sakktbla
standard inputrl olvas
kimenet:
visszatrsi rtk: rvnyes/nem rvnyes pozci
bemenetknt kapott sakktbla adatait mdostja
*/
int beker_pozicio(char tabla[MAXMERET][MAXMERET]){
int oszlop_ix, sor_ix, ervenyes;
char babu, inp[20];
printf("Pozicio (pl. hA2): ");
scanf("%s", inp); /* bemenet beolvassa */
oszlop_ix=inp[1]-'A'; /* oszlopindex szmtsa */
sor_ix =inp[2]-'1'; /* sorindex szmtsa */
babu =inp[0]; /* bbu azonostja */
if (ervenyes =(babu>='A' && babu<='z')) /* rvnyes bemen adat? */
tabla[oszlop_ix][sor_ix]=babu; /* trols */
return ervenyes; /* rvnyes flag visszaadsa */
}
/*
sakktbla inicilizlsa
bemeneti paramter: sakktbla
kimenet: inicializlt sakktbla
*/
void init(char tabla[MAXMERET][MAXMERET]){
int i,j;
for (i=0; i<= MAXMERET; i++)
for (j=0; j<= MAXMERET; j++)
tabla[i][j]=0; /* minden mezre 0 */
}
/*
bekri s kirajzolja a sakktblt
bemenet: standard bemenet
kimenet: standard kimenet
*/
int main(){
char tabla[MAXMERET][MAXMERET];
int N;
N=beker_N(); /* tbla mretnek beolvass */
init(tabla); /* inicializls */
while(beker_pozicio(tabla)); /* babupozcik beolvassa */
kirajzol(tabla,N); /* tbla kirajzolsa */
return 0;
}
A kirajzol fggvny soronknt rajzolja ki a tblt: ha van bbu az adott mezn, akkor
annak kdjt is kirja, valamint a mez sznt is jelli egy csillag karakterrel.
Egy plda futsi eredmny a kvetkez:
Tabla merete: 5
Pozicio: kA3
Pozicio: KD1
Pozicio: hB5
Pozicio: *
A B C D E
+--+--+--+--+--+
5|* | h|* | |* |
+--+--+--+--+--+
4| |* | |* | |
+--+--+--+--+--+
3|*k| |* | |* |
+--+--+--+--+--+
2| |* | |* | |
+--+--+--+--+--+
1|* | |* | K|* |
+--+--+--+--+--+
Feladatok:
10.1. Prbljuk ki az fgets fggvnyt hasznl KotelBeker fggvnyt az getchar()
fggvnyhvs nlkl. Elszr a megadott ktlhossz utn soremelst ssnk. Ezutn
prbljuk becsapni a programot: az adatbevitelnl ne zrjuk le a sort a ktl mrete utn,
hanem szkz utn adjuk meg a felels nevt, majd ezutn ssnk soremelst, pl. gy:
adja meg a kovetkezo kotel hosszat: 57.6 Gyalog Fifi Bence
Mirt mkdik most a program (eltekintve a kiss zavaros bemeneti kpernytl)?
10.2. Tmbk rendezsnek egyik kedvelt mdszere a buborkos rendezs. Ez az algoritmus
a tmb vgrl indulva minden elemet sszehasonlt az elz elemmel. Ha a kt elem
sorrendje nem megfelel (teht a nagyobb elem ll ell), akkor megcserli az elemeket.
gy az els kr utn a tmb els eleme garantltan a legkisebb lesz. Ezt az eljrst foly-
tatjuk, de most mr a tmb vgtl csak a msodik elemig haladunk, stb. N-1 kr utn
a tmb rendezett lesz. Ksztsk el az algoritmus pszeudo-kdjt. (A megolds a kvet-
kez feladatban lthat)
10.3. A buborkos rendezs pszeudo-kdja a kvetkez:
Eljrs Buborek
Ciklus i=1-tl (N-1)-ig
Ciklus j=(N-1)-tl i-ig -1-esvel
Ha Tmb(j-1)>Tmb(j) akkor
Csere=Tmb(j-1)
Tmb(j-1)=Tmb(j)
Tmb(j):=Csere
Elgazs vge
Ciklus vge
Ciklus vge
Eljrs vge
Programozzuk be az algoritmust C nyelven s teszteljk a mkdst.
10.4. Egsztsk a sakktbla-rajzol programot gy, hogy a bbuk bevitele utn lehessen lpni
is. A Lpseket a kiindul s cl mez azonostsval adjuk meg. Pl. az A3A3 lps az
A1 mezn tallhat bbut az A2 mezre helyezi t. (A programnak nem kell ellenrizni
a lpsek helyessgt.) A program minden lps utn rajzolja ki a tblt. Ha * karaktert
adunk meg lpsnek, a program fejezze be mkdst.
10.5. Egy sakktblra pnzrmket helyeznk, minden mezre kerlhet 0, 1, vagy akr tbb
rme is. Az rmket gy helyezzk el, hogy megadjuk az rme rtkt s a mez pozci-
jt: pl. az 5B3 parancs egy 5 duktos rmt helyez el a B3 mezre. A bevitelt * karak-
ter zrja. Ezutn a program rajzolja ki a tblt, minden mezn jelezve, hogy mennyi
pnz van rajta (ahol nincs pnz, azt a mezt hagyja resen).
10.6. Egsztsk ki az elz feladatban rt programot gy, hogy minden sor utn kirja az
adott sorban lv rmk sszegt s minden oszlop al kirja az adott oszlopban lv
rmk sszegt.
A rekurzi s alkalmazsa
Ha ezt egy programozsi nyelven szeretnnk megfogalmazni, akkor pl. gy jrhatunk el:
Fggvny fakt=Faktorilis(n)
Ha n = 1 akkor
fakt=1
klnben
fakt=Faktorilis(n-1)*n
elgazs vge
Eljrs vge
Jl lthat, hogy a Faktorilis fggvny sajt magt hvja meg, de mr eggyel kisebb be-
men paramterrel. A meghvott fggvny ismt meghvja nmagt, ismt kisebb eggyel ki-
sebb paramterrel, stb. A vgtelen lncolat ott szakad meg, amikor a meghvott fggvny be-
men paramtere 1-re cskken: ekkor nem trtnik jabb fggvnyhvs, hanem az utolsnak
meghvott fggvny visszaadja az 1 rtket. A rekurzv lncot megszakt kilpsi felttelnek
minden rekurzv fggvnyben lteznie kell, klnben a fggvny meglls nlkl hvn jra
s jra nmagt. A fggvnyek hvsi lnca pl. a kvetkezkppen alakul, ha a 4 faktorilist
szmtjuk ki (az egyszersg kedvrt a Faktorilis fggvnynv helyett az F rvidtst hasz-
nltuk) :
kat. Ez azonban mr elg kis N rtkekre is hasznlhatatlanul lass lenne, pl. N=10 esetn
mr nagysgrendileg 1013 esetet kellene megvizsglni. Felesleges azonban minden esetet v-
gignzni, ennl gyesebb algoritmus is adhat. Tegyk fel a kirlynket egyesvel: ha a tbl-
ra mr feltett kirlynk kzl brmely kett is ti egymst, akkor felesleges tovbb prbl-
kozni: az eredmny mindenkppen rossz lesz. Ksztsnk teht egy olyan algoritmust, ami
gy prblkozik - szisztematikusan kirlynk leraksval, hogy a rossz llskezdemnyeket
azonnal szreveszi s az ez irny prblkozsokat abbahagyja. Az ilyen tpus algoritmuso-
kat backtracking, vagy visszalpses keres algoritmusoknak nevezzk. A backtracking algo-
ritmusokat gyakran rekurzv fggvnyekkel valstjuk meg.
Az N-kirlyn problmra is nagyon szp rekurzv visszalpses keres megoldst adha-
tunk: Helyezznk el az els sorban egy kirlynt az els oszlopba. Ezutn helyezznk el a
maradk N-1 sorban N-1 kirlynt. Ha nem sikerlt, akkor az els sorban a kirlynt tegyk
a kvetkez mezre. Ha gy sem tallunk megoldst, akkor tegyk arrbb ismt... A tbbi
sorban hasonlan jrjunk el.
Az algoritmus megfogalmazsa kicsit formlisabban:
Eljrs Felrak(lls, sor)
Ciklus oszlop=1-tl N-ig
lls (sor, oszlop) pozcira kirlynt tesz
J=Ellenriz(lls)
Ha J = IGAZ akkor
Ha sor = N akkor
// megoldst talltunk!
Kirajzol(lls)
Klnben
// eddig j, folytassuk a kvetkez sorral!
Felrak(lls, sor+1)
Elgazs vge
Elgazs vge
// ezt kiprbltuk, vegyk le
lls (sor, oszlop) pozcirl kirlynt levesz
Ciklus vge
Eljrs vge
#include <stdio.h>
#include <stdlib.h>
#define MAX 14
/*
tbla kirajzolsa
bemenet:
paramterek:
szamlalo: eddig tallt megoldsok szma
n: tbla mrete
allas: az aktulis lls.
kimenet:
standard kimenet
*/
void kirajzol(int szamlalo, int n, int allas[]){
/* A program futsnak gyorstsa rdekben csak az els
szz megoldst rajzolja ki.
*/
if (szamlalo>100) return;
int i, j;
printf("\n\n%4d. megoldas:\n ", szamlalo);
for (i=0; i<n; i++) printf(" %c", 'A'+i);
printf("\n +");
for (i=0; i<n; i++) printf("-+");
for (i=n; i>0; i--){
printf("\n%2d|", i);
for(j=0; j<n; j++) printf("%c|", allas[i-1]==j?'X':' ');
printf("%d\n +", i);
for(j=0; j<n; j++) printf("-+");
}
printf("\n ");
for(i=0; i<n; i++) printf(" %c", 'A'+i);
}
/*
lls ellenrzse: nem tik-e egymst a vezrek
felttelezi, hogy az utols sor kivtelvel mr ellenrizve volt
bemeneti paramterek:
allas: az aktulis lls.
sor: az j sor, ebben kell elenrizni az llst
visszatrsi rtk: leglis lls-e
*/
int ellenoriz(int allas[], int sor){
int i;
for(i=0; i<sor && allas[i]!=allas[sor] && /* ts oszlopban? */
abs(allas[i]-allas[sor])!=sor-i; i++); /* ts tlsan? */
return (i==sor); /* ha i elri sor-t, akkor nem volt ts */
}
/*
rekurzv felrak fggvny
bemenet:
paramterek:
meret: tbla mrete
allas: aktulis felrakott lls.
rtelmezse: adott sor hnyadik oszlopban van a vezr
sor: ettl a sortl folytatdik a felraks
kimenet:
az allas vltoz az j llst tartalmazza
visszatrsi rtk: eddig tallt megoldsok szma
*/
int felrak(int meret, int allas[], int sor){
int i, jo;
/* A static kulcssz miatt csak egy szaml lesz,
s csak egyszer inicializldik.
*/
static int szaml=0;
/* A sor minden oszloppozicijn vgigmegynk */
for(allas[sor]=0; allas[sor]<meret; allas[sor]++){
/* Addig megy, amg a korbbi sorok vezrvel nincs
tsben a vizsglt pozici.
*/
jo=ellenoriz(allas, sor);
/* Ha egyikkel sincs tsben */
if(jo){
/* Ha nem az n. sorban vagyunk:
felrak() fgvnyhvs kvetkez sorra (rekurzi).*/
if(sor<meret-1)felrak(meret, allas, sor+1);
/* Ha az n. sorba sikerlt berakni,
int main(){
int n, ret, sorallas[MAX];
do{
printf("A tabla merete [1-14]: ");
ret=scanf("%d", &n); /* tblamret bekrse */
while(getchar()!='\n'); /* puffer rtse scanf utn */
}while(!ret || n<1 || n>MAX); /* amg j adatot nem adunk... */
Feladatok:
11.1. rjuk t az N-kirlyn programot N-bstya programm: helyezznk el az NN-es tbln
N darab bstyt gy, hogy azok ne ssk egymst.
11.2. Mdostsuk az N-kirlyn programot gy, hogy els megolds utn lljon meg.
11.3. Mdostsuk az N-kirlyn programot gy, hogy az llst egy NN mret tmbben t-
roljuk.
11.4. rjunk rekurzv programot a Fibonacci-szmok generlsra. Az Fibonacci-szmok de-
fincija a kvetkez:
Fn = Fn 1 + Fn 2 , ha n > 1
F0 = 0
F1 = 1
11.5. rjunk rekurzv programot a Catalan-szmok generlsra. A Catalan-szmok definci-
ja a kvetkez:
n 1
Cn = Ci C ni1 , ha n > 0
i =0
C0 = 1
(Az els nhny Catalan-szm a kvetkez: 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862.)
Egyszer programjaink ksztse sorn nem okozott klnsebb gondot, hogy a programok
szerkezett, a szksges fggvnyeket, eljrsokat, adatszerkezeteket megtervezzk: ezek
ilyen egyszer esetekben termszetesen addtak, logikusnak tntek. A feladat struktrja
termszetes mdon megjelent a program szerkezetben is, mind az adatszerkezetek, mind
a vezrlsi szerkezetek szintjn.
Bonyolultabb esetekben azonban a tervezsi folyamatot clszer tudatos mdon, sziszte-
matikusan vgezni. A gyakorlatbak kt alapvet megkzeltst, gondolkodsi mdot tallunk:
az alulrl flfel tervezst s a fellrl lefel tervezst.
A tovbbiakban ttekintjk e kt alapvet mdszert. Azt azonban mr most meg kell je-
gyezni, hogy sem egyik, sem msik mdszerrl nem lehet lltani, hogy jobb a msiknl: je-
lents szemlletbeli klnbsg van a kt megkzelts kztt. gy egyes gyakorlati esetekben
hol egyik, hol a msik megkzelts bizonyulhat hatkonyabbnak. De egy vals mrnki fel-
adat megoldsa kzben valsznleg egy kombinlt mdszert fogunk alkalmazni: a tervezs
sorn vltogatni fogjuk a kt mdszert.
Az fellrl lefel tervezs elnyei: a fellrl lefel tervezs szp megoldsokat eredm-
nyez, hiszen az adott feladathoz jl illeszked struktrj megoldst kapunk. A komplex fel-
adattl egyre egyszerbb rszfeladatokon t jutunk el a megoldsig, minden szinten kezelhet
mret problmt oldunk meg. A kzbls lpsek sorn definilt rszfeladatok nll szoft-
ver-egysgek (pl. fggvnyek) lesznek, melyek elemi s ksbb definiland sszetett tev-
kenysgeket tartalmaznak. A tervezs sorn definilt egysgek kapcsolatai, interfszei jl
definiltak, ezrt ezek nllan is kezelhetk, prhuzamosan is fejleszthetk. A kdols teht
knny s ttekinthet, az eredmny jl strukturlt, logikus felpts lesz.
Az fellrl lefel tervezs htrnyai: A fejleszts sorn fellrl lefel haladva egysge-
ink defincii olyan alegysgekre hivatkoznak, melyek egyelre csak funkcionlisan ismertek,
ezek defincija csak ksbb kszl el. gy egy magas szinten megtervezett s ltrehozott egy-
sg nem tesztelhet hiszen elemei mg hinyoznak. Ezrt a fellrl lefel tervezssel k-
szlt szoftverek tesztelse csak a tervezsi s fejlesztsi folyamat legvgn kezddhet el.
(11) tlalok
(12) esznk
(13) leszedem a vacsort
(14) elmosogatok
A msodik lpsben a tevkenysgek fggsgeit vizsglom meg. Pldul a gyertya asz-
talra helyezse (2) clszeren meg kell elzze a gyertya meggyjtst (3), valamint a gyertya
eloltsa (4) csak az evs (12 ) utn kvetkezhet. Az ilyen tpus fggsgek brzolsnak
eszkze a fggsgi grf lehet, amelynek cscsai a tevkenysgek, egy A s B cscs kztt
pedig akkor vezet irnytott l (A-bl B-be mutat nyl), ha B tevkenysg fgg A tevkeny-
sg vgrehajtstl. Teht a fenti problma fggsgi grfjban pl. ltezni fognak a (2) (3)
s (12) (4) lek. A teljes fggsgi grf a 12.2. brn lthat.
Feladatok:
12.1. Az albbi elemi mveletekbl alulrl felfel tervezssel hatrozzuk meg a program
struktrjt oly mdon, hogy minden sszetett mvelet legfeljebb hrom msik mve-
letbl lljon!
Bekr A, Bekr B, Bekr C, Kir W, Kir R, Kir P, P=A*W+1, W=A+R+Q,R= ngy-
zetgyk(Q*Q+Q), Q = ngyzetgyk(A*A+B*B)
Rajzoljuk fel a program struktrjt Jackson-brval!
Valstsuk meg a programot C nyelven, fggvnyek segtsgvel, globlis vltozk
hasznlatval.
Valstsuk meg a programot C nyelven, fggvnyek segtsgvel, globlis vltozk
nlkl.
12.2. Tervezzk meg a kt szm legnagyobb kzs osztjt kiszmt programot Euklideszi
algoritmus segtsgvel, fellrl lefel tervezssel.
Valstsuk meg a programot C nyelven.
12.3. rjuk le a fellrl lefel tervezs folyamatt pszeudo-kddal, egy TopDown nev re-
kurzv algoritmussal.
12.4. rjuk le a fellrl lefel tervezs folyamatt pszeudo-kddal, egy BottomUp nev re-
kurzv algoritmussal.
Irodalomjegyzk
ASCII kdols
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
#include <stdio.h>
int main(){
printf("Egy printf-fel tobb sornyi\ninformaciot is ki lehet
iratni.\nTetszoleges helyen sort\nemelhetunk \"\\n\"
ujsor\nkarakterrel.\n\n");
//Egy printf-fel tobb sornyi
//informaciot is ki lehet iratni.
//Tetszoleges helyen sort
//emelhetunk "\n" ujsor
//karakterrel.
//
printf("Tudunk specialis karaktereket is kiirni:\nmacskakorom:
\"\nvisszaper: \\\nszazalekjel: %%\n\n");
//Tudunk specialis karaktereket is kiirni:
//macskakorom: "
//visszaper: \
//szazalekjel: %
//
printf("A \"\\t\" tabulator
hasznalataval\nnyolc\tkarakterenkent\ttabulalhatjuk\ta\tkiirando\tinformaci
ot.\n\n");
//A "\t" tabulator hasznalataval
//nyolc karakterenkent tabulalhatjuk a kiirando
informaciot.
//
printf("\t\t\t\t\"\\t\\t\\t\\t\" hatasara itt kezdem a
kiirast,\r\"\\r\"-t hasznalva itt folytatom.\n\n");
//"\r"-t hasznalva itt folytatom. "\t\t\t\t" hatasara itt kezdem a
kiirast,
//
printf("Decimalis elojeles egesz kiirasa \"%%d\" format string-gel
tortenik, pl.: %d\n\n", -123);
//-1
//+0
//+1
//+2
//
printf("Tobb [flag]: az elobbieket 8 karakteren, elojellel, balrol
nullaval kiegeszitve:\n%+08d\n%+08d\n%+08d\n%+08d\n%+08d\n\n",-2, -1, 0, 1,
2);
//Tobb [flag]: az elobbieket 8 karakteren, elojellel, balrol nullaval
kiegeszitve:
//-0000002
//-0000001
//+0000000
//+0000001
//+0000002
//
printf("Tobb [flag]: 8 karakteren, + elojel helye kihagyva, balrol
nullaval kiegeszitve:\n% 08d\n% 08d\n% 08d\n% 08d\n% 08d\n\n",-2, -1, 0, 1,
2);
//Tobb [flag]: 8 karakteren, + elojel helye kihagyva, balrol nullaval
kiegeszitve:
//-0000002
//-0000001
// 0000000
// 0000001
// 0000002
//
printf("Irjuk ki a 12-ot parametereket hasznalva, az alabbi
szamrendszerekben:\ndecimalis %d = oktalis %o = hexadecimalis %x\n\n", 12,
12, 12);
//Irjuk ki a 12-ot parametereket hasznalva, az alabbi szamrendszerekben:
//decimalis 12 = oktalis 14 = hexadecimalis c
//
printf("Irjuk ki ugyanezt, hasznaljuk a [flag] mezot a szamrendszerek
jelolesere:\n%d = %#o = %#x\n\n", 12, 12, 12);
//Irjuk ki ugyanezt, hasznaljuk a [flag] mezot a szamrendszerek
jelolesere:
//12 = 014 = 0xc
//
printf("Irjuk ki ugyanezt, hexadecimalis szamoknal a 10-15 szamjegyek A-
F legyen:\n%d = %#o = %#X\n\n", 12, 12, 12);
//Irjuk ki ugyanezt, hexadecimalis szamoknal a 10-15 szamjegyek A-F
legyen:
//12 = 014 = 0XC
//
printf("Igy nez ki a Pi 2 (3.14), 4 (3.1415) es 10 (3.1415926535)
tizedesjegy pontossaggal megadva \"%%e-vel\":\n%e %e %e \n\n", 3.14,
3.1415, 3.1415926535);
//Igy nez ki a Pi 2 (3.14), 4 (3.1415) es 10 (3.1415926535) tizedesjegy
pontossaggal megadva "%e-vel":
//3.140000e+000 3.141500e+000 3.141593e+000
//
Asszociativi-
struct szemely{
char Nev[21];
struct datum Szuletesi_ido;
}Fiu;
Fiu.Szuletesi_ido.Evszam=1990;
Fiu.Szuletesi_ido.Honap=11;
Fiu.Szuletesi_ido.Nap=29;
struct szemely{
char Nev[21];
struct datum Szuletesi_ido;
}Fiu;
struct szemely *pFiu=&Fiu;
pFiu->Szuletesi_ido.Evszam=1990;
pFiu->Szuletesi_ido.Honap=11;
pFiu->Szuletesi_ido.Nap=29;
++ post-inkremens int i=2, j;
j=i++;
// i:3; j:2
-- post-dekremens int i=2, j;
j=i--;
// i:1; j:2
++ 2 pre-inkremens int i=2, j;
j=++i;
// i:3; j:3
-- pre-dekremens int i=2, j;
j=--i;
// i:1; j:1
+ plusz eljel int i=2, j;
(nincs hatsa) j=+i;
// i:2; j:2
- negatv eljel int i=2, j;
j=-i;
// i:2; j:-2
! logikai tagads int i;
i=!(2<3);
// i:0 (hamis)
~ bitenknti neg- char c1=0x0f, c2;
ls c2=~c1;
// c1:0b00001111; c2:0b11110000
struct datum *pDatum=&Datum;
(*pDatum).Evszam=1990;
& cm (objektum int i, *pi;
memriacme) pi=&i;
sizeof tpus vagy ob- struct datum{
jektum mrete unsigned int Evszam;
byte-ban unsigned int Honap;
unsigned int Nap;
}Datum;
int i=sizeof(int*);
int j=sizeof(Datum);
//i:4 (32 bites architektra)
//j:12
* 3 szorzs double a=3.2, b=4.1, c;
c=a*b*2.0;
//c:26.24
/ oszts int i=3, j=2;
double a, b;
a=i/j; //egsz rtk oszts
b=a/j; //lebegpontos oszts
//a:1.0; b:0.5 .........................
% modulus int i=7, j=4, k;
double a=7.0, b=4.0;
k=i%j;
//k=a%b;// fordtsi hibt okoz
//(modulus csak egsz tpusokon
//rtelmezett)
//k:3 (a 7/4 maradka 3)