C, C++, OOP Mokomes Programuoti [A.Matulis] (2005) by Cloud Dancing

198

description

Klausimas „kaip parašyti gerą C+ programą?" primena klausimą „Kaip rašyti gerus romanus?" Yra du patarimai: „Žinok, ką nori pasakyti" ir „Treniruokis. Mėgdžiok gerą stilių". Bjarne Stroustrup

Transcript of C, C++, OOP Mokomes Programuoti [A.Matulis] (2005) by Cloud Dancing

  • , + + , O O P

    Mokoms programuoti

    Algirdas MATULIS

    Puslaidininki fizikos institutas

    Scanned by Cloud Dancing

    Vilnius, 2005

  • Matulis . , + + , O O P Mokoms programuoti

    Redagavo Graina Matulien Pieiniai Algirdo Matulio Maketavo Algirdas Matulis Virelio dizainas UAB CIKLONAS"

    ISBN 9955-497-86-6 Algirdas Matulis. 2005 UAB CIKLONAS". 2005

  • Pratarm

    Si nedidel knygel skirta tiems, kurie jau iek tiek paband rayti pro-gramas Pascal'io, Fortran'o, ar Basic 'o kalbomis, nori pramokti progra-muoti vis labiau populiarjaniomis C ir C + + kalbomis ir susipainti su objektinio programavimo principais.

    Knygel atsirado i paskait, kurias autorius kelet met skait tikslij specialybi studentams ir doktorantams Puslaidininki fizikos institute. Todl ir pavyzdiai pateikiami i matematini metod taikymo srities: integral skaiiavimas, diferencialini lygi sprendimas, Monte Kailo me-todas, funkcij grafik braiymas, veiksmai su vektoriais ir matricomis. Tai nra isami C, C + + ir objektinio programavimo apvalga, o greiiau tik paskatinimas giliau tais dalykais domtis. Taiau jeigu pasiseks perskaityti knygel nuo pradios iki galo ir parayti visas joje aptariamas programas, tai pajusite, kad mokate programuoti, ir bsite neblogai pasiruo skaityti rimtesnes knygas programavimo klausimais.

    Autorius atsiprao skaitytoj dl ne visada teisingo lietuvik termin vartojimo. Todl visur pateikiami ir angliki t pai dalyk pavadinimai. Jie sudti ir j knygos gale pateikt rodykl greta autoriaus naudojam lietuvik pavadinim.

    Man malonu padkoti geram draugui hab. dr. ilvinui Kancleriui u kruopiai perskaityt knygos rankrat ir gerus patarimus. Su juo mes aptariame visas programavimo problemas, kartu diaugiams nedideliais pasiekimais ir stengiams tobulti. Esu labai dkingas dizaineriui Tomui Dumbrauskui, visada papuoianiam mano knygas aismingais vireliais. Labai ai monai Grainai, kuri visada dalinasi su manim knyg raymo rpesiais, o kart msi nelengvo redagavimo.

    Visas pastabas ir komentarus praome atsisti Email'o adresu amatulisStakas.lt . Tuo adresu galima pasikonsultuoti ir knygelje pa-teikt program sudarymo klausimais.

  • Turinys

    Pratarm iii

    1 VADAS 1

    2 PROCESORIUS IR JO K A L B A 11 2.1 Kam mums to reikia 11 2.2 Kompiuteris H 2.3 Asembleris 14 2.4 Atminties tvarkymas ir kintamieji 18 2.5 Programos segmentai 21 2.6 Atminties modelis 23

    3 PATI PRADIA 25 3.1 Komandos 25 3.2 Funkcijos 27 3.3 Pirmoji programa 28 3.4 Kintamj deklaravimas 29 3.5 Ciklas 34

    4 FUNKCIJOS IR A R G U M E N T A I 41 4.1 Dviej funkcij programa 41 4.2 Funkcij veiklos derinimas 42 4.3 Hederiai 44 4.4 Teisinga dviej funkcij programa 45 4.5 Rezultato grinimas argument srae 48 4.6 Kintamieji ir j rodykls 50 4.7 Kintamojo siuntimas nuoroda 52

  • 5 KELETAS M A T E M A T I N I M E T O D 55 5.1 Simpsono taisykl 55 5.2 Rungs ir Kutos metodas 58 5.3 Algebrins lygties aknis 61 5.4 Monte Karlo metodas 63

    5.4.1 Pirmas metodas 64 5.4.2 Antras metodas 67 5.4.3 Treias metodas 68

    5.5 Atsitiktinis procesas 71 5.6 Re kursins funkcijos 76

    6 M A S Y V A I IR RODYKLS 79 6.1 Masyvai 79 6.2 Alobci ja 80

    6.2.1 Statin alokacija 81 6.2.2 Dinamin alokacija 82

    6.3 Daugialypiai masyvai 85 6.4 Kaip nusisti masyv funkcijai? 87 6.5 Eilut 91

    7 KELETAS PAGRAINIM 93 7.1 Funkcijos vietoj argument 93 7.2 Projektas 94 7.3 Meniu 96

    8 KLASS 99 8.1 Kas tai yra OOP? 99 8.2 Kompleksini skaii klas 102 8.3 Operatori pakeitimas 106

    9 KLASI PANAUDOJIMAS 113 9.1 Grafiko langas 113 9.2 Alfabetiniai langai 116 9.3 Pikselin grafika 124 9.4 Funkcijos braiymas 127 9.5 Virtualins funkcijos 134 9.6 Problemos su parametrais 142

  • TURINYS vii

    10 MATRICOS IR V E K T O R I A I 149 10.1 Vektoriaus klas 149 10.2 Priskyrimo operatorius 156 10.3 Kopijavimo operatorius 157

    11 ISO/IEC standartas 163 11.1 Vard erdvs apribojimas 163 11.2 Naujieji hederiai 166 11.3 vedimas ir ivedimas 167 11.4 Funkcijos ablonas 169 11.5 Klass ablonas 172 11.6 STL 175

    Pabaiga 177

    A C++ K O M A N D O S IR FUNKCIJOS 179 A.l Baziniai odiai (Keywords) 179 A.2 Tipai 180 A.3 Operatoriai 181 A.4 Funkcijos 182 A.5 Funkcija main 185

    Literatra 187

    Rodykl 189

  • 1 VADAS

    i knygel yra apie tai, kaip parayti program kompiuteriui. Tikiuosi, kad js kompiuter turite, nes prieingu atveju neverta jos skaityti.

    Kompiuteris gali bti bet koks. Mums pakakt net IBM 8086, bet manau, kad tokio dabar jau nepasisekt surasti. Tikriausiai js turite pentium kompiuter. Tai visai neblogai.

    Svarbiausios kompiuterio dalys yra procesorius ir atmintis. Proceso-rius vykdo visas ms komandas, o atmintyje jis talpina duomenis bei rezultatus, o taip pat ir program, kuri vykdo.

    Operacin sistema. sakyti procesoriui k nors tiesiogiai mes negalime. Ms prie procesoriaus neprileidia. Su procesoriumi mes galime ben-drauti tik per tarpinink, kuris vadinasi operacine sistema. Toki sistem yra inoma keletas:

    1. DOS pati paprasiausia sistema. Taiau ji dabar yra jau beviltikai pasenusi. Ji puikiai tvarkydavosi 8086-tame ir net 80286-tame kom-piuteryje. J galima bt dti ir pentium tipo kompiuter, bet taip jau niekas nedaro. Tai bt tiesiog juokinga ir kvaila.

    2. UNIX ir LINUX tai operacins sistemos, kurios bando konkuruoti su Mikrosofto kompanija. Taiau dar nesimato, ar jos gali Mikrosoft nugalti. Man jos nelabai patinka. Todl apie jas nieko ir nekalbsiu.

    3. WINDOWS 98, NT, 2000, XP tai Mikrosofto kriniai, kurie dabar dominuoja personaliniuose kompiuteriuose ir net sitvirtina serve-riuose. Mano kompiuteryje kaip tik yra tokia operacin sistema ir todl esu labai prie jos priprats. Taigi kalbdamas apie operacin sistem visuomet tursiu omenyje WINDOWS operacin sistem.

  • Microsoft Word

    D o c u m e n t ?

    [Times New Roman 48 | Normal

    Vilnius

    1.1 pav. MDI aplikacija.

    Windows anglikai vadinama multitasking sistema yra tokia sistema, kuri vienu metu gali atlikti daug darb. Kiekvienas darbas, vadinamas ap-likacija, turi savo atskir lang ekrane. Todl i sistema ir yra vadinama langais.

    Aplikacij lang gali bti keletas ri. Jie parodyti paveiksluose.

    1. MDI (Multi Document Interface) aplikacija, kurioje yra dirbama su keletu dokument. Tokios yra, pavyzdiui, Origin ar Word ap-likacijos. Viena i j parodyta 1.1 paveiksle. Matome, kad aplikacijos lange dar yra keli maesni atskir dokument langai.

    2. SDI (Single Document Interface) tai aplikacija, teturinti vienintel lang. Tokia, pavyzdiui, yra Notepad aplikacija, kuri parodyta 1.2 paveiksle. Tame lange galima rayti, arba paiyti.

    3. Dialog tai aplikacija, turinti vien lang, kurio negalima keisti. Jame negalima nei rayti, nei paiyti. Bendraujama su tokia ap-

  • I O Unt i t led - N o t e p a d PSE I B i 4 - S S i l How a r e you?

    * v1

    Ii j Sjl

    1.2 pav. SDI aplikacija.

    likacija, spaudant vairius klavius. Viena i toki dialogo tipo apli-kacij kalkuliatorius parodyta 1.3 paveiksle.

    4. Console tai pati paprasiausia aplikacija, kuri turi vien juod lang, ir kurioje galima spausdinti tik tekstines eilutes. Konsolins aplikacijos langas yra parodytas 1.4 paveiksle. Beje, paspaudus Alt+Enter klavius, juod konsols lang galima iplsti per vis ekran. Tuomet jis atrodo taip, kaip atrodydavo skaiiavim rezul-tatas sename DOS operacins sistemos valdomame kompiuteryje.

    Manau, kad kiekvienam bt smagu imokti konstruoti MDI aplikaci-jas. Taiau tai labai nelengvas darbas. Vis pirma, tam reikia turti kok nors labai ger kompiliatori, pavyzdiui VisualC++, kuris uima diske apie 200 MB. Antra, norint k nors pamatyti ekrane, reikia parayti apie 50 puslapi pradinio programos kodo. Be to, dar reikia ir suprasti, k reikia kiekviena to kodo eilut. Norintiems rayti tokias programas rekomenduoju paskaityti knyg [1].

    itos knygels tikslai daug kuklesni. Mes mokysims rayti tik konso-lins programas.

    Virtualin DOS'in maina. Dar daugiau, mes papraysime Windows operacins sistemos, kad ji mums emuliuot virtualin DOS'in main. Arba pasakysiu paprasiau. sivaizduosime, kad turime senovik 8086-

  • j:Calculator H S S H

    I i N i t S i l l

    0

    ...

    I Br ick I

    0" 1 0 J mcI JLl J ^ I Ml: J 5 j msI J j 2 3 - I \tx m . I : I L

    1.3 pav. Dialogo tipo aplikacija.

    1.4 pav. Konsolin aplikacija.

  • t kompiuter ir jame yra DOS operacin sistema. Todl patariu turti kompiuteryje instaliuot kok nors DOS'in kompiliatori C + + , pavyzdiui, BorlandC, ver. 3.1. Tai gana patogus paketas, o juo sukompiliuotos pro-gramos gerai atitinka mintas konsolines pogramas. Manau, kad jums pasiseks susirasti t paket Internet'e. A pats j susiradau svetainje http : / / sun .uos . .kr /download . htm.

    Programavimas. Taigi mes norime, kad kompiuterio procesorius pada-ryt mums kai k naudingo. Tuo tikslu reikia parayti program, kuri kompiliatorius sugebt paversti vykdomuoju failu. Daniausiai tokie failai turi exe ipltim. Trumpindami retkariais j pavadinsime tiesiog exe failu. Paleidus t fail, procesorius ir isprs mums reikaling udavin.

    Programas galima rayti vairiomis kalbomis, jeigu pasiseka surasti tos kalbos kompiliatori. Tikri programuotojai nuo seno naudoja asemblerio kalb. Ties juo mes iek tiek apsistosime kitame skyriuje. Dabar apie asembler pasakysiu tik du dalykus. Pirma, parayti program asembleriu labai sunku. Asembleriu parayta programa yra labai didel, nes proce-soriaus komandos yra labai primityvios. Procesoriui visk reikia smulkiai ir nuobodiai aikinti. Antra, asembleryje galima panaudoti visas proce-soriaus komandas (asembleris tai faktikai paties procesoriaus kalba). Todl programuojant asembleriu galima pasinaudoti visais kompiuterio resursais. Jeigu js norite parayti viruso program, tai j reikia rayti asembleriu. Visa programin ranga ilg laik taip pat buvo raoma tik asembleriu. Pavyzdiui, DOS operacin sistema parayta asembleriu. Sis-temines programas rao sisteminis programuotojas. Asembleris tai sis-teminio programuotojo kalba.

    Auktojo lygio programavimo kalba. Taiau be sistemini progra-muotoj yra dar ir mokslininkai. Jie irgi mgsta rayti programas. Asem-bleris jiems nekandama kalba. Todl 1958 metais specialiai mokslinin-kams buvo sukurta labai patogi ir gana paprasta kalba Fortran'as.

    Fortranu besinaudojaniam mokslininkui nebereikia inoti, kas yra pro-cesoriaus registras. Jam net nereikia inoti, kad kompiuteryje yra proce-sorius. Jeigu mokslininkas nori suskaiiuoti sinus, tai jam reikia parayti tik vien eilut

    Y = SIN(X)

    Taiau ita auktojo lygio kalba turi ir trkum daugelis kompiuterio resurs fortrane tampa nebeprieinamais. Pavyzdiui, nebegalima ekrane

  • nupaiyti tako, nebegalima valdyti porto, prie kurio prijungtas koks nors prietaisas.

    Taigi senais laikais buvo tokia padtis. Sisteminiai programuotojai pavydjo mokslininkams, kurie ra programas labai paprasta auktojo ly-gio kalba, o mokslininkai pavydjo sisteminiams programuotojams, kurie nors ir ra programas labai nepatogiu asembleriu, taiau galjo su kom-piuteriu daryti visk, kas tik jiems audavo galv.

    C tarpin programavimo kalba. 1972 metais buvo pabandyta sukurti tarpin kalb, kuri patikt visiems. Taip atsirado C kalba, kuri atrodo, kaip auktojo lygio kalba, o daryti su ja galima visk, tarsi tai bt asembleris.

    tai it kalb mes ia ir ruoiams mokytis. Manau, kad man nereikia pasakoti apie jos privalumus. Raau apie C todl, kad ta kalba man labai patinka. O jeigu js skaitote i knygel, tai, matyt, tikits, kad ta kalba patiks ir jums, ar bus reikalinga. Galiu pasakyti, kad dabar C jau tapo sistemini programuotoj kalba. Didioji dalis populiariausi operacini sistem Unix, Windows paraytos btent C kalba. Galima beveik tvirtinti, kad paskutiniuoju metu C tampa gimtja personalinio kompiu-terio kalba.

    Pascal'is. Yra dar ir kitoki auktojo lygio kalb Basic, Pascal ir 1.1. Noriau iek tiek pakalbti apie Pascal'. A jau minjau, kad C yra pati laisviausia kalba su ja galima daryti visk. Ir, aiku, netruko atsirasti ideologas tai Nicklaus Wirth1 kuris pasak, kad neribota laisv progra-mavime (kaip ir visika laisv gyvenime) yra labai blogai. Programavimas turi bti tiksliai reglamentuotas. Wirth'as sukr Pascal'.

    Pascal'is tai labai tvarkinga kalba. Cia kiekvienas odis turi tiks-li savo viet. Tai, k sukr Wirth'as, dabar yra vadinama struktriniu programavimu. Knygel prasideda btent struktrinio programavimo pa-vyzdiais. Juk norint k nors imokti, reikia priprasti prie tvarkos.

    Objektinis programavimas. Grieta tvarka, kaip ir visika laisv, taip pat yra labai nepatogus dalykas. Todl Pascal'is nra labai populiarus. Ilg laik jis iliko tik kaip universitetin programavimo kalba, bet dabar ir universitetuose pradedama jos atsisakyti. Todl buvo pabandyta iek tiek suteikti Pascal'iui laisvs. Buvo padaryta galimyb paiam programuoto-jui susikurti savas struktras objektus. Tokiu bdu atsirado OOP (Object

  • Oriented Programming). lietuvi kalb, matyt, t termin reikt ivers-ti taip: i objektus orientuotas programavimas. A naudosiu paprastesn termin. Vadinsiu j tiesiog objektiniu programavimu.

    Visi greitai pastebjo, kad OOP yra labai vaisinga idja. OOP buvo netrukus dtas ir C. Tokiu bdu atsirado nauja domi kalba C + + .

    Reziumuodamas noriau pasakyti tai k. C + + tokia pati laisva ir galinga kalba, kaip ir C. Taiau C + + kalboje programuotojas gali pats save apriboti jis gali susikurti pats sau tam tikras programavimo taisykles. Tai aidimas, kuriame mes galime susikurti savo mgstamas taisykles. iai kalbai ir objektiniam programavimui paskirta antroji knygels dalis.

    K mokysims. Manau, kad jau galime artti prie mokymosi. Taigi ko adu jus mokyti?

    Programavimo kalba, kaip ir bet kokia kita bendravimo kalba, turi tris svarbius elementus:

    gramatik;

    odyn;

    stili.

    Gali pasirodyti, kad patys svarbiausi yra pirmieji du gramatika ir ody-nas. I tikrj, jeigu js inote kalbos gramatik ir kelet odi, tai galite pradti kalbtis manau, kad uj parduotuv sugebsite nusipirkti duonos.

    Taiau, patys suprantante, kad inodami tik tiek, dar nesugebsite parayti romano. Jums taip pat bus be galo sunku dalyvauti proting moni pokalbyje. Taigi jeigu js norite pasinaudoti visomis kalbos gali-mybmis, teks priprasti prie tos kalbos naudojimo stiliaus.

    Visai tas pats yra ir su programavimo kalba. Programuotojas pro-fesionalas rao programas naudodamasis programavimo kalbos stiliumi. Todl didiausi dmes skirsiu C + + kalbos stiliui, tikdamas, kad gra-matik ir odyn js sugebsite valdyti patys. Juos reikia mokytis. Todl teks paskaityti kitas neplonas knygas. Be abejo, aptarsime visas kalbos konstrukcijas, kurios mums bus betarpikai reikalingos, taiau nesivelsime vis C + + kalbos galimybi ivardinim ar aptarim. Beje, vis mums reikaling odi sraas yra pateiktas priede.

    Programavimo procesas. Programos paraymas yra gana ilgas proce-sas. Jis schemikai pavaizduotas 1.5 paveiksle. Manau, kad js nesu-

  • Programa

    .EXE ^ Resultatas

    .COMy

    Editor ) ( Compiler ) ( Linker) ( DebuggeT~)\

    (Turbo) IDE (Integrated Development Environment) (BorlandC^y

    1.5 pav. BorlandC kompiliatorius.

    glumins anglik termin gausa. Mat iki iol man neteko matyti lietu-viko kompiliatoriaus. Todl ir jums, raant programas, teks irti tuos anglikus terminus. Taigi ar verta ia rayti lietuvikus t pavadinim atitikmenis.

    Pirmiausia, pasinaudoj redaktoriumi (editor), paraome programos tekst cpp fail (fail, kurio ipltimas yra cpp). J matome urayt kairiajame schemos bloke. Beje, programavimas kitomis aukto lygio kal-bomis skiriasi tik tuo, kad bus kitoks pradinio kodo tekstinis failas.

    Toliau programos kod kompiliuojame kompiliatoriumi (compiler) ir gauname objektin, arba obj fail. Tai jau kompiuterio kalba paraytas programos gabaliukas. Sakau, kad tai tik programos gabaliukas todl, kad didels programos atveju yra patogu j sukomponuoti i keletos objektini fail. Visus tuos gabaliukus sujungia vien galutin exe fail kita pro-grama, vadinama komponuotoju (linker). Beje, komponuotojas taip pat prijungia prie programos danai naudojamas bibliotekines funkcijas. Gaut exe fail jau galima bt naudoti kaip gatav program. Taiau daniau-siai ji bna pilna klaid ir netikslum. Todl j dar reikia derinti ir taisyti. Tai atliekama dar vienos programos derintojo (debugger) pagalba.

    Kad nereikt vargti atskirai su redaktoriaus, kompiliatoriaus, kom-ponuotojo ir derintojo programomis, rekomenduoju pasinaudoti kokia nors

  • integruota sistema. Toks, pavyzdiui, yra jau mintas BorlandC 3 .1 pake-tas, kur visos tos keturios programos yra sudtos vien, taip vadinam IDE (Integrated Development Environment), arba Turbo aplink. iuo paketu naudojausi, ruodamas knygelje pateiktus program pavyzdius ir tikrindamas pratimus.

    K skaityti? Mums belieka aptarti paskutin klausim kaip mokytis ir k skaityti. Reikia pasakyti, kad dabar jau yra ileista tkstaniai knyg apie C ir C + + kalbas. Dauguma i t knyg paraytos angl kalba. Kai kurios i j yra iverstos rus kalb. Knyg lietuvi kalba beveik neteko matyti.

    Noriu paminti solid Stroustrup'o C + + kalbos iradjo veikal [2]. Tai labai sunkiai skaitoma knyga, taiau joje galima rasti atsakymus beveik visus klausimus.

    Pradedantiesiems noriau parekomenduoti k nors lengvesnio, pavyz-diui, Davis knyg [3]. Tikiuosi, kad kiekvienas i js sugebsite patys susirasti k nors tinkamo. Beje, atsakymus daugel klausim galima su-rasti paiame BorlandC pakete, paspaudus kalvius Ctrl+Fl ir isikvietus pagalb (help).

    Patarimas. Ubaigdamas , gal kiek per ilgai utrukus, vad, negaliu susilaikyti nepapasakojs paskutinio kalambro. Labai seniai bandiau imokti slidinti nuo kaln. Tai labai sudtingas dalykas, nes sunku susi-gaudyti ir k daryti, ir koki kepur nusipirkti. Todl puoliau skaityti knygas. Tik po ilgo laiko rankas man pakliuvo knyga, kurioje visa tai buvo labai paprastai paaikinta tiesiog viename puslapyje buvo sufor-muluotos trys puikios taisykls.

    1. Pirmoji taisykl buvo tokia. Jeigu norite imokti slidinti nuo kaln, tai neskaitykite knyg apie kaln slidinjim. Tiesiog slidinkite nuo kaln.

    2. Antroji taisykl skamba iek tiek rimiau. Ji paaikina, kaip tai reikia daryti. Ji sako: visai nesvarbu, kaip tai daryti. Darykite taip, kaip jums atrodo patogiau.

    3. Ir pagaliau treioji taisykl. Kai js jau kelet kart nusileisite nuo kalno, apsidairykite aplinkui. Galbt js pastebsite mog, kuris tai daro u jus truputl graiau. Pabandykite t mog pamgdioti.

  • Taigi visos tos trys taisykls tinka ir programavimui C + + kalba, o i knygel jums silau tam, kad bt k pamgdioti. Taigi raykite progra-mas. Jeigu js paraysite visas ia silomas programas, matyt, iek tiek pramoksite programuoti.

  • 2 PROCESORIUS IR JO KALBA

    2.1 Kam mums to reikia Studijuojant auktojo lygio programavimo kalbas, tokias kaip Fortran ar C + + , tenka kankintis su kintamaisiais, rodyklmis ir kitokiomis abs-trakiomis svokomis. Jas i tikrj sunku gerai suvokti apsiribojant tik studijuojama auktojo lygio kalba. Mat perfrazavus inom matematikams Giodelio teorem, galima teigti, kad nemanoma sukurti nepriekaitingos taisykli sistemos panaudojant tik tomis taisyklmis charakterizuojamos sistemos svokas.

    Bet kokias auktojo lygio kalbos problemas daug lengviau suprasti prisimenant jos sukrimo tikslus. Btent bet kokia programavimo kalba yra skirta tam, kad programuotojas galt susikalbti su kompiuteriu. Fak-tikai tai yra vertimo i moni naudojamos bendravimo kalbos (pavyzdiui, lietuvi ar angl) vienam tik kompiuteriui suprantam mainin kalb problema. Todl manau, kad prie pradedant auktojo lygio programa-vimo kalbos studijas labai pravartu iek tiek susipainti tiek su kompiu-terio struktra, tiek su elementariosiomis mainins kalbos svokomis, ir pasekti, kaip tos svokos pavirsta auktojo lygio programavimo kalbos kon-strukcijomis.

    Tam, kad paskui bt lengviau suprasti tas C + + kalbos konstrukci-jas, iame skyriuje pateikiame elementarias inias apie kompiuter ir jo mainin kalb.

    2.2 Kompiuteris Kompiuteris yra prietaisas informacijai apdoroti. Juo naudojantis galima parayti laik arba suskaiiuoti, kam yra lygi dviej skaii (pavyzdiui, 5 ir 7) suma. Du svarbiausi kompiuterio elementai yra operatyvin atmintis,

  • kurioje galima urayti mint informacij (skaiius, raides, odius ir t. t.), ir procesorius, kuris sugeba su ta informacija tvarkytis.

    Procesoriaus veikla susideda i nuoseklaus labai paprast veiksm vyk-dymo. Pavyzdiui, procesoriaus galima paprayti, kad jis tam tikroje at-minties vietoje urayt skaii perkelt kit atminties viet arba sudt du vlgi i tos atminties paimtus skaiius. Tuo tikslu procesoriui reikia nusisti instrukcij. tai ia ir ikyla problema, kokia kalba ta instrukcija turi bti parayta.

    Pradti, matyt, reikia nuo abcls. Prisiminkime, kad lietuvi kalboje yra vartojami 32 simboliai raids:

    a, b, c, , . (2.1)

    Tai ne vienintelis galimas variantas. Pavyzdiui, graik kalboje yra ki-tokie simboliai: a, , , o rus kalboje yra daug mums dabar jau beveik nebesuprantam kirilicos simboli. K nors skaiiuodami mes naudojame dar kitus simbolius, naudojame tam tikr aritmetikos kalb, kurioje yra deimt skaitmen:

    O, 1, 2, 3, 4, 5, 6, 7, 8, 9. (2.2)

    Tai yra todl, kad msuose vartojama deimtain skaiiavimo sistema ir skaiius deimt, vienetu didesnis u devynis, yra ymimas jau dviej skait-men konstrukcija: 10.

    O kokius gi simbolius, kokias raides naudoja procesorius? Pasirodo, kad jis supranta tik du simbolius:

    0 ir 1. (2.3)

    Todl danai sakoma, kad kompiuteryje yra naudojama dvejetain sistema. Vadinasi, procesoriaus naudojami odiai, sakiniai, instrukcijos ir visa kita turi bti parayti btent ia nuli ir vienet kalba.

    Tai ne taip baisu, kaip atrodo i pirmojo vilgsnio. Pavyzdiui, ga-lima susitarti ir ukoduoti mums prastus deimtainius skaiius nuliais ir vienetais, kaip tai parodyta 2.1 lentels pirmame, antrame, ketvirtame ir penktame stulpeliuose. Galima ukoduoti ir raides. Pavyzdiui, pagal ASCII (American National Standard Codes for Information Interchange) kodavimo lentel raidei A atitinka konstrukcija 01000001, o raidei / 01100110.

    Panaiai koduojamos ir procesoriaus instrukcijos. Pavyzdiui, reikinys

    100010110000001000000000 (2.4)

  • 2.1 lentel. Keletas skaii deimtainje, dvejetainje ir eioliktainje sistemose.

    "10" "2" "16" "10" "2" "16" 0 0000 0 8 1000 8 1 0001 1 9 1001 9 2 0010 2 10 1010 A 3 0011 3 11 1011 B 4 0100 4 12 1100 C 5 0101 5 13 1101 D 6 0110 6 14 1110 E 7 0111 7 15 1111 F

    yra procesoriui skirta instrukcija, praanti paimti skaii i antrosios at-minties lstels ir nusisti t skaii j pirmj pozicij personalinje pro-cesoriaus ura knygelje. Mat procesorius ne tik tvarko operatyvin kompiuterio atmint, bet dar turi nedidel special atminties gabaliuk, vadinam registrais, kurioje jis atlieka skaiiavimus. Jeigu suraysime i eils visas tokias procesoriui skirtas instrukcijas, tai ir gausime program, kuri vykdydamas procesorius isprs mus dominant udavin. Tokios mainine kalba paraytos programos pavyzdys parodytas 2.1 paveiksle.

    Nemanau, kad js itvertumte, skaitydami roman su taip ukoduo-tomis lietuvi kalboje naudojamomis raidmis. Pastebti, kad virutinje patamsintoje eilutje uraytas skaiius "5", turbt galima. Taiau su-prasti, k reikia visi kiti nuliai ir vienetai vargu ar pasiseks, ypa jeigu tursime omenyje, kad kompiuterio atmintyje visi tie skaiiukai surayti vien ilg virtin.

    Todl pabandysime tai perrayti iek tiek patogesniu pavidalu. Js turbt jau atkreipte dmes, kad 2.1 paveiksle kiekvienas skaiius ("O" arba "1") uraytas atskir ma langel, imituojant pai maiausi kompiuterio atminties lstel. Ji vadinasi bitu. O kiekvienoje eilutje uraiau po atuonis tokius bitus. Tai neatsitiktinai. Kompiuterio at-mintyje bitai yra grupuojami didesn atuoni bit struktr, vadinam baitu. Ir kiekvienas baitas kompiuterio atmintyje turi savo adres. Tie adresai deimtainje sistemoje (kad mums bt patogiau juos suskaiiuoti) surayti pirmajame 2.1 paveiksle pavaizduotos lentels stulpelyje. Matote, ia j yra 27. Tai nedidelis kompiuterio atminties gaballis. Dabar ope-

  • ratyvinje personalinio kompiuterio atmintyje bait skaiius siekia beveik milijard. Taigi

    kompiuterio atmintis sudaryta i bait, ir kiekvienas baitas turi pastov savo adres.

    Praau to niekada nepamirti. Js galite sivaizduoti bait, kaip nedidel dut, su kuria siejami du skaiiai. Vien i j galima t dut dti. Tai baito turinys. O kitas skaiius aminai uraytas ant paios duts. Tai duts numeris arba baito adresas. ios duts kompiuterio atmintyje irikiuotos nuosekliai tarsi namukai miesto gatvje.

    Manau, kad jums (kaip ir man) nelabai patinka tie nuliai su vienetais. Juos tikrai sunku skaityti ir prisiminti. Todl kiekvienas baitas padalina-mas dvi tetradas po keturis bitus ir j turinys pakeiiamas eioliktains skaiiavimo sistemos simboliais. Tie simboliai parodyti treiame ir etame 2.1 lentels stulpeliuose. Matome, kad pirmieji (nuo "O" iki "9") eiolik-tains sistemos simboliai sutampa su tokiais paiais deimtains sistemos simboliais, o likusieji (nuo "10" iki "15") paymti pirmosiomis angliko al-fabeto raidmis. Skaiius "16" eioliktainje sistemoje ymimas jau dviem simboliais "10".

    Pasinaudoj eioliktaine skaiiavimo sistema 2.1 paveiksle parodyt programos gabaliuk perraome taip:

    0000: 00 00 05 00 07 00 00 00 0008: 00 00 B8 38 5B 8E D8 Al 0010: 00 00 8B IE 02 00 03 D8 0018: C3 00 00

    Tikiuosi, sutiksite, kad nors tai ir nesuprantamas, bet vis tik akiai mielesnis vaizdas. Atkreipkite dmes, kad skaiiai kairiajame stulpelyje nurodo pir-mojo baito eilutje adres. Jie irgi urayti eioliktainje sistemoje, ir tai geriausiai atitinka kompiuteryje naudojam vienintel dvejetain sistem.

    ie lentelje urayti baitai yra visai ekvivalentiki nuliais ir viene-tais ireiktai programai, parodytai 2.1 paveiksle. Todl toliau tok bait rinkin ir vadinsime programa parayta mainine kalba.

    2.3 Asembleris Dirbant su pirmosiomis sovietinmis skaiiavimo mainomis man yra tek rayti programas mainine kalba. Dabar maai kas rytsi tokiam bevilti-kam ingsniui. Reikalas tas, kad 1950 metais buvo sugalvota, kaip padaryti

  • 0 0|0|0|0|0|0|0|0 1 01010 0 01 01 01 0 2 0|0|0|0|0t 1|0|1 3 01010,0 0|0|0|0 4 01010|OI0|11111 5 0 J 0 j 010 0 r0,0|0 6 01010 10 0 r 01010 7 0 10010 0|0|0|0 8 0 10 1010 0101010 9 0|0|0|0 0 101010

    10 1|0|1 ,1 I 0, OI 0 11 0,0,1 |1 1 |0|0|0 12 0,1,0,1 1,0,1,1 13 1,0,0,0 1,1,1,0 14 ,,,, 15 1,0,1,0 0,0,0,1 16 0|0|0|0 0 |0 10 10 17 0|0,0,0|0|0|0|0 18 1,0,0,0 1,0,1,1 19 0,0,0,1 1,1,1 ,0 20 0,0|0,0 01 01 1,0 21 0,0, 0, 0| 0, 0| 0, 0 22 0|0|0,0 0, 0, 111 23 1,1,0,1 1,0,0,0 24 IIIIOiOIO1O1IiI 25 0 I 0 I 0,0 010,0 0 26 0|0,0|0 0 ,010 10

    2.1 pav. Programa parayta mainine kalba.

  • mainin kalb suprantamesne ir patogesne programuotojui. Pavelkime emiau pateikiam programos gabaliuk.

    Duomenys 0000 05 "5" 0001 00 0002 07 "7" 0003 00

    -L Wgj-L CLLUCL - -

    0000 B8 38 5B mov ax, 5B38h 0003 8E D8 mov ds, ax 0005 Al 00 00 mov ax, [0000] 0008 8B IE 02 00 mov , [0002] OOOC 03 D8 add bx, ax 000E C3 ret

    Kairje pusje perrame anksiau mainine kalba parayt tekst. Vis bait rinkin padalinome dvi dalis. Vienoje i j yra duomenys: skaiiai "5" ir "7'. O kitoje yra pati programa. Patogumo sumetimais duomen ir programos baitus sunumeravome atskirai, nors prie dedant kompiuter reikia tai pataisyti ir padaryti vientis bait numeracij pagal tai, kur ta programa bus rayta jos vykdymo metu. Toliau, kad bt aikiau, pro-gramos baitus suskirstme grupes, atitinkanias kiekvien procesoriaus instrukcij. K gi, nors vis dar nra nieko aikaus, bet nors matosi, kad ms programoje yra eios instrukcijos.

    1950 metais buvo pasilyta ms mainine kalba parayt program perrayti taip, kaip parodyta deinje pusje. Cia jau kakas panaaus angl kalb. I tikrj penktoje programos instrukcijoje matome od add, kuris anglikai reikia sudti. Taigi i instrukcija prao procesoriaus prie registro bx turinio pridti skaii, kuris uraytas ax registre.

    Gal prisimenate, jau minjau, kad procesorius turi personalin ura knygel registrus. J kiekis priklauso nuo kompiuterio architektros. Senasis IBM 8086 procesorius turjo keturiolika bendro naudojimo regis-

    ax, bx, cz, dx, di, si, ip, bp, sp, flags, cs, ss, ds, es, kuriuose buvo galima urayti po du baitus (16 bit) informacijos. Pra-dedant nuo IBM 80386 kompiuterio, procesoriaus ura knygel gerokai padidjo. Bendro naudojimo registrai buvo padidinti iki 32 bit. J pava-dinimai pakeisti, pridedant i kairs papildom e simbol (nuo odio ex-tended). Pavyzdiui, vietoje registro ip atsirado registras eip. Buvo taip

  • pat pridta madaug tiek pat sistemini registr. ioje knygelje mes kalbsime tik apie trumpus IBM 8086 tipo registrus. Tai verta daryti dl dviej prieasi. Viena vertus, mokytis visada geriau pradti nuo paprastesni dalyk. Kita vertus, net kompiuteriuose su ilgais registrais galima naudoti tik j puses, raant programas analogikas toms, kurios tiko senai IBM 8086 mainai.

    Taigi pasikartosiu, vykdydamas penktj ms trumpos programos in-strukcij, procesorius prie dviej bait ilgio skaiiaus, urayto bx registre, prideda skaii, nuskaityt nuo ax registro.

    Labai aiki prasm ir paskutins instrukcijos ret . Tai angliko odio return nuotrupa, kuri reikia sugrim, arba ios programos pabaig. Su-tiks toki instrukcij, procesorius sugrta i program ikvietusi kit program ar funkcij. iuo atveju jis sugrta vis kompiuter valdani operacin sistem.

    Likusiose keturiose instrukcijose matome odel mov. Tai kito angliko odio move nuotrupa, kuri sako, kad vykdydamas tas instrukcijas proce-sorius kak perstumia (arba nusiunia) i vienos atminties vietos kit. Pavyzdiui, antrojoje instrukcijoje ax registro turinys nusiuiamas ds registr.

    Treioji ir ketvirtoji siuntimo instrukcijos yra iek tiek kitokios. Ma-nau, kad galima susivokti, kad ia kakas tai siuniama ax ir bx registrus. Taiau duomen altinis dabar kitas. Tai ne registras, o tam tikra vie-ta operatyvinje atmintyje. Treiojoje instrukcijoje tai dviej bait ilgio skaiius, uraytas pradedant 0000 adresu duomen srityje, o ketvirtojoje toks pat skaiius, uraytas pradedant 0002 adresu. Nors sakau, kad siuniami arba sudedami skaiiai, taiau tai nebtina. Procesoriui juk vis tiek, kas ten tuose baituose urayta. Gali juk bti ir raids arba kokios nors fotografijos pikseliai. Pavyzdiui, pirmojoje instrukcijoje ax registr siuniamas ne kokio nors baito turinys, o paioje instrukcijoje esantis, e-ioliktainje sistemoje uraytas skaiius 5B38, kuris yra tam tikro baito operacinje atmintyje adresas. Taigi jeigu mes baitus sivaizduosime, kaip dutes (t jums tik k siliau), vadinasi, mov instrukcijos pagalba galima siuntinti ne tik tuos skaiius, kurie tas dutes sudti, bet ir ant pai dui uraytus numerius. Beje, tuos numerius (bait adresus) galima sudti ir paias dutes. Tokiu bdu baituose galima laikyti kit bait adresus, o tai leidia naudoti netiesiogins (indirect) adresacijos metodus.

    Smoningai sugaiau gerokai laiko aptardamas deinje pusje para-yt program, nordamas jus tikinti, kad nors ta programa yra visai ekvivalenti programai, uraytai kairje pusje mainine kalba, taiau ji

  • yra kandama net ir mogui, kuris dar net nra moksis programavimo. Sakyiau, kad tai yra visai padorios kalbos variantas. Si kalba vadinama asembleriu.

    Asembleris, kaip minjau, buvo sugalvotas 1950 metais, ir nuo to laiko visi, kas nori intymiai bendrauti su procesoriumi, rao programas asem-bleriu, kuris, galima sakyti, visai atitinka gimtj mainin procesoriaus (arba kompiuterio) kalb. Taiau reikia turti omenyje, kad procesorius vis tik asemblerio nesupranta. Todl reikalingas vertjas kompiliatorius, kuris iverst asembleriu parayt program mainin kalb. O pats vertimo procesas vadinamas programos kompiliavimu. Taigi asembleriu parayta programa paruoiama tekstiniame asm faile, kaip tai parodyta 16 puslapyje deinje pateikto programos gabaliuko pusje, o kompiliatorius j iveria mainin kalb, t. y. bit (ar bait) rinkin, kok matome 2.1 paveiksle. Tokiu bdu gautas exe failas gali bti paleidiamas kompiute-ryje. Jis, kaip minjau, vadinamas vykdomuoju failu.

    2.4 Atminties tvarkymas ir kintamieji Pagal tai, k papasakojau praeitame skyriuje, galime susidaryti spd, kad asemblerio kompiliatorius yra gana paprasta programa, kuri pagal j dt lentel pakeiia asembleriu paraytas instrukcijas j mainins kalbos atitikmenimis. Kadangi, raant programas asembleriu be kompiliatoriaus negalima apsieiti, buvo nutarta j apkrauti papildomis pareigomis.

    Raant programas mainine kalba, ikyla labai nemaloni atminties kon-trols pareiga. Kaip mes jau inome, kiekvienas tiek duomen, tiek pro-gramos baitas turi savo adres. Raydami program, turime prisiminti vi-sus tuos adresus ir nieko nesupainioti. Mes turime gerai sivaizduoti, kurio-je atminties vietoje bus rayta programa jos vykdymo metu, ir visk gerai sustyguoti. Ir bus labai blogai, jeigu kitas vartotojas sugalvos paleisti ms program kitoje kompiuterio atminties vietoje. Nordamas tai padaryti, jis turt visus programoje raytus adresus perrayti i naujo.

    Todl i nemaloni atminties kontrols pareiga ir buvo ukrauta kompi-liatoriui, o programuotojas ivaduotas ne tik nuo atminties kontrols, bet ir nuo konkrei adres. Tai buvo padaryta vedant programavimo pro-ces vairius vardus. Pavelkime emiau pateikiam bait ir asemblerio instrukcij rinkin.

    1 2 0000

    masm model small

  • 3 OOOO 4 0000 5 0000 0005 6 0002 0007 7 0004 8 0000 9 0000 B8 10 0003 8E D8 11 0005 Al 00 00 12 0008 8B IE 02 00 13 000C 03 D8 14 000E C3 15 end start

    cats du 5h rats dw 7h . code

    stack 256 . data

    start: mov ax, Sdata mov ds, ax mov ax, cats mov bx, rats add bx, ax ret

    Jis iek tiek panaus anksiau aptart asembleriu parayt program. Tai yra kompiliatoriaus pagaminta iklotin (listing) savotika jo darbo ataskaita. Deinje pusje matome programuotojo asembleriu parayt program, o kairje kompiliatoriaus darbo rezultat: program, per-rayt mainine kalba. Pirmame lentels stulpelyje tiesiog sunumeruo-tos asemblerio instrukcijos, o antrame stulpelyje pateikti programos bait adresai. Pati mainin programa surayta treiame stulpelyje. Tas treias stulpelis ir yra pagrindinis kompiliatoriaus darbo rezultatas. Jj kompilia-torius pateikia vadinamajame objektiniame faile (faile su pratsimu obj) .

    Palygin i iklotin su 16 puslapyje pateikta programa, matome, kad yra ir skirtum. Pavyzdiui, vietoje ankstesni instrukcij

    mov ax, [0000] mov bx, [0002]

    matome naujas instrukcijas

    mov ax, cats mov bx, rats

    Jose anksiau urayti konkrets bait adresai operatyvinje kompiuterio atmintyje (0000 bei 0002) pakeisti programuotojo igalvotais aismingais vardais: cats bei rats.

    Pavelg kairij lentels dal matome, kad kompiliatorius pakeit tuos vardus reikiamus bait adresus. Pats, deja, jis to nesugebjo padaryti ir teko jam iek tiek padti. Tai buvo padaryta dviej papildom instrukcij dka, kurios raytos penktj ir etj asemblerio eilutes:

    cats dw 5h rats dw 7h

  • c a t s

    5

    r a t s

    7

    2.2 pav. Kintamieji duts.

    Pirmoji i j yra direktyva, nurodanti kompiliatoriui, kad duomen srityje reikia rezervuoti du baitus (raid w yra nuo odio word, kuris ir reikia dvigub bait), j juos rayti skaii "5", ir toliau visoje programoje vard cats pakeisti pirmojo i t dviej bait adresu. Kaip matome, kompilia-torius tai ir padar. Antroji instrukcija yra analogika direktyva dl vardo rats .

    Taigi vardai cats bei r a t s yra ekvivalentas adres operatyvinje at-mintyje. J panaudojimas ivaduoja mus nuo konkrei adres raymo. Taiau mums vis tik reikia prisiminti, kad tai yra adresai, o ne "kats" su "pelmis". O svarbiausia reikia prisiminti, kiek bait yra rezervuota tais vardais vadinamiems atminties gabaliukams.

    Kai kada tuos vardus vadina kintamaisiais, turdami omenyje, kad j nurodom atminties blok gali bti raomas bet koks skaiius, be abejo, suderintas su to bloko matmenimis. Prisimenate, 14 puslapyje raiau, kad bait galima sivaizduoti, kaip dut. Taigi kintamasis asembleryje taip pat yra dut. Dvi tokios duts, atitinkanios ms aptariamoje programoje panaudotus kintamuosius, parodytos 2.2 paveiksle. Su tomis dutmis taip pat yra siejami du dalykai. Vienas i j tai skaiius, kur galima t dut dti. Ms aptariamoje programoje tai skaiiai "5" ir "7". O kitas dalykas tai t dui (j pirmj bait) adresai ( cats bei rats ) , kurie urayti ant pai dui. tai toks yra skirtumas tarp asem-blerio ir mainins kalbos. Panau skirtum tarp algebros ir aritmetikos. Aritmetikoje veiksmai yra atliekami su konkreiais skaiiais, o algebroje mes naudojame raides (kitamuosius), vietoje kuri galima statyti bet ko-kius skaiius. Todl algebroje gauti rezultatai yra bendresni jie tinka bet kokiems skaiiams. Asembleryje iloimas taip pat akivaizdus: mes aidiame su kintamaisiais dutmis, ir mums nebereikia rpintis, kaip konkreiai kompiliatorius irikiuoja tas dutes kompiuterio atmintyje.

    Asembleryje galima naudoti ir kitokio bait skaiiaus kintamuosius: baitus, dvigubus bei keturgubus odius ir kt. i kintamojo svoka vliau buvo perneta auktojo lygio programavimo kalbas.

  • Noriu atkreipti dmes dar vien asemblerio ypatum, kur matome eilutje

    9 0000 B8 mov ax, Odata

    Pradiniame programos variante toje vietoje buvo instrukcija

    mov ax, 5B38h

    Jos dka ax registr buvo siuniamas programoje naudojamos duome-n srities adresas (toliau t srit vadinsime duomen segmentu). Dabar tai pakeista simboliu data. Prisimenate, mes juk susitarme, kad asem-bleryje daugiau neberaysime joki konkrei adres. Bet tai ia mums ir nepasisek kompiliatorius nesugebjo rayti mainin program konkretaus duomen segmento adreso ir paliko ten neupildyt viet.

    Toki neupildyt viet objektiniame faile gali pasitaikyti ir daugiau. Pavyzdiui, jos paliekamos vietoje vis bibliotekini funkcij, toki, kaip nuskaitymas simbolio i klaviatros, nusiuntimas simbolio ekran ir pana-iai. Reikalas tas, kad kompiliatorius neformuoja galutinai vykdomojo exe failo. Tai atlieka kita programa komponuotojas. Btent, komponuo-tojas atsakingas u vis objektini fail ir funkcij bibliotek sujungim viening vykdomj fail. To sujungino metu ir raomi visi anksiau nerayti adresai, nes tik tada ir yra nusprendiama dl vis atminties blok idstymo.

    2.5 Programos segmentai Jau ne kart minjau, kad asembleryje duomenys ir programa suraomi atskirus atminties gabalus. Jie vadinami segmentais. Dabar atjo laikas pakalbti apie tai plaiau.

    Pradsime nuo paios programos, kurioje suraytos procesoriaus ins-trukcijos. Joms yra paskirtas procesoriaus ip (instruction pointer) regis-tras. Siame registre visada yra adresas tos instrukcijos, kuri procesorius ruoiasi vykdyti. 8086 procesoriaus ip registras (kaip ir visi kiti regis-trai) yra 16 bait. Vadinasi, jame galima urayti 216 = 65536 adres. Todl atrodo, kad procesorius gali manipuliuoti tik su 65536 B (bait) = 64 KB (kilobait) atminties gabalu. Toks atminties gabalas ir vadinamas segmentu.

    Pentium procesoriaus registrai yra 32 bit apimties. Todl is pro-cesorius gali kontroliuoti 232 = 429467296 B = 4 GB (keturi gigabait)

  • ip I T m i l l l l l I I I I I I Offset 16 bit - i

    L CS I I I 1 segment

    20 bit adresas j | | | | | | || | | | | | | | | | j segmentioffset

    2.3 pav. Instrukcijos adresas.

    atminties segment. Tokios didels operatyvins atminties dabartiniai per-sonaliniai kompiuteriai dar neturi. Vadinasi, pentium procesorius kontro-liuoja vis savo atmint vieno e ip (extended instruction pointer) registro pagalba, ir atrodyt, kad nra reikalo imtis sudtingesni adresacijos bd. Taiau atminties segmentacija pasirod labai patogi, nes galina lengvai stumdyti atskirus programos ir duomen gabalus po vis atmint, kai to prireikia. Todl tolimesn kalba apie 8086 procesoriaus tvarkymsi su at-minties segmentais yra daug bendresn, negu gali pasirodyti i pirmojo vilgsnio, ir j verta atkreipti dmes.

    Taigi 64 KB atminties segmentas yra labai maas, ir todl naudojamos kitos priemons atminties adresacijai iplsti. Procesorius turi keturis segment registrus: cs, ds, ss, es. J dka adresuojami trys svarbs programos segmentai: programos kodo, duomen, steko bei dar vienas segmento registras es gali bti panaudotas pagalbiniams tikslams.

    Procesorius instrukcijos adreso sudarymui be registro ip panaudoja dar ir kodo segmento registr cs. Tikras atminties adresas yra gaunamas pas-tumiant ios du registrus keturiais bitais vienas kito atvilgiu ir sudedant j turin, kaip tai yra parodyta 2.3 paveiksle. Tokiu bdu yra gaunamas 20 bit ilgio adresas, kurio dka galima kontroliuoti 220 = 1048576 = 1 MB (vieno megabaito) apimties atminties gabal. Tai ir yra standartin 8086 procesoriaus, arba DOS operacins sistemos atmintis (conventional memory).

    Nusakant adres atmintyje, cs registro turinys yra vadinamas segmentu (segment), o ip registro turinys ofsetu (offset). Taigi visas baito adresas uraomas tokiu bdu: segment: off set. Pavyzdiui, pirmojo atminties baito adresas yra 0000:0000, o paskutiniojo standartins atminties baito adresas bt F000:FFFF. J galima bt paymti dar ir tokiu bdu FFFF:000F. Pavelg 2.3 paveiksl, nesunkiai sitikinsime, kad tai reikia vien ir t pat adres FFFFF. Toks dvigubas adresas yra dar vadinamas tolimu (far) adresu. Analogikai offset yra vadinamas trumpu (short)

  • adresu. Segmento ribose procesorius naudoja trump adresacij. Todl labai danai segmentuota programa veikia greiiau.

    Programoje naudojami duomenys yra uraomi kit duomen seg-ment. Jis yra adresuojamas analogikai, pasitelkus ds registr. Taigi visi programos kintamieji irgi yra adresuojami dvigubu segment: o f f s e t bdu. Kadangi visos ms programos bus labai trumpos, tai jeigu kartais teks kalbti apie kintamojo adres, daniausiai domsims tik jo trumpuoju adresu.

    2.6 Atminties modelis io skyriaus pabaigai dar vienas painus dalykas. Nepergyvenkite, jeigu to jums nepasiseks suprasti. Juk visada prie io skyrelio galsite sugrti, kai apie tai teks vliau usiminti.

    Programoje gali bti trij ri segmentai: kodo, duomen ir steko. Kas yra stekas, netrukus suinosite. Priklausomai nuo to. kiek t segment yra ir kaip jie idstyti, turime vienok, ar kitok atminties model. Pati maiausia (ir, be abejo, greiiausiai veikianti) programa gaunama tada, kai visi trys minti segmentai sudedami vien ir t pai atminties viet, t. y. tada, kai tris segment registrus (cs , ds ir ss) nusiuniamas tas pats to bendro programos segmento adresas. Toks atminties modelis vadinamas t iny (mayiu) modeliu.

    is ekonomikas modelis, deja, turi vien esmin trkum jame tra tik sveikieji skaiiai. Manau, kad mes, mokslininkai, niekaip neisiversime be trupmenini skaii. Todl apsistosime ties kitu small (mau) mo-deliu, kuriame yra tie trupmeniniai skaiiai.

    Small modelyje naudojami du segmentai. Vienas i j yra kodo seg-mentas. Juo mes nesidomsime. Jis gali bti domus tik tiems, kurie rytsi mokytis programuoti asembleriu. Beje, BorlandC kompiliatorius gali bti ia labai geru pagalbininku. Mat jo galima paprayti, kad jis pagamint kompiliacijos metu tekstin asemblerio (su pratsimu asm) fail. Viena vertus tai gera pradia, norint parayti asemblerio program, o kita vertus tame asemblerio faile galima pamatyti subtilias klaidas, kai j nepa-siseka irykinti derinant C + + kalba paraytas programas.

    Kitame small modelio segmente sudedami kartu duomenys ir stekas. Vadinsime j tiesiog duomen (data) segmentu. tai segment mums danai teks pasiirti. Todl vilgterkim 2.4 paveiksl, kuriame ir paro-dytas mintasis segmentas. Vadinasi, dabar trijuose segment registruose

  • ds = ss = es

    / Data globaliniai kintamieji

    Stack

    sp lokaliniai kintamieji

    dinamin alokacija

    2.4 pav. Small atminties modelio duomen segmentas.

    (ds, ss bei es) yra vienas ir tas pats duomen segmento pradios adresas (ds :0000). Matome, kad segmentas padalintas tris dalis. Jo viruje yra sritis, kur sudedami (alokuojami) globaliniai kintamieji. Tai kintamieji, kurie matomi i bet kurios programos vietos ir gali bti bet kada ir bet kur panaudoti. Segmento apaioje yra vadinamasis stekas (stack). Tai labai svarbi sritis, kurioje alokuojami lokaliniai kintamieji, kurie atsiranda tuomet, kai yra aktyvuojama juos naudojanti programos funkcija. Todl ie kintamieji tai atsiranda, tai vl pranyksta ir stekas vis laik pulsuoja. jo vir visada rodo specialus steko registras sp (stack pointer). O dar vienas registras bp (base pointer) naudojamas konkreiam, steke esaniam kintamajam nuskaityti.

    Tarp globalini kintamj ir steko yra treia sritis, vadinama krva (heap). i atminties dal programuotojas gali naudoti savo nuoira. Jeigu jam kokiais nors sumetimais prireikia tam tikro bait skaiiaus, tai jis gali j paprayti pas vadinamj atminties administratori, kuris ir iskirs reikiamus baitus krvoje. Krva daniausiai naudojama dinaminei kintamj alokacijai, t. y. tiems kintamiesiams, apie kuriuos suinoma tik programos vykdymo metu.

    tai ir visa mums reikalinga informacija apie kompiuter. Dabar im-sims programavimo C ir C + + kalbomis, kuriam laikui apie tai umir-dami. Taiau, kai prireiks, bandysime prisiminti, kaip atrodo kompiuterio atmintis, bait adresai ir k su jais daro procesorius.

  • 3 PATI PRADIA

    3.1 Komandos C kaip ir kiekviena kita programavimo (ar bendravimo) kalba susideda i sakini. Tuos sakinius vadinsime komandomis. Komanda yra tam tikras odis (ar net odi grup), kuris baigiasi simboliu " ; " . Taigi pati papras-iausia komanda yra tiesiog kabliatakis

    Tai yra tuia komanda - ji nekliudo, taiau nieko ir nereikia. Netuios komandos pavyzdys galt bti toks:

    a=2;

    Tai yra priskyrimo komanda. Angl kalboje simbolis a vadinamas identi-ficator. Mes j vadinsime tiesiog kintamojo vardu. Taigi itas operatorius priskiria kintamajam a reikm 2.

    Galima naudoti ir kitokius, sudtingesnius, kintamj vardus. Tai gali bti bet koks raidi ir skaii rinkinys. Reikia atkreipti dmes du da-lykus. Tame rinkinyje neturi bti tarp. O taip pat reikia nepamirti, kad C kalboje didiosios ir maosios raids yra skirtingos. Todl vardai ALGA ir alga nurodo skirtingus kintamuosius. Tradicikai C kalboje stengiamasi naudoti masias raides.

    Rekomenduojama naudoti tokius kintamj vardus, kurie atspindi kin-tamojo prasm. Toks, pavyzdiui, galt bti kintamasis mano_alga. Jo prasm manau yra aiki ir nereikalauja papildom komentar. Dabar pradeda sigalti Pascal'io tradicija pirmsias odi raides rayti didio-siomis. Taigi galima bt kintamojo vard urayti dar ir taip ManoAlga. Tie abu vardai, be abejo, ymi skirtingus kintamuosius. Vartoti vien tik didisias raides nepatartina. Mat tokie vien tik i didij raidi

  • sudaryti odiai vartojami kitiems tikslams. Taip paymimi vadinamieji macros' ai konstrukcijos, kuriomis pakeiiami didesni teksto gabalai. Todl mes stengsims toki konstrukcij nenaudoti. Kadangi ioje kny-gelje pateiktos programos gana trumpos, tai daniausiai kintamuosius ymsime kokia nors viena maja raide. O pirmj didij raid var-tosime tik antrojoje knygels dalyje klasms ir objektams paymti.

    Programuodami C ir C + + kalba mes turime gerai sivaizduoti, kaip procesorius supranta kintamj. Ankstesniame skyriuje, kalbdamas apie asembler, minjau, kad vardais (arba kintamaisiais) paymimos danai vartojamos atminties vietos arba tam tikra nedidel duomen dalis. Nors auktojo lygio programavimo kalbose kintamasis turi daugiau savybi, mums bus patogu (bent jau pradiai) manyti, kad kintamasis yra tam tikra vieta kompiuterio atmintyje. Neblogas kintamojo pavyzdys yra, sakykim, Puslaidininkiu Fizikos Inst i tutas . Turbt visiems yra aiku, kad tai yra tam tikra vieta Vilniuje. Beje, t viet galima paymti ir ki-taip, pavyzdiui, Gotauto 11. Tai yra io instituto adresas. Anglikose knygose kintamojo adresas vadinamas odiu pointer. Mes j vadinsime rodykle. Noriu pabrti, kad kintamojo adresas rodykl yra labai svarbus C kalbos instrumentas, ir mums labai danai teks su juo susidurti.

    Kadangi jau inome, kaip atrodo komanda, tai galime pradti rayti programas. tai tokios programos pavyzdys:

    a=2;{b=3;c=a+b;}d=4;

    Atkreipsime dmes du svarbius dalykus. Pirma, kadangi kiekviena C kalbos komanda visada baigiasi tuo paiu simboliu (kabliatakiu ;), tai nra didelio reikalo rpintis komand atskyrimu. Ir taip gerai matosi, kur pasibaigia viena komanda ir prasideda kita. Beje, ia mes parame dar ir riestinius skliaustus, kurie sujungia kelet komand vadinamj komand grup. Mintoje programoje ji nieko nereikia ir pateikta tik iliustraciniais sumetimais. Taiau pasitaikys atvej, kur tokios komand grups bus reikalingos. Antra, ms programa labai neivaizdi ji primena vien ilg makaron. Todl toks programos uraymas, o kartu ir toks progra-mavimo stilius, ne veltui yra vadinamas makaroniniu programavimu. Tai blogas programavimo pavyzdys. Mes toki program neraysime.

    Taigi pirmiausia pasirpinsime, kad ms programa bt geros ivaiz-dos. T yra nesunku padaryti, nes C kalboje yra du simboliai tarpas ir nauja eilut, kurie kompiliatoriui nieko nereikia. Todl galime suskaldyti program eilutes ir pridti daug tarp, ir tokiu bdu j iek tiek pa-grainti. C kalboje yra net tradicija (rekomenduoju jos nepaeidinti),

  • rayti po vien komand j eilut. Taip pat labai rekomenduoju pradti rayti program nuo kairiojo lapo krato ir pastumti j dein (sakykim, per du tarpus) visas komand grupes. Todl tik k pateikt program perraysime tokiu, mano manymu, ymiai graesniu, pavidalu:

    a = 2 ;

    b = 3; c = a + b;

    d = 4;

    3.2 Funkcijos Praeitame skyriuje susipainome su priskyrimo komanda ir elementari algebrini veiksm operatoriais. Be j dar galima naudoti funkcijas. Pa-vyzdiui, galime rayti tokias program eilutes:

    y = s i n ( x ) ;

    Cia skaiiuojama s in (x ) funkcijos reikm ir gautas rezultatas priskiria-mas kintamajam y. Simbolis s in (x ) reikia kreipimsi j tam tikr, atski-rai parayt, programos gabaliuk, kuris yra vadinamas funkcija. Mums nereikia rpintis paia s in (x ) funkcija, nes j komponuotojas susiranda matematini funkcij bibliotekoje ir stato ms programos exe fail. Be abejo, mes galime ir patys parayti mums reikalingas funkcijas. Kaip tai padaryti imoksime vliau.

    Pats svarbiausias klausimas, naudojant funkcijas, yra kada tas funkci-jas naudoti, ir ar i viso naudoti. Manau, kad atsakymas yra akivaizdus. Jeigu vienu ir tuo paiu programos gabaliuku mums tenka pasinaudoti du ar daugiau kart, tai verta t programos gabaliuk perrayti funkcijos pavidalu, o pagrindinje programos dalyje rayti kreipinius t funkcij.

    Taiau tai nra vienintelis funkcijos panaudojimo atvejis. Manykim, kad mes programos pradioje esame priversti vesti labai daug pradini duomen. Uuot ra visas tas duomen vedimo komandas ms pa-grindinje programoje, verta jas iskirti atskir duomen vedimo funkcij, ir pagrindinje programoje parayti tik vien kreipin t funkcij. Taip ms programa taps elegantikesne, geriau struktrizuota. J bus daug lengviau skaityti ir analizuoti.

  • Toks programavimo stilius, kai didel programa skaldoma daugiau ar maiau autonomini funkcij, yra vadinamas struktriniu programavimu. Btent tok programavimo stili ia mes ir naudosime. Yra net nerayta taisykl jeigu kakuris programos gabaliukas pasidaro beveik vieno pus-lapio ilgio, reikia pagalvoti apie funkcijos vedim.

    Taigi ms programa bus ne komand, bet funkcij rinkinys.

    3.3 Pirmoji programa Net jeigu mums ir nepatikt rayti funkcijas, vien i j mes visada pri-valome parayti. ita funkcija turi special vard ji vadinasi main (pagrindin), ir nuo jos prasideda programos vykdymas. Ji atrodo taip:

    main()

    Po funkcijos vardo matome du skliaustelius. Tarp j yra raomi argumen-tai, kurie tai funkcijai yra perduodami jos ikvietimo metu. Paiai pirmajai programos funkcijai mes dar neturime ko perduoti, todl skliausteliai yra tuti. Taiau parayti skliaustelius privalome, nes be j kompiliatorius ne-supras, kad tai yra funkcija. Toliau raome riestinius skliaustelius. Mes jau inome, kad riestiniai skliausteliai ymi komand grup. iuo atveju minta komand grup ir sudaro ms funkcijos kn arba funkcijos kod. Jie irgi yra tuti. Ms pagrindin funkcija yra tuia ji nieko nedaro. Taigi tuia ir pirmoji ms programa.

    Taiau manau, kad btent nuo tokios tuios programos ir reikia pradti programuoti. Pabandykite i program kompiliuoti. Jeigu js jau esate instaliav BorlandC paket, tai paleiskite j ikviesdami be. exe fail. At-sidariusiame redaktoriaus lange, kauktelj pels klavi meniu langelyje FilelNew, atidarykite nauj fail ir usiraykite j disk (kad neprat toks sunkus darbas). Tada veskite tik k aptartos main funkcijos tekst ir, kauktelj pels klavi meniu langelyje Run | Run (arba dar geriau pas-paud Ctrl+F9 klavius klaviatroje), kompiliuokite. Kompiliatorius ne-protestuoja. Klaid nra. Beje, paspaudus Ctrl+F9 klavi, ikvieiamas ne tik kompiliatorius, bet ir komponuotojas. Jis, kaip matote, irgi ne-turi mums joki pretenzij. Vadinasi, mes parame teising pirmj pro-gram, j sukompiliavome, sukomponavome ir pasigaminome teising exe fail, kur galima surasti arba toje paioje direktorijoje, kurioje usirate

  • cpp fail, arba specialioje direktorijoje, nurodytoje langelyje Optionsl Direc tor ies Output Directory. Procesorius fail supranta, vykdo ir, be abejo, nieko neurao ekrane. Taip ir turi bti, nes mes juk nieko jo neprame daryti. Gera pradia, kaip sakoma, pus darbo. Svarbu, kad jau imokome rayti programas C kalba.

    3.4 Kintamj deklaravimas Dabar, kai mes jau esame iek tiek patyr ir inome, kaip rayti programas C kalba, pabandysime parayti iek tiek sudtingesn program. dsime pagrindin funkcij vien priskyrimo komand:

    main()

    a = 3;

    Pabandome j kompiliuoti. Rezultat matome 3.1 paveiksle. Ciaparodyta tai, k mato tie, kurie naudoja BorlandC paket. Kairiajame juodame lange matome programos pirma.cpp tekst, o antrame viesiame lange mums kompiliatorius pranea, kad programoje yra viena klaida. Vienos eiluts programoje sunku j padaryti daugiau. Paspaudus bet kok klavi, pasirodo kitas praneimas:

    Undefined symbol ' a ' .

    Reikalas tas, kad kompiliatorius prabga program tik vien kart. Susidrs su raide a, jis nesupranta, k toji ms panaudota raid reikia. Jums jau minjau, kad kintamasis yra tam tikra vieta kompiuterio at-mintyje. Taigi mintas praneimas reikia, kad kompiliatorius nesupranta, kiek reikia rezervuoti vietos ms sugalvotam kintamajam a kompiuterio atmintyje. Reikia C ir C + + kompiliatoriams padti, kaip tai jau darme asemblerio programoje (r. 19 puslapyje aptartas "kai" ir "peli" dekla-racijas). Taigi prie panaudodami kintamuosius, privalome juos deklaruoti. Teisinga programa turi bti parayta taip:

    main() {

    int a;

    a = 3;

  • Available memory: 1972K

    1 " >

    File Edit Search Run Compile Debug Project Option.

    Main file: .APIRMA.CPP Compiling: EDITOR ^ PIRMA.CPP

    File 4 1 1

    Lines compiled: Warnings:

    Errors:

    Total 4 1 1

    3.1 pav. Pirmosios programos kompiliavimo rezultatas.

  • Lyginant su ankstesne programa, ia yra viena papildoma eilut, kuri ir deklaruoja ms naudojam kintamj. Simbolis int reikia, kad tai yra sveikojo tipo kintamasis (integer). Kompiuterio atmintyje jis uima 2 bai-tus, ir jame gali bti patalpintas skaiius, kurio vert yra nuo -32768 iki 32767. Yra dar ir kitoki kitamj: char, long, f l o a t , double, unsigned int ir 1.1. Apiejuos praau paskaityti knygose, arba BorlandC paketo Help'e, kur surasite paspaud Ctrl+Fl klavius.

    C kalboje nra grietos taisykls, kur patalpinti kintamj deklaraci-jas. Jos turi tik pasirodyti anksiau, negu tie kintamieji yra programoje panaudojami. Jas galima patalpinti funkcijos pradioje ir atskirti tuia eilute nuo kit funkcijos operatori. C + + kalbos tradicija yra deklaruoti kintamj kiek galima ariau prie komandos, kurioje tas kintamasis panau-dojamas pirm kart.

    tai dabar ms mayt programa yra teisinga, kompiliatorius nebe-purktauja ir daugiau neberodo klaid. Programa veikia, ji nebe tuia. Taiau ekrane mes vl nieko nematome, nes ms programoje nra duo-men ivedimo komandos. Beje, programos veiklos rezultatus galima pa-matyti Output lange, kuris yra jungiamas papaudus Alt+F5 klavius arba pasinaudojus Menu: Window | Output langeliu.

    Cia noriu jums priminti, kad BorlandC pakete yra derintojo programa, kurios pagalba galima program vykdyti paingsniui ir stebti visus pro-gramos kintamuosius. Tuo nesunkiai galite sitikinti patys, atidar meniu Run ir Debug langelius. Taigi jeigu vietoje komandos Run spaudysite F7 klavi, tai visos programos komandos bus vykdomos po vien i eils. O meniu DebuglInspect komanda atidar papildomus langelius, matysite programos kintamuosius. Dar patogiau yra komandos Options I Envi-ronment I Mouse pagalba atidarius Mouse Options langel, padti tak prie Inspect eiluts. Tuomet kintamj stebjimo langelius galsite ati-darinti tiesiog deiniojo pels klavio paspaudimu.

    i labai paprasta ms pirmoji programa suteikia ger prog visa tai pademonstruoti. Pavelkime 3.2 paveiksl. Cia kairje BorlandC paketo lango dalyje matome maesn tams lang, kuris yra ne kas kita, kaip tekstiniame redaktoriuje parayta ms pirmoji programa. Joje paskutin eilut vieia kiek rykiau, ir tai reikia, kad mes esame programos derini-mo reime ir btent ia yra sustabdytas programos vykdymas. Apaioje matome atidaryt pilk Inspect lang, kuriame parodytas ms vienin-telis kintamasis a. Jo vert yra 3, kaip ir turi bti. Be to, ia matome ir

  • 3.2 pav. Kintamojo stebjimo langelis.

    io kintamojo adres: 8FF9:FFF4. Prisiminsime, kad tie du skaiiai rodo duomen segmento pradi ir o f f s e t ' , t. y. artim kintamojo adres duomen segmente. Tuo nesunku sitikinti, atidarius dar vien lang paveikslo deinje, kuriame parodyti procesoriaus registrai. J visada gali-ma atidaryti, pasinaudojus meniu WindowlRegister langeliu.

    Matome, kad ds , s s ir e s registruose yra viena ir ta pati vert 8FF9, sutampanti su segmeto verte kintamojo a Inspect langelyje. Mes jau i-nome, kad tos sutampanios registr verts ymi vienintel duomen seg-ment small atminties modelyje.

    Dar atkreipsime dmes o f f s e t ' FFF4, kuris sutampa su sp (stack pointer) registro verte. A jau minjau, kad funkcijoje deklaruoti kin-tamieji (o kintamasis a kaip tik deklaruotas main funkcijoje) yra alokuo-jami steke, kuris yra duomen segmento apaioje. Tai yra vienintelis main funkcijos kintamasis. Todl jis yra steko viruje, kur visada rodo sp registras. Tvarkytis su steku procesoriui padeda kitas bp (base pointer) registras. Jis rodo funkcijai skirto steko apai. Ms atveju tai yra dvejetu maesn vert FFF6. Mat ms programos main funkcija turi tik vien dviej bait dydio a kintamj.

  • Pirmosios programos aptarim pabaigsime prisimindami asembler. A jau minjau, kad galima paprayti BorlandC paketo, kad jis mums paga-mint asemblerio fail. Tuo tikslu menu langelyje Options | Compiler | Co-de generation udedame varnik eilutje Generate assembler source ir kompiliuojame program, paspausdami klavius Alt+F9. Tada vietoje vykdomojo exe failo kompiliatorius pagamina asemblerio fail (pirma, asm). j galime pasiirti pasinaudodami tuo paiu BorlandC paketo redaktoriumi. Neisigskite. Priadu asemblerio failais danai js nekan-kinti. Tai tikros veikianios programos asemberio failas. Todl ia yra daug deklaracij ir specialios informacijos derintojui. emiau parodytame tekste i to didelio failo ipjoviau tik tai, kas betarpikai siejasi su ms pirmos programos kompiliavimu:

    ; int mainO

    .main proc near push bp mov bp,sp sub sp,2

    ; { ; int a; ; a = 3;

    mov word ptr [bp-2],3

    ; return O;

    xor ax,ax jmp short 158

    31958: ; }

    mov sp,bp pop bp ret

    _main endp

    Programa ne tokia jau didel, kaip gali pasirodyti i pirmojo vilgsnio. Mat kabliatakis ( ; ) asembleryje reikia komentar. Todl irti reikia tik tas

  • eilutes, kuri pradioje to kabliatakio nra. O toki eilui visai nedaug. Beje, asemblerio kompiliatorius labai tvarkingas. Komentar pavidalu jis parodo ms pirmos programos C kod. Todl matome, kaip C programos komandos pavirsta asemblerio kodu.

    Taigi funkcijos pavadinimas int mainO pavirsta analogiku asemble-rio procedros ir jos pabaigos pavadinimu. Po pavadinimo tuoj pat seka veiksmai su registrais. stek nusiuniamas turinys t registr, kurie bus naudojami programoje, kad programos pabaigoje tas vertes galima bt atstatyti. Tam naudojamos push ir pop instrukcijos.

    Deklaracija int a asemblerio kod neveriama. Ja kompiliatorius pasinaudoja tik savo darbe. Dka jos jis suino, kad funkcijoje yra tik vienas dviej bait kintamasis ir todl, atimdamas i sp registro dvejet, paruoia tinkamas steko apaios ir viraus vertes.

    Vienintel iversta operacija i C kalbos j asemblerio kalb yra eilut mov word ptr [bp-2] ,3, kuri ir nusiunia trejet atmint ( duomen segmet) bp registre nurodytu adresu.

    Beje, is dviej kalb (C ir asemblerio) sugretinimas parodo, kaip gerai C kalba atitinka asembler. Todl galime manyti, kad auktojo lygio C kalba yra ariausiai prie mainins kompiuterio kalbos.

    Najau laikas grti prie ms pagrindinio udavinio prie programavimo C kalba.

    Jeigu mes norime parayti iek tiek rimtesn program, tai turime susi-painti su valdymo komandomis. J pagalba galima pakeisti nuosekl pro-gramos komand vykdym. Galima taip pat sudaryti ciklus, kur kelet kart atliekama viena ir ta pati komand seka. Pavyzdiui, skaiiuojant toki sum

    3.5 Ciklas

    3

    (3.1) n=l

    verta panaudoti cikl. J matome programoje:

    main() {

    int i , s ;

    s = 0;

  • f o r ( i = 1; i < 4 ; i = i + 1) { s = s + i ;

    siirkime, kaip sudarytas f o r ciklas. Tarp ios komandos skliausteli uraomi trys kabliatakiais atskirti sakiniai. Pirmasis i j atlieka ciklo kintamojo i inicializacij (priskiria jam pradin vert). Antrasis sakinys tai faktikai ciklo nutraukimo slyga. Ciklas vykdomas tol, kol i slyga yra patenkinta. Na, o paskutinis sakinys, kaip matome, yra komanda, keiianti ciklo kintamj po kiekvieno ciklo pakartojimo prijo pridedamas viene-tas. Vietoje t trij sakini galima urayti bet kokius kitus, jeigu tik jie prisideda prie ms tiksl gyvendinimo.

    Tuoj u skliausteli matome riestinius skliaustus, yminius cikle kar-tojam komand grup. iuo atveju ji sudaryta i vienintels kintamojo s padidinimo komandos. Programos pradioje is kintamasis, kurioje mes ir skaiiuojame sum, be abejo, turi bti ivalytas, priskiriant jam nulin vert. Ir dar privalome deklaruoti abu programoje naudojamus kintamuo-sius s ir i .

    C kalboje yra ir kitoki cikl sudarymo ir programos vykdymo pakeiti-mo komand: goto , break, continue, return, i f . . . e l s e , switch, while, do . . .wh i l e . Su jomis arba susipainsime vliau, arba susira-site jas patys, sprsdami pratimus. Niekada nenaudokite goto koman-dos. Nicklaus Wirth sako, kad jeigu naudojate goto komand, vadinasi, nemokate programuoti.

    Tie i js, kurie mokate programuoti kitomis kalbomis, manau, paste-bjote, kad ms parayta programa beveik niekuo nesiskiria nuo analogi-kos programos, paraytos kokia nors kita programavimo kalba, pavyzdiui, Fortran'u, Pascal'iu, ar Basic'u. I tikrj, tai ne C stiliumi parayta programa. Beje, joje dar yra ir klaid. Todl, prie kompiliuojant, siloma j dar kart perrayti tokiu galutiniu pavidalu:

    / / sum.cpp

    / * Sumos skaiiavimo programa * /

    #include

    main C) i

    int s = 0 ;

  • f o r ( i n t i = 1; i < 4; i++) s += i ; pr int f ("Sum = '/d\n", s ) ;

    > ioje programoje panaudotos naujos, tik C kalbai bdingos komandos:

    i++ vietoj i = i + l i r s + = i vietoj s = s + i . Trumpinamos ir kitos algebrins operacijos. ios komandos elegantikesns u sensias, ir danai padeda kompiliatoriui sudaryti greitesn kompiuterin program. Praom jas visada naudoti.

    Kitas vertas dmesio dalykas yra tas, kad C + + kalboje galima dekla-ruoti kintamj kartj inicializuojant. Tai taip pat neblogas programos su-trumpinimo ir jos pagrainimo rankis. Primenu, kad C + + kalboje rekomen-duojama nedeklaruoti kintamj, jei neketiname j tuoj pat inicializuoti. Taigi is deklaracijos ir inicializacijos apjungimas btent yra tai, ko reikia.

    Programoje matome dar ir kit nelaukt eilui. Aptarsime jas i eils. Pirmosios dvi i j tai komentarai. Mes turime galimyb / / simboliu paymti vien komentar eilut, arba simboliais / * . . . * / ap-skliausti vis komentar blok. Manoma, kad gerai paraytoje programoje komentarai turi sudaryti ne maiau tredalio eilui.

    A nekomentuosiu treiosios eiluts. Kakas turi pasilikti neaikaus! Kitaip jums gali pasirodyti, kad C yra labai lengva programavimo kalba. Taiau ita eilut btinai turi bti rayta program, nes kitaip kompi-liatorius programos nekompiliuos.

    Atkreipsime dmes tai, kad esant ciklo komand grupje tik vienai komandai, jos nebtina apskliausti riestiniais skliaustais.

    Na ir pagaliau paskutinje eilutje urayta pr int f ( . . . ) funkcija, kuri parodo skaiiavimo rezultat ekrane. Rekomenduoju nepatingti paspausti klavius Ctrl+Fl, isikviesti Help' ir detaliai susipainti su tos svarbios funkcijos panaudojimo variantais.

    Dabar jums siloma pasitreniruoti patiems ir parayti keturias tokias programas.

    Pratimas 1. Daugybos lentel nuo 1 iki 10. i programa iek tiek sudtingesn u tik k ms paraytj. Joje reikia panaudoti du f o r cik-lus, kur vienas i j yra raytas kito ciklo operatori grup. Programos rezultatas turi bti toks, koks parodytas 3.3 paveiksle. Nepamirkite, kad js matysite baltus simbolius juodame fone. Mes gi patogumo sumetimais toliau paiysime invertuoto ekrano paveiksliukus juodus simbolius bal-tame fone. Labai nepergyvenkite, jeigu nepasiseks nupaiyti toki grai

  • *** Hultiplication table ***

    1 2 3 4 5 6 7 S 9 10

    2 4 6 8 10 12 14 16 18 20 3 6 9 12 IS 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 S 10 IE 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90

    10 20 30 40 50 60 70 80 90 100

    3.3 pav. Pratimas 1.

    linij. Jus jas imoksite nupaiyti, kai veiksite 4 pratim.

    Pratimas 2. Lentel = 1, , 10, 2, 3 ir 1/x. Tai visai paprasta vieno f o r ciklo programa. Ekrane turi pasirodyti 3.4 paveiksle parodyta lentel.

    Pratimas 3. Deimtaini, atuntaini, eioliktaini ir dvejetaini skai-i lentel nuo 1 iki 16. Programos veiksm rezultat matote 3.5 paveiks-le. Manau, kad su deimtainiais, atuntainiais ir eioliktainiais skaiiais problem netursite. Dar kart atidiai perskaitykite apie p r i n t f ( . . . ) funkcij. Ten rasite nurodym, kaip urayti formato eilut, kad bt atspausdinti reikiami skaiiai. Skaiius dvejetainje sistemoje reiks ga-mintis patiems. Parodykite, k sugebate. Dvejetainius skaiius galima pasigaminti nuoseklios dalybos i 2 bdu. Galima t dalyb pakeisti ele-gantikesnmis postmio > ir maskavimo & operacijomis. Galima net pa-sinaudoti specialia itoa funkcija, kuri bet kok sveikj skaii bet kokioje sistemoje pakeiia charakteri (raidi ir skaitmen) masyvu.

    Pratimas 4. ASCII kod lentel. Tai standartin kompiuteryje naudoja-m simboli lentel. Komanda p r i n t f ("7,4d % c " , 97, 97) atspausdina ekrane tokius simbolius: 97 a. Mat pirmasis 97 skaiius spausdinamas kaip sveikasis ( int ) , o antrasis kaip raid (char), paymta numeriu 97. Atspausdinkite visus 256 simbolius. Patys sugalvokite, koki lentel juos sudti. Neisigskite, jeigu kai kurie simboliai nesileis spausdinami. Kad ivengtumte nelaukto lentels sudarkymo, panaudokite i f komand.

    Man pasisek tuos visus ASCII kodus surayti dvi lenteles, kaip tai

  • *** Table ***

    >: 2 3 i/x

    1 1 1 1. 00 2 4 8 . 50 3 9 27 0. 33 4 16 64 0. 25 S 25 125 0. 20 6 36 216 0. 17 7 49 343 0. 14 S 64 512 0. 12 9 81 729 0. 11

    10 100 1000 0. 10

    3.4 pav. Pratimas 2.

    ** Numerical systems **

    "1" "8" "IS" "2"

    0 0 0 0 1 1 1 1 2 2 2 10 3 3 3 11 4 4 4 o 5 5 5 101 6 6 6 110 7 7 7 111 8 10 8 1000 9 11 9 1001

    10 12 A 1010 11 13 B 1011 12 14 C 1100 13 15 D 1101 14 16 E 1110 15 17 F 1111

    3.5 pav. Pratimas 3.

  • ASCII codes : Part I

    0 1 El 2 3 V 4 5 * 6 7 8 9 10 11 12 V 13 14 J] 15 D!

    16 17 i 18 I 19 ; 20 U 21 22 _ 23 I 24 r 25 26 27 * 28 U 29 30 * 31 -32 33 f 34 " 35 tt 36 $ 37 % 38 a 39 40 ( 41 ) 42 43 + 44 45 - 46 47 / 48 49 1 50 2 51 3 52 4 53 5 54 6 55 7 56 8 57 9 58 59 60 < 61 = 62 > 63 ? 64 Il 65 66 67 C 68 D 69 E 70 F 71 G 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 0 80 P 81 Q 82 R 83 S 84 T 85 U 86 U 87 U 88 X 89 V 90 2 91 [ 92 \ 93 ] 94 95 96 97 a 98 99 C 100 d 101 e 102 f 103 9

    104 h 105 i 106 j 107 k 108 1 109 m 110 n 111 0 112 P 113 q 114 r 115 s 116 t 117 u 118 u 119 120 X 121 122 z 123 { 124 I 125 } 126 127

    ftSCII codes : Part I I

    128 129 130 131 a 132 a 133 a 134 a 135 136 137 138 139 140 i 141 i 142 143 S 144 145 146 f 147 0 148 0 149 0 150 151 152 153 0 154 (i 155 < 156 157 U 158 159 f 160 a 161 162 163 U 164 165 N 166 167 168 i 169 r 170 n 171 Js 172 . 173 t 174 175 176 177 I 178 I 179 I 180 181 182 Il 183 184 =I 185 186 H 187 188 fl 189 11 190 3 191 1 192 L 193 X 194 T 195 196 - 197 + 198 j; 199 I 200 Il 201 202

    n 203 U 204 1! 205 206 u 11 207

    I

    208 U 209 J 210 211 U 212 213 F 214 215 i

    216 X T 217 J 218 219 I 220 221 I 222 I 223 224 a 225 IJ 226 r 227 228 229 230 231 232 i 233 o 234 i) 235 6 236 to 237

    J 238 e 239

    240 = 241 + 242 243 < 244 r 245 J 246 - 247 S

    248 249 250 251 J 252 253 2 254 255

    3.6 pav. Pratimas 4.

  • parodyta 3.6 paveiksle. Atkreipkite dmes, kad antroje kod lentels da-lyje yra nemaai pseudografini element, kuriuos visada galima panau-doti savo programose rezutat ivedimo pagrainimui. I ten esani simboli galima sudaryti graias linijas, j susikirtimus ir daug kit daili ornament. Pavyzdiui, ra program komand

    printf ("'/,'/,.,'/,.,\'', 201,205,205,205,205,205,187);

    ekrane pamatysite neilg dvigub itisin linij su ulenktais emyn galais. Taigi pasitreniruokite ornament paiyme. Beje, tai galima padaryti ir paprasiau. Galima tuos paius ornamentus tiesiog nupaiyti BorlandC redaktoriuje. Tik k aptart linij galima nupaiyti trumpesne ir elegan-tikesne komanda, uraant ASCII lentels simbolius tiesiog printf ko-mandos formato eilut (tarp kabui). Simbolius galima vesti i klaviat-ros, paspaudus ALT ir surinkus trij skaitmen simbolio numer klaviais, esaniais klaviatros deinje.

  • 4 FUNKCIJOS IR ARGUMENTAI

    4.1 Dviej funkcij programa Manau, kad js skmingai veikte 3 skyriaus uduotis ir dabar jau mokate parayti vienos funkcijos programas. Dabar imsims sudtingesni, dviej funkcij program. Cia matote vien i j.

    main() {

    int a = 2; int b;

    b = two(a) ;

    pr int f ("A=Xd 2*A='/,d\n" ,a ,b ) ; > two(x) {

    int temp;

    temp = 2 * ; return temp;

    > Tai nra labai paini programa. Pagrindinje main funkcijoje kreipiamasi funkcij two, kuri yra parayta tuoj pat u main funkcijos. Si funkcija grina padvigubint argumento vert.

    Para program, tikjoms pamatyti ekrane tok rezultat:

    A = 2 2*A = 4

  • Deja, ioje programoje yra tiek daug klaid, kad net nesinori jos kompiliuo-ti. Be abejo, galiau suformuluoti visas taisykles. Js jas imoktumte ir mes raytume programas be klaid. Bet tai ne pats geriausias mokymosi bdas. Manau, kad yra daug geriau i pradi daryti daug klaid, o paskui i t klaid mokytis. Nordami pataisyti programoje padarytas klaidas, mes turime gerai suprasti, kaip kompiliatorius tvarkosi su kintamaisiais. Jeigu tai suprasime, tai visos taisykls darysis akivaizdios.

    4.2 Funkcij veiklos derinimas Akivaizdu, kad visos funkcijos turi bti gerai suderintos tarpusavyje. Ki-taip programa nesprs reikiamo udavinio. Pagrindinis ms rpestis, kad kintamieji bt teisingai nusisti j kvieiam funkcij, o pastaroji teisingai nusist savo veiklos rezultat j ikvietusiai funkcijai. Taigi prie perduo-dant valdym i main funkcijos j funkcij two, reikia nusisti tai funkcijai kintamj a, o two funkcija turi grinti main funkcijai padvigubinto kin-tamojo vert.

    Tai galima padaryti vairiais bdais. Pats papraiausias bdas yra deklaruoti kintamuosius globalikai, kaip yra parodyta emiau.

    int a = 2; int b;

    main()

    two() ; printf("A=Xd 2*A=Xd\n",a,b);

    > two () {

    b = 2 * a;

    Dabar a ir b yra globaliniai kintamieji. Jas mato visos po deklaracij esanios funkcijos (t. y. main ir two). Vadinasi, i viso nebra kintamj persiuntimo problemos, taiau u tai tenka mokti brangi kain. Dabar

  • funkcijos netenka savo nepriklausomybs. Mes nebegalime pakeisti main funkcijoje naudojam kintamj vard, nes tai padarydami sugadinsi-me two funkcij. O juk labai nemalonu, kai didelje programoje, i-tais klaid 15-tame puslapyje, sugadiname funkcij, esani 73-iame pus-lapyje. Suderinti toki program beveik nemanoma ir visikai nebegalima nei jos priirti, nei tobulinti. Toks makaroninis programavimo bdas yra labai blogas ir mes juo nesinaudosime. Vadovausims principu, kad gerai struktrizuotoje programoje i viso neturi bti globalini kintamj.

    Taigi kiekviena funkcija turi dirbti su savo lokaliniais kintamaisiais, o reikalingi kintamieji turi bti siuntinjami i vienos funkcijos kit, kaip tai urayta 41 puslapio programoje. Tai kaip su ia kintamj persiun-timo problema susitvarko procesorius? O jis daro tai k. Kai main funkcija kvieia two funkcij, persisdama jai kintamj a, procesorius kopijuoja t kintamj ir jo kopij patalpina steke. Si kintamojo a kopija faktikai tampa lokaliniu two funkcijos kintamuoju, su kuriuo pastaroji atlieka veiksmus. Ji padvigubina io kintamojo vert ir urao rezultat kit lokalin kintamj temp.

    Dabar ikyla antroji problema. Baigusi savo darb funkcija two privalo sugrinti kintamojo temp vert j ikvietusiai main funkcijai. Vadinasi, ji turi kakur t rezultat patalpinti. Mes sivaizduosime, kad tas gri-namas rezultatas yra taip pat patalpinamas steke. I tikrj grinimas atliekamas truputl sudtingesniu bdu, taiau mums dabar nra reikalo gilintis tas detales. Tuo besidomintiems, siloma patiems sugeneruoti asemblerio kod ir patyrinti, kada ir kaip funkcija grina kintamj.

    Vadinasi, kompiliatorius turi i anksto inoti, kiek vietos reikia tiems kintamiesiems steke. Todl funkcij argumentai ir funkcijos grinama vert turi bti deklaruojami. Tai padaroma programos vard pirmj funkcijos eilut pakeiiant tokiu bdu

    int two(int x)

    ia funkcijos skliausteliuose uraytas int nurodo siuniamo funkcij argumento tip (kitaip sakant, nurodo, kiek jam reikia rezervuoti vietos steke), o prie pai funkcij uraytas int deklaruoja grinamo kinta-mojo tip.

    Funkcija main yra tokia pati funkcija, kaip ir visos kitos. Todl reikia deklaruoti ir jos grinam vert. C kalboje yra tradicija deklaruoti main funkcij, grinania int tipo vert. Todl rekomenduojama i funkcij rayti pagal tok trafaret:

    int main()

  • return 0; > Grinamas nulis faktikai yra siuniamas operacinei sistemai, ikvietusiai ms program. Tokiu bdu programa pranea operacinei sistemai, kad ji savo udavin vykd skmingai.

    Taiau tai buvo dar ne paskutin klaida ms programoje. Jau jums minjau, kad kompiliatorius prabga program tik vien kart. Todl su-tiks main funkcijoje eilut b = two (a) , nesupranta, kokios tai yra funkci-jos ikvietimas, nes paios funkcijos kodo jis dar nra perskaits. Mes turime pagelbti kompiliatoriui. Yra keletas bd, kaip tai padaryti. Pa-vyzdiui, galima sukeisti funkcijas vietomis, ir parayti two funkcij vir main funkcijos. Taip daroma Pascal'io programose kvieiamos funkci-jos ten visada yra raomos vir jas kvieianij. Kartais taip rayti bna nepatogu. Pagrindin funkcija visada atsiranda failo gale, o tai apsunkina programos analiz. C kalboje tai sprendiama paprasiau, vedant vis funkcij deklaracijas paraant programos pradioje vis naudojam funkcij vard eilutes.

    4.3 Hederiai Programoje panaudota duomen ivedimo funkcija pr int f taip pat turi bti deklaruojama. Tai labai nemalonus darbas, nes, nordami j atlikti mes privalome inoti bibliotekini funkcij deklaracijas. C kalbos krjai nutar ir ia mums truput padti. Visos bibliotekini funkcij deklaracijos yra suraytos specialius failus, turinius h ipltimus. Jie vadinasi hede-riais (header). Mums belieka tik komponuoti reikiam heder program. Funkcija pr int f yra deklaruota s t d i o . h faile.

    Bet kokio failo jungim program galima atlikti direktyvos pagalba. Direktyva vadinasi eilut, prasidedanti simboliu #. Pats kompiliatorius direktyv neskaito. Taiau yra dar viena speciali programa, kuri va-dinasi preprocesoriumi. Jis prabga kompiliuojam program prie pat kompiliatori ir perskaito visas direktyvas. Surads direktyv #include, vaizdiai kalbant, preprocesorius paima irkles, perkerpa direktyvos vieto-je ms program ir rao nurodyt fail. Tokios direktyvos pagalba mes galime statyti program bet kok fail bet kokioje vietoje. Taiau pagal nusistovjusi tradicij tas taikoma tik hederiams.

  • Failui nurodyti #include direktyvoje naudojamos kabuts " . . . " . Tarp j reikia parayti piln failo pavadinim (skaitant direktorij, kurioje jis patalpintas). Beje, direktorijas atskirianius enklus (backslash) reikia sudvigubinti, nes toks viengubas enklas BorlandC pakete naudojamas tik specialiems (valdantiems) simboliams ymti. Yra dar ir kitas failo pava-dinimo nurodymo bdas, apskliaudiant j kampuotais skliausteliais < . . . >. itaip nurodomi failai, kurie yra specialioje include direktorijoje arba direktorijoje, nurodytoje kompiliatoriaus opcijose. Naudojant BorlandC paket, tai galima surasti atidarius meniu langel OptionslDirectories Include Director ies .

    Taip pat labai rekomenduoju program visada jungti dar ir kit header conio.h, kuriame yra dvi labai patogios komandos. Viena i j c l r s c r ( ) ivalo ekran. i komand verta parayti kiekvienos programos pradioje. O kita getchO sustabdo trumpam programos vykdym ir parodo rezultat duomen ivedimo lange. Paspaudus bet kok klavi, programos vykdymas tsiamas.

    4.4 Teisinga dviej funkcij programa Dabar mes esame jau pasiruo perrayti teisingai aptariam dviej funk-cij program. Ji yra tokia:

    Programa 1

    // Teisinga programa : kintamojo kopijos siuntimas

    #include #include

    // Funkcijos deklaracija int two(int x);

    / / int mainO {

    int a = 1, b = 2;

    clrscr() ; a = 3;

  • 4.1 pav. Programos 1 derinimas.

    b = two(a); printf ("A = '/.d 2*A = 7,d\n", a, b); getchO ;

    return 0;

    Il Funkcijos kodas int two(int x) {

    return 2 * ; >

    Matote, lyginant su pradine 41 puslapio programa, dabar teisingai yra deklaruoti visi kintamieji ir funkcijos. O taip pat programos pagrainimo sumetimais pridta keletas komentar ir imestas lokalinis temp kintamasis i funkcijos two, kuris ten buvo visai nereikalingas. i program galima ir kompiliuoti. Matome, kad klaid nra, o, j paleidus, ekrane pasirodo teisingas rezultatas.

    Iliustraciniais sumetimais pabandysime i program derinti. Spaudy-dami F7 klavi ir sustoj two funkcijos viduryje, matome 4.1 paveiksle par-odyt vaizd. Be paios programos ia parodyti dar trys inspect langeliai. Du i j rodo lokalinius main funkcijos kintamuosius: a bei b. Pirmajam i j priskirtas skaiius 3, o kintamasis b turi kakoki atsitiktin vert. Taip pat parodytas kintamasis x, kuriame urayta ta pati kintamojo a vert. Vadinasi, kintamasis a i tikrj buvo atsistas j funkcij two(x). Taiau

  • I { FFEC FFFO {FFF2 FFF4

    x(a) = 3

    a = 3

    SPtwo

    sp main

    4.2 pav. Programos 1 stekas.

    taip pat matome, kad kintamj a ir adresai yra skirtingi. Vadinasi, lokalinis funkcijos two kintamasis yra main funkcijos kintamojo a kopija. Ir tai yra du skirtingi kintamieji.

    Atkreip dmes kintamj adresus, sitikiname, kad jie irikiuoti tvar-kingai. Maiausias adresas yra kintamojo x, nes jis vliausiai ia atsirado. Jis atsirado tik tada, kai valdymas buvo perduotas two funkcijai. Tai patvirtint ir registro sp verts, kurias galima pamatyti meniu langelyje Window I Register . Kol esame funkcijoje main sp = FFF2, o kai perokame two funkcij, jo vert pasikeiia FFEC, nes steke atsiranda lokalini tos funkcijos kintamj sritis.

    Jums gali kilti klausimas, kodl ne sp = FFFO, juk two funkcija teturi tik vien lokalin kintamj. Kodl two funkcijai skirtoje steko dalyje atsi-rado dar trys papildomi baitai? klausim BorlandC derintojas neduoda atsakymo. Norint tai isiaikinti, tekt derinti asemblerio program. Tada sitikintume, kad tie trys baitai i tikrj palikti ia ne veltui. Dviejuose i j uraomas adresas main funkcijoje, kur reikia sugrti, kai baigiamas funkcijos two darbas. O dar vienas baitas reikalingas bp registro verts isaugojomui. Mat visos funkcijos vartoja tuos paius registrus, o ikvie-tusios funkcijos registr verts neturi prati.

    Manau, kad dabar tursime supratim, kas tai yra stekas ir kas su juo darosi kreipimosi funkcijas metu. Vaizdiai io ms darbo rezultatas yra pateiktas 4.2 paveiksle, kur parodytas 1 programos stekas.

  • Taigi imokome, kaip reikia nusisti kintamuosius funkcijas, arba kaip nusisti funkcijas kintamj kopijas. Anglikai tai vadinama: sending variable by value (j funkcij siuniama kintamojo vert).

    4.5 Rezultato grinimas argument srae Kai kada norisi, kad funkcija grint ne vien, o kelet reikmi. Pavyz-diui, naudojant kompleksinius kintamuosius, reikia grinti du skaiius reali ir menam kompleksinio skaiiaus dal, o, atliekant veiksmus su masyvais, i vienos funkcijos tenka sisti kitai vis skaii rinkin. Ko-mandos return dka, deja, galima grinti tik vien skaii. Jeigu mes ruoiams j grinti daugiau, tai turime rezultat (o tiksliau informacij apie rezultat) talpinti funkcijos argument sra. Pairsime, kaip tai galima padaryti.

    Tuo tikslu perraysime anksiau aptart dviej funkcij program. Taiau dabar abu kintamuosius ir funkcij perduodam argument a, ir funkcijos grinam vert b patalpinsime argument srae. Kai imoksime grinti vien kintamj argument srae, galsime ten j pa-talpinti ir daugiau. Si nauja programa, matyt, turt atrodyti taip: / /

    void two(int a, int b ) ;

    / / int main()

    int a, b;

    c l r s c r ( ) ; a = 3; two(a, b ) ; pr int f ("A = '/.d 2*A = 7.d\n", a, b ) ; getchO ;

    return 0;

    / / void two Cint a, int b)

  • b = 2 * a;

    Joje yra panaudota kitokia two funkcija. Jos argument srae yra du kintamieji siuniamas kintamasis a ir rezultatas b. Matome, kad funkcija two(a,b) nieko nebeturi grinti j ikvietusiai main funkcijai, nes ji pati priskiria kitamajam b dvigub argumento a vert. Todl ji yra deklaruojama, kaip void (tuia) funkcija. Fortran'e ar Basic'e tokie program gabaliukai yra vadinami paprogrammis (subroutine). C kalboje paprogrami nra. Viskas ia vadinama funkcijomis.

    Programa atrodo puikiai. Pabandysime j kompiliuoti. Klaid nra, programa veikia. Taiau ekrane matome

    A = 3 2*A = 3

    ir suprantame, kad suskaiiuotas rezultatas yra klaidingas. Funkcija two nedvigubina argumento a verts.

    Nordami surasti klaid, vl naudojame BorlandC derintoj. Vl spau-dome F7 klavi, vykdome po vien komand ir kontroliuojame visus pro-gramoje naudojamus kintamuosius.

    Mes matome, kad funkcija two (a ,b ) yra teisinga. Ji dvigubina argu-ment a ir priskiria t gaut reikm kitam kintamajam b, visai taip, kaip mes ir norjome. Taiau problema yra ta, kad ji dvigubina ne t kintamj. Atkreip dmes kintamj adresus, matome, kad ms programoje, kaip jau buvo minta, yra du kintamj komplektai, priklausantys main ir two funkcijoms. Perduodami funkcijai two argumentai yra tik main funkcijos kintamj kopijos. Funkcija two siningai priskiria savo kintamajam b (kur atsirado main funkcijos kintamojo b kopija) padvigubinto a kinta-mojo reikm. O juk mes norime, kad ji padvigubint pat main funkcijos b kintamj.

    Kaip isprsti it i pirmo vilgsnio toki sudting problem? Spren-dim rasime, prisimin analogik atvej i ms gyvenimo. Manykime, kad a esu main funkcijos analogas ir noriu, kad Jonas (imituojantis two funkcij) nunet mano draugui Petrui (kintamasis b) laik (kintamj a). Turbt jums akivaizdu, kad aidimas vykdomas su dviem kintamaisiais (Petru ir laiku), kaip tai buvo daroma ms analizuojamoje programoje. Abu tuos kintamuosius reikia perduoti funkcijai (Jonui). Sutinkamai su C filosofija, bandysime perduoti Jonui t kintamj kopijas. Su laiku problem nra. Galima sisti laiko kopij, nes juk yra moni, kurie

  • mgsta originalus pasilikti atminiai. Taiau, pagalvoj apie Petro kopij, matome, kad ia kakas ne taip. Laik juk reikia perduoti tikram gyvam Petrui, o ne kakokiai jo kopijai.

    Mes juk inome, kaip i paini problem isprsti. Nereikia Jonui joki Petro kopij. Jonui reikia inoti Petro adres (!), kad jis galt pas jj nueiti ir nuneti laik.

    Taigi mes pamatme ms darom klaid ir galime suformuluoti toki taisykl:

    Jeigu norime, kad funkcija pakeist kokio nors kintamojo reik-m, tai nereikia to kintamojo sisti funkcijai. Funkcijai reikia nusisti to kintamojo adres.

    Vadinasi, turime imokti susirasti kintamojo adres, kur mes jau susi-tarme vadinti kintamojo rodykle (pointer).

    4.6 Kintamieji ir j rodykls Kaip surasti kintamojo rodykl arba kintamj pagal rodykl paaiks, pavelgus 4.1 lentel

    4.1 lentel. Kintamasis ir jo rodykl.

    kintamasis rodykl X &x

    * p P

    tai ia verta prisiminti 14 bei 20 puslapiuose aptartas dutes. Manykime, kad C bei C + + kalbose kintamieji taip pat yra duts, kaip parodyta 4.3 paveiksle. Jeigu dut yra dedamas kintamasis x, tai ant tos duts automatikai uraomas adresas &x (kintamojo rodykl). O jeigu turime dut, ant kurios uraytas adresas p, tai j galima dti kintamj *p.

    Atkreipkite dmes, kad kintamieji C kalboje (pav. 2.2) ir asembleryje (pav. 4.3) iek tiek skiriasi. Jeigu asembleryje kintamojo vardas cats yra uraomas ant duts, tai C bei C + + kalbose kintamasis yra dtas pai dut. Visa tai verta prisiminti, kai, pasitelk asembler norsime isiaikinti subtilias klaidas C bei C + + programoje, jeigu jos pasitaikyt.

  • Sx P

    X *P

    4.3 pav. C ir C + + kintamieji.

    Pagal i paprast taisykl turime pakeisti 49 puslapyje pateikt pro-gram taip:

    Programa 2

    // Kintamojo adreso siuntimas

    #include #incIude / / void two(int , int *py); Il int mainO {

    int a, b;

    clrscr(); a = 3; two(a, &b); printf ("A = '/.d 2*A = 7,d\n", a, b); getchO ;

    return 0; > / / void two(int , int *py) {

    *py = 2 * x; >

    Dabar programa veikia ir urao ekrane teising padvigubint rezultat. Atkreipsime dmes du svarbius dalykus. Funkcijoje main, kreip-

    damiesi funkcij two, siuniame jai kintamj a ir kintamojo b adres (jo rodykl &b). Funkcija two padvigubint kintamojo reikm priski-

  • ria kintamajam, kur rodo rodykl py. Atkreipkime dmes tai, kaip argument srae yra deklaruojama pati rodykl. C kalboje nra spe-cialaus odio rodyklei deklaruoti. Todl i pradi vaigds (*) pagalba i rodykls padaromas kintamasis, ir tik po to deklaruojamas to kintamojo tipas. Faktikai deklaruojama, kad i rodykls py padarytas kintamasis bus int tipo. Vadinasi, py yra rodykl int tipo kintamj. Praome to neumirti.

    i kintamojo perdavimo funkcij procedr bt logika pavadinti kintamojo rodykls siuntimu funkcij. Anglikai tai vadinama: sending variable by pointer.

    4.7 Kintamojo siuntimas nuoroda Mes imokome, kaip nusisti funkcij kitamuosius tiesiogiai arba ro-dykls pagalba. Pastarj siuntimo metod btina naudoti tuomet, kai norime pakeisti siunianios funkcijos kintamj. is aidimas su rodyk-lmis atrodo iek tiek keistai ir nelabai patraukliai. Todl C + + kalboje galima taikyti dar vien, lengviau simintin, kintamj persiuntimo bd

    kintamojo siuntim nuoroda (sending variable by reference). Jis yra iliustruojamas toliau pateikiamame vis dar tos paios programos variante.

    Programa 3

    // Kintamojo siuntimas nuoroda

    ifinclude #include

    / / void two(int , intfe y);

    / / int mainO {

    int a, b;

    clrscr () ; a = 3; two(a,b); printf ("A = '/.d 2*A = '/.d\n", a, b);

  • getchO ;

    return 0; > / / void two(int , int& ) {

    = 2 * ;

    }

    domu, kad ita programa beveik nesiskiria nuo 49 puslapyje esanios neteisingos programos. Vienintelis skirtumas yra tas, kad funkcijos two de-klaracijoje prie kintamojo y yra priraytas papildomas & simbolis. Tiems, kurie esat moksi programuoti Pascal'iu, pasakysiu, kad is simbolis yra ten vartojamo odelio var analogas. io simbolio panaudojim deklaruo-jant kintamj galime suprasti taip. Nors programoje raome taip tarsi funkcij sistume pat kintamj, kompiliatorius pakeiia j pagal tik k aptart rodykls perdavimo mechanizm. Tuo galima sitikinti, sugretinus program 2 bei 3 asemblerio kodus.

    Ritamj siuntim funkcijas rodykle ar nuoroda reikia naudoti sai-kingai, nes ne visada verta suteikti funkc