Professional Documents
Culture Documents
INFORMATIKA
Programavimas C++ kalba
Mokymo priemon
Vilnius - 2009
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Turinys
VADAS .......................................................................................................................................5 i. Bendrieji informatikos klausimai .................................................................................5 ii. Trumpai apie kompiuteri programin rang. C++ program apdorojimo etapai ............................................................................6 iii. Apie mokymo priemon ................................................................................................7 1. C++ programos struktra ..................................................................................................8 2. Kintamieji. Duomen tipai ................................................................................................11 2.1. Vardai (identifikatoriai) .............................................................................................11 2.2. Pagrindiniai duomen tipai ......................................................................................11 2.3. Kintamj skelbimas .................................................................................................12 2.4. Kintamj galiojimo sritis .........................................................................................12 2.5. Kintamj inicializacija.............................................................................................13 2.6. Paintis su simboli eilutmis ..................................................................................13 3. Konstantos ............................................................................................................................15 3.1. Konstant tipai ............................................................................................................15 3.2. Apibrtosios konstantos ( #define )......................................................................17 3.3. Paskelbtosios konstantos ( const )...........................................................................18 4. Operatoriai ...........................................................................................................................19 4.1. Priskyrimo operatorius ( = ) .....................................................................................19 4.2. Aritmetiniai operatoriai ( + , - , * , / , % ) ................................................................20 4.3. Sudtiniai priskyrimo operatoriai ( += , -= , *= , /= , %= , >>= , <<= , &= , ^= , |= ) ............................................................................................................20 4.4. Reikms didinimo ir mainimo operatoriai ( ++ , -- ) ........................................21 4.5. Palyginimo operatoriai ( == , != , > , < , >= , <= ) ..........................................22 4.6. Loginiai operatoriai ( ! , &&, | ) ................................................................................23 4.7. Slygos operatorius ( ? ) ............................................................................................24 4.8. Kablelio operatorius ( , ) ............................................................................................24 4.9. Bit operatoriai ( & , | , ^ , ~ , << , >> ) .............................................................25 4.10. Aikiai nurodomi duomens tipo keitimo operatoriai ..........................................25 4.11. Operatorius sizeof() ................................................................................................25 4.12. Kiti operatoriai ..........................................................................................................26 4.13. Operatori pirmumo lygiai .....................................................................................26 5. Pagrindinis duomen vedimas/ivedimas .....................................................................28 5.1. Standartinis ivedimas ( cout ) ................................................................................28 5.2. Standartinis vedimas ( cin ).....................................................................................30 5.3. cin ir simboli eiluts ................................................................................................31 5.4. stringstream funkcija ..............................................................................................32 2
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
5.5. Duomen vedimo/ivedimo funkcijos printf ir scanf ........................................33 5.6. Darbas su duomen failais........................................................................................36 6. Valdantieji sakiniai .............................................................................................................40 6.1. Slygos sakinys: if ir else .........................................................................................40 6.2. Ciklai ( while, do-while, for ) ..................................................................................41 6.3. Perokimo sakiniai ( break, continue, goto, exit() ) .........................................44 6.4. Variantinis sakinys ( switch )...................................................................................46 6.5. Paprast program pavyzdiai.................................................................................47 7. Funkcijos ..............................................................................................................................53 7.1. void tipo funkcijos .....................................................................................................55 7.2. Argument reikmi ir adres perdavimas parametrams ...................................56 7.3. Numatytj reikmi parametrai ............................................................................58 7.4. Funkcijos vienodais vardais......................................................................................59 7.5. Funkcij ablonai ( template ) ................................................................................59 7.6. inline funkcijos ..........................................................................................................62 7.7. Rekursijos ....................................................................................................................62 7.8. Funkcij skelbimas ....................................................................................................63 8. Masyvai ................................................................................................................................66 8.1. Masyv inicializacija .................................................................................................66 8.2. Kreipimasis masyvo elementus ..............................................................................67 8.3. Daugiamaiai masyvai ..............................................................................................68 8.4. Masyvai kaip funkcij parametrai ...........................................................................69 8.5. Program su masyvais pavyzdiai ...........................................................................71 9. Simboli sekos .....................................................................................................................75 9.1. Simboli sek inicializacija ......................................................................................75 9.2. Simboli sek naudojimas ........................................................................................76 10. Rodykls (pointers) ...........................................................................................................78 10.1. Adreso operatorius ( & ) ..........................................................................................78 10.2. Duomens nurodytu adresu operatorius ( * ) ........................................................79 10.3. Rodykls tipo kintamj paskelbimas ..................................................................80 10.4. Rodykls ir masyvai .................................................................................................81 10.5. Rodykli inicializacija .............................................................................................82 10.6. Rodykli aritmetika ..................................................................................................83 10.7. Rodykli rodykls .....................................................................................................84 10.8. void rodykls............................................................................................................85 10.9. null rodykl ..............................................................................................................86 10.10. Funkcij rodykls ...................................................................................................86 11. Dinamin atmintis ............................................................................................................88 11.1. Operatoriai new ir new[ ] .....................................................................................88 3
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
11.2. Operatoriai delete ir delete[ ] .............................................................................89 11.3. Dinamin atmintis ANSI-C++ standarte ............................................................91 12. Duomen struktros .........................................................................................................92 12.1. Duomen struktros ................................................................................................92 12.2. Struktr rodykls....................................................................................................95 12.3. Struktros struktrose .............................................................................................97 12.4. Dinamins duomen struktros: sraai, mediai ir kita ..................................97 13. Kiti duomen tipai .......................................................................................................... 102 13.1. Apibrtieji duomen tipai ( typedef )............................................................... 102 13.2. Bendrosios atminties sritys ( union ) .................................................................. 102 13.3. Bevards bendrosios atminties sritys union ...................................................... 104 13.4. Ivardijimai ( enum ) ............................................................................................. 105 14. Klass ir objektai ............................................................................................................. 106 14.1. Konstruktoriai ir destruktoriai .............................................................................. 109 14.2. Klass su keliais konstruktoriais .......................................................................... 111 14.3. Numatytasis ( default ) konstruktorius ............................................................... 112 14.4. Klasi rodykls ....................................................................................................... 113 14.5. Klasi skelbimas naudojant struct ir union ..................................................... 114 14.6. static nariai klasse.............................................................................................. 115 14.7. Klasi ablonai ( template ) ............................................................................... 116 15. Draugikumas ir paveldimumas ................................................................................... 118 15.1. Draugikosios funkcijos ( friend ) ....................................................................... 118 15.2. Draugikosios klass.............................................................................................. 119 15.3. Klasi paveldimumas ............................................................................................ 120 15.4. Kas nepaveldima i bazins klass? .................................................................... 123 15.5. Daugeriopas paveldimumas ................................................................................. 123 16. Polimorfizmas .................................................................................................................. 125 16.1. Bazini klasi rodykls ......................................................................................... 125 16.2. Virtuals klasi nariai ........................................................................................... 126 16.3. Abstrakiosios bazins klass ............................................................................... 128 17. Dar apie duomen fail vedim/ivedim ................................................................. 133 17.1. vedimo/ivedimo funkcijos read() ir write() ................................................... 133 17.2. vedimo/ivedimo funkcijos fscanf(), fprintf() ir kitos ................................... 134 altiniai ................................................................................................................................... 139 Priedas. C++ standartins bibliotekos. ............................................................................ 140
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
VADAS
i. Bendrieji informatikos klausimai
Kas yra informacija? Skaiiai, tekstai, garsai, vaizdai, kt. Informacijos perdavimo bdai: knygos, telefonas, radijas, televizija, kompiuteri tinklai (einama link viskam bendro duomen perdavimo tinklo). Problema - kryptingas informacijos apdorojimas: j reikia dlioti (kaupti) taip, kad galtume greiiausiai susirasti mums reikaling informacij (rikiavimas pagal autoriaus pavard, mokslo sritis, bazinius odius, kt.); kompaktikas saugojimas, greitas perdavimas. Informatika - mokslas apie informacijos apdorojimo metodus, informacijos technologijas, kompiuteri aparatins ir programins rangos krim, kt. Kompiuteri istorija: j kartos, universals ir specializuoti, skaitmeniniai ir analoginiai. Kompiuterio struktra: rengini paskirtis, ryiai tarp j, kompiuteri architektra. IBM PC sudtis, rengini charakteristikos. Duomen vaizdavimas kompiuteriuose: 2 (dvejetain) skaiiavimo sistema ir jos vartojimo prieastys. Ryys tarp 2 skai. sist. ir 10 skai. sist. Apie 8 skai. sist. ir 16 skai. sist., kodl j prireik. Skaii vaizdavimas fiksuotu ir slankiu kableliu. Simboliai ir j kodavimas. Programinis kompiuteri valdymo principas. Programa - tai mainini komand seka. Mainins komandos struktra. Algoritmas: kokie veiksmai ir kokia eils tvarka jie turi bti atlikti, norint isprsti kakok udavin. Nuosekli veiksm seka. Programavimo automatizavimas: operacins sistemos, programavimo kalbos, program paketai ir t.t. Komandin ir grafin sveikos: dialogo tarp mogaus ir kompiuterio palaikymo bdai. Pvz., MS DOS aplinka, NORTON COMMANDER, WINDOWS, LINUX. Danai sutinkama santrumpa GUI Graphic User Interface (grafin vartotojo sveika). Informatikos standartai: susitarimai laikytis vienodos tvarkos, taisykli. Pvz., OSI (Open System Interconnection) modelis - tai standart rinkinys, kurio reikia laikytis, kad skirting ri kompiuteriai galt palaikyti ry; protokolai - standart rinkiniai, kuri laikomasi perduodant duomenis kompiuteri tinklais. ISO tarptautin standartizacijos organizacija; yra ir kitos: CEN, ETSI, t.t.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ii. Trumpai apie kompiuteri programin rang. C++ program apdorojimo etapai
Operacin sistema (OS) - tai gatav program rinkinys, padedantis vartotojui priirti bei eksploatuoti kompiuter. Kompiuteri gamintojai, programins rangos krjai pateikia vartotojams OS urayt diske, pastoviojoje atmintyje, kt. Pvz., MS DOS, jo komponents BIOS, COMMAND.COM, AUTOEXEC.BAT, tvarkykls (draiveriai), NORTON COMMANDER; WINDOWS; UNIX; LINUX ir t.t. vairiems darbams palengvinti yra kuriama pagalbin programin ranga (programavimo kalb kompiliatoriai, duomen bazi valdymo sistemos, tekst rengimo, elektroninio pato, narymo po internet programos, kt.). ia akcentuosime tik tuos komponentus, kurie reikalingi programuojant C++ kalba. C++ kalba parayta programa - tai tekstas i vairi simboli. Pirmas udavinys mogui yra perkelti tokios programos tekst kompiuterio atmint. iam tikslui gali bti panaudota pagalbin programa - tekst rengykl (EDIT, KEDIT, NOTEPAD ar kt.; plaiai inomas WORD iems tikslams netinka). Programos tekstas turi bti uraytas fail, kurio vardo pltinys yra .c arba .cpp (pvz., abc.c arba abc.cpp). Tekst rengykli teikiamos paslaugos yra labai plaios: terpti ar itrinti simbol, eilut, perkelti teksto dal i vienos vietos kit, kopijuoti, kt. Kadangi kompiuteris gali veikti tik pagal maininmis komandomis ireikt program, todl btinas antras etapas. Jo metu vesta kompiuterio atmint teksto pavidalo C++ programa, kuri vadinama programos pradiniu moduliu (.cpp), pertvarkoma mainini komand pavidal. T atlieka kita pagalbin programa C++ kompiliatorius. Jei kompiliatorius aptiko klaid C++ programos pradiniame modulyje, reikia grti pirmj etap, tekst rengykle itaisyti program ir vl kompiliuoti j. Kompiliavimo ir redagavimo metu gaunama vykdymui parengta vartotojo programa mainine kalba - vykdomasis modulis (.exe). Pertvarkius C++ program mainin pavidal (suformavus programos kod), belieka j vykdyti. Netgi kompiuteriui dirbant pagal vartotojo sudaryt program, proces gali siterpti OS. Yra sukurtos integruotosios programavimo sistemos arba aplinkos (IDE Integrated Development Environment), kuriose galima atlikti vis aukiau mint pagalbini program veiksmus.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Sveiki gyvi!
Preprocesorius programoje sutiks nuorod #include (ji raoma atskiroje eilutje), programos tekst stato vis nurodyto failo turin:
#include "failo_vardas" #include <failo_vardas>
i dviej nuorod skirtumas yra toks, kad kompiliatorius ieko nurodyto failo skirtinguose disko kataloguose. Kai failo_vardas yra apkabintas dvigubomis kabutmis,
8
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
kompiliatorius vis pirma failo ieko tame kataloge, kuriame yra #include nuorod turinti programa. iame kataloge neradus nurodyto failo, paieka tsiama numatytajame (default) kataloge, kuris konfigruojant kompiliatori buvo paskirtas standartini (gatav) bibliotek failams. Jei failo_vardas yra apskliaustas enklais < ir >, jo iekoma tik kataloge, kuris paskirtas standartini bibliotek failams. alia standartini bibliotek fail programuotojai gali susikurti asmenini bibliotek failus ir #include nuorodomis traukti juos vairias savo programas kai tik to prireikia.
using namespace std; Visi standartinse bibliotekose naudojami elementai yra aprayti vard srae (namespace) std. itokia programos eilute nurodoma, kad norime naudotis to vard srao elementais. Tai daugeliui C++ program, naudojani standartines bibliotekas, reikalingas sakinys. int main () itokia eilute nurodoma programos pagrindins (main) funkcijos pradia. Kiekvienoje C++ programoje turi bti pagrindin funkcija. Nuo jos pradedamas visos programos darbas, nesvarbu kurioje programos pradinio modulio vietoje ji bt parayta. Po main raomi skliaustai (), kurie C++ kalboje nurodo, kad prie juos einantis vardas yra funkcijos, o ne kitokio tipo elemento vardas. Tarp skliaust gali bti nurodomi parametrai. Toliau raomas pagrindins funkcijos programos tekstas turi bti tarp riestini skliaust { }. cout << "Sveiki gyvi!"; i eilut yra C++ kalbos sakinys (angl. statement). Sakinys tai paprasta arba sudtinga iraika, kuria nurodomi konkrets reikiami atlikti veiksmai. cout nurodoma, kad ekran reikia ivesti simboli sek, t.y. tekst Sveiki gyvi! cout programa imama i standartinio failo <iostream>, kurios elementai yra aprayti vard srae std. Todl ioje programoje ir prireik #include <iostream> ir using namespace std; Pastebkime, kad C++ kalboje sakiniai baigiami kabliatakiu. eilui
return 0; return sakiniu baigiamas pagrindins funkcijos darbas. Po jo nurodomas programos baigimo kodas. 0 reikia, kad pagrindin funkcija veik normaliai ir baig darb be klaid. Paprastai C++ programos baigiamos tokiu sakiniu. Kadangi pagrindins funkcijos (main) pradi nurodanioje eilutje yra int, tai baigimo kodas ioje programoje yra nurodytas sveikuoju skaiiumi (integer). Pagrindins funkcijos baigimo kodas gali bti panaudotas organizuoti tolesniam kompiuterio darbui. Kai raoma void main() arba tik main(), tai pagrindin funkcija jokio baigimo kodo negrina ir return sakinys nereikalingas.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Atkreipkime dmes tai, kad ne visos programos eiluts iaukia konkreius veiksmus vykdant sukompiliuot program. Dalis i j yra tik paaikinimai (pvz.,
Sveiki gyvi!
10
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
11
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int
signed: nuo -2147483648 iki 2147483647 unsigned: nuo 0 iki 4294967295 signed: nuo -2147483648 iki 2147483647 0 iki 4294967295 unsigned: nuo true arba false 3.4e +/- 38 1.7e +/- 308 1.7e +/- 308 (mantisje - 7 skaitmenys) (mantisje - 15 skaitmen) (mantisje - 15 skaitmen)
1 4 8 8 2
platusis simbolis
Pastaba: skirtinguose kompiliatoriuose duomen tipai gali bti realizuoti skirtingai, t.y. gali skirtis ioje lentelje nurodyti reikmi diapazonai, uimamos atminties dydis.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
#include <iostream> using namespace std; int a; char r; unsigned int c; int main () { int metai; float ada; cout << Kiek jums metu?; cin >> metai; return 0; } globaliuosius kintamuosius galima kreiptis i bet kurios programos vietos, einanios po i kintamj paskelbimo. Lokalij kintamj galiojimo sritis yra apribota riestiniais skliaustais {} , ir juos galima kreiptis nuo paskelbimo vietos iki udaranio riestinio skliausto. // // lokalieji kintamieji // // globalieji kintamieji //
13
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// pirmas simboli eiluts pavyzdys #include <iostream> #include <string> using namespace std; int main () { string se = "Tai eilute"; // skelbiama ir inicializuojama eilute cout << se; return 0; } Skelbimo metu eilui tipo kintamiesiems, kaip ir skaitiniams kintamiesiems, pradins reikms gali bti suteiktos dviem bdais. Pvz., string se = "Tai eilute"; string se ("Tai eilute"); Jeigu skelbiant eilut pradin reikm jai nesuteikiama, tai, kaip ir kitokiems kintamiesiems, reikm gali bti suteikiama programos bgyje priskyrimo operatoriumi. Pvz., // programos su eilute pavyzdys #include <iostream> #include <string> using namespace std; int main () { string se; se = "Tai pirma eilutes reiksme"; // priskyrimo sakinys cout << se << endl; se = "Cia jau kita eilutei suteikiama reiksme "; cout << se << endl; return 0; } Tai eilute
14
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
3. Konstantos
Konstanta tai iraika, kurios reikm ilieka tokia pati vis programos darbo laik.
ia parodytos trys deimtaini skaii konstantos. Sveikj skaii konstantos gali bti raomos ir atuntaine arba eioliktaine skaiiavimo sistema. Atuntainio skaiiaus pradioje raomas 0 (nulis), o eioliktainio 0x (nulis ir x). 75 0113 0x4b // deimtainis skaiius // atuntainis // eioliktainis
iame pavyzdyje vis trij konstant reikms yra vienodos, tik jos uraytos skirtingomis skaiiavimo sistemomis. Kaip ir int tipo kintamieji, taip ir sveikj skaii konstantos gali turti poymius unsigned ir long. Jie nurodomi raidmis u ir l skaiiaus gale. u ir l gali bti maosios arba didiosios. 75 75u 75L 75ul // int tipo konstanta // unsigned int // long // unsigned long
Slankaus kablelio skaiiai. Tai deimtainiai skaiiai, turintys ir trupmenin dal. Jie gali bti raomi dvejopai: naudojant tak trupmeninei daliai atskirti nuo sveikosios arba naudojant eksponentin pavidal, t.y. su raide e. 3.14159 6.02e23 1.6e-19 3.0 // 3.14159 // 6.02 padauginta i 10, pakeltos 23 laipsniu // 1.6 padauginta i 10, pakeltos -19 laipsniu // 3.0
15
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Nesant papildom nurodym slankaus kablelio konstantos yra double tipo. Norint turti float arba long double tipo konstant, jos gale reikia rayti raid f arba l. iose konstantose raids e, f ir l gali bti maosios arba didiosios. 3.14159L 6.02E23f // long double tipo konstanta // float
Simbolis ir eilut. 'z' "Sveiki gyvi" // simbolio konstanta, char tipo // simboli eiluts konstanta, string tipo
Simbolio tipo (char) konstantos raomos tarp viengub kabui, o eilui tipo (string) konstantos - tarp dvigub kabui. Atkreipkime dmes iuos du uraus: x 'x'
Uraas x reikia kintamojo vard, o uraas 'x' simbolio konstant. Kai kurie simboliai turi tam tikr ypatum, kaip, pvz., valdantieji simboliai (kai kuriuos atitinka klaviai, pvz., Enter, Tab, kt.). Tai specials simboliai, kuriuos sunku arba nemanoma pavaizduoti programos tekste. Todl valdantieji simboliai vaizduojami j pradioje raant atgal pasvirus brkn ( \ ) ir po to vien kok nors kit simbol. tai valdanij simboli sraas: Valdantysis simbolis \n \r \t \v \b \f \a \' \" \? \\ Reikm pereiti kitos eiluts pradi (pvz., Enter klavias) grti tos paios eiluts pradi (Home klavias) tabuliacija (Tab klavias) vertikali tabuliacija (spausdintuvams valdyti) grti per vien pozicij (Backspace klavias) form feed (spausdintuvams valdyti) perspjimo signalas (pypteljimas) vienguba kabut ( ' ) dviguba kabut ( " ) klaustukas ( ? ) atgal pasvirs brknys ( \ )
16
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Konstant su valdaniaisiais simboliais pavyzdiai: '\n' '\t' "Kaire \t Desine" "vienas\ndu\ntrys" Taip pat bet kur simbol galima nurodyti jo skaitiniu ASCII kodu, prie j raant atgal pasvirus brkn. Kodas gali bti uraytas tik atuntainiu arba eioliktainiu skaiiumi. Atuntainis kodas raomas tuoj po brknio, pvz., \25 , o eioliktainis kodas dar turi x , pvz., \x4A . Simboli eiluts konstanta gali bti raoma keliose i eils einaniose puslapio eilutse. Pereinant kit puslapio eilut raomas atgal pasvirs brknys. Pvz., "simboliu eilute uzrasyta dviejose \ puslapio eilutese" Keletas eilui, tarp kuri yra tarpai, tabuliacija (buvo paspaustas klavias tab) ar perjimas nauj puslapio eilut (enter), yra sukabinamos ir reikia vien ilg eilut. Pvz., "Tai yra" "viena ilga" "simboliu eilute."
Jei norime turti eilut i plaij simboli wchar_t (t.y. simboli, kuriems atmintyje skiriama po 2 baitus), jos priekyje raoma raid L. Pvz., L"Tai placiuju simboliu eilute" Logins konstantos. Tai bool tipo reikms. Jos uraomos odiais true ir false .
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Pvz., #define PI 3.14159265 #define bruksnys \n------------\n Taip gavome dvi naujas apibrtsias konstantas: PI ir bruksnys. iuos vardus galima naudoti programoje kaip ir bet kuri prast konstant. Pvz., // apibrtosios konstantos programoje // apskritimo ilgiui skaiiuoti #include <iostream> using namespace std; #define PI 3.14159 #define bruksnys \n------------\n int main () { double r = 5.0; double apskrilgis; apskrilgis = 2 * PI * r; cout << apskrilgis; cout << bruksnys; return 0; } #define yra preprocesoriaus nuoroda, o ne C++ kalbos sakinys. Todl jos gale kabliatakis nededamas. // spindulys
31.4159
----------
18
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
4. Operatoriai
Kadangi jau susipainome su kintamaisiais ir konstantomis, inagrinkime galimus veiksmus su jais. Veiksmai C++ kalboje nurodomi operatoriais. Operatorius tai kakoks simbolis arba j derinys, kuriuo nurodoma atlikti kakok veiksm.
a=4 b=7
return 0; } ios programos rezultatas yra toks: kintamojo a reikm yra 4, o kintamojo b 7. Pastebkime, kad keiiant b reikm, kintamojo a reikm nekinta.
19
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
C++ kalbos ypatyb, lyginant j su kitomis programavimo kalbomis, yra ta, kad priskyrimo operacija gali bti atliekama ir priskyrimo operatoriaus deinje pusje. Pvz., a = 2 + (b = 5); Tai ekvivalentika tokiems dviems priskyrimo sakiniams: b = 5; a = 2 + b; Tai reikia, kad vis pirma kintamajam b priskiriama reikm 5, o po to, prie ios reikms pridjus 2, gauta suma 7 priskiriama kintamajam a. C++ kalboje taip pat yra teisinga tokia iraika: a = b = c = 5; iuo sakiniu reikm 5 priskiriama visiems trims kintamiesiems a, b ir c.
Sudties, atimties, daugybos ir dalybos operacijos visikai atitinka matematikoje naudojamas operacijas. Tik operatorius dviej sveikj skaii dalybos liekanai gauti yra ymimas procento enklu. Pvz., jeigu uraysime: a = 11 % 3; tai kintamasis a gis reikm 2, kadangi tai yra skaiiaus 11 padalinto i 3 dalybos liekana.
20
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Tas pats galioja ir visiems kitiems ( % , >> , << , & , ^ , | ) operatoriams. Programos pavyzdys: // sudtinis priskyrimas #include <iostream> using namespace std; int main () { int a, b=3; a = b; a += 2; cout << a; return 0; }
// ekvivalentika a=a+2 5
atliekamos funkcijos yra ekvivalentikos. Visi jie kintamojo c reikm padidina vienetu. ie operatoriai gali bti raomi prie kintamojo vard arba po jo. Paprastos iraikos, kaip a++ arba ++a , duoda t pat rezultat. Taiau sudtingesnse iraikose, ++ ar -- raymas prie ir po kintamojo vardo turi svarb skirtum. Pvz., raant ++a , kintamojo a reikm vis pirma padidinama vienetu ir po to naudojama sudtingoje iraikoje, o raant a++ , sudtingoje iraikoje naudojama turima a reikm ir tik po to ji didinama vienetu. Atkreipkime dmes skirtum iuose pavyzdiuose:
21
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
2 pavyzdys
// A reikm - 3, B reikm - 4
1 pavyzdyje B reikm vis pirma padidinama vienetu ir po to priskiriama kintamajam A, o 2 pavyzdyje B turima reikm vis pirma priskiriama kintamajam A
Vietoje ia palyginam skaitini konstant, inoma, gali bti bet kokios leistinos iraikos arba kintamieji. Tarkime, kad a=2, b=3 ir c=6. Todl:
(a == 5) (a*b >= c) (b+4 > a*c) ((b=2) == a) // rezultatas false, nes 2 nelygu 5 // true, ( 2*3 >= 6 ) // false, ( 3+4 > 2*6 ) // true
Bkime atids! Operatorius = (vienas lygybs enklas) nra tas pat, kaip operatorius == (du lygybs enklai). Pirmasis yra priskyrimo operatorius, o antrasis palyginimo. Todl paskutin iraika ((b=2) == a) skaiiuojama taip: vis pirma 2 priskiriamas kintamajam b , o po to i reikm palyginama su kintamojo a reikme. Taigi, rezultatas yra true.
22
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Operatoriumi && (du simboliai &) nurodoma login operacija IR (anglikai AND). Jos rezultatas yra true tik tada, kai abiej operand reikms yra true. a true true false false b true false true false a && b true false false false
Operatoriumi || (du vertikals brkniai) nurodoma login operacija ARBA (anglikai OR). Jos rezultatas yra true, kai bent vieno operando reikm yra true. a true true false false Pavyzdys: ((5 == 5) && (3 > 6)) ((5 == 5) || (3 > 6)) // rezultatas false // true (true && false) (true || false) b true false true false a || b true true true false
23
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// Programos su slygos operatoriumi pavyzdys #include <iostream> using namespace std; int main () { int a,b,c; a=2; b=7; c = (a>b) ? a : b; cout << c; return 0; }
// c gis reikm 7 7
24
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
~ << >>
25
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
iuo sakiniu kintamajam a bus priskirtas 1, nes char tipo kintamajam atmintyje skiriamas tik vienas baitas. sizeof grainamas dydis yra konstanta, kuri visada bna apibrta prie vykdant program.
Teisingas atsakymas yra 6, t.y. pirmos i i dviej iraik rezultatas. Yra nustatyti ne tik aritmetini, bet ir kiekvieno C++ kalboje sutinkamo operatoriaus pirmumo lygiai (prioritetai). Operatori pirmumo lygiai, pradedant aukiausiu ir baigiant emiausiu, yra ie: Pirmumo lygis
1
Operatorius
::
(du dvitakiai)
I kairs dein
Vieno operando, raomi prie vard (prefix) Netiesioginiai ir nuorodos (pointers) Operando enklo operatoriai 26 I deins kair
* +
& -
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
4 5 6 7 8 9 10 11 12 13 14 15 16
(type) .* * / ->* %
I deins kair I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I kairs dein I deins kair I deins kair I kairs dein
Postmio Palyginimo Palyginimo Loginio IR su bitais Loginio grietojo-ARBA su bitais Loginio ARBA su bitais Loginio IR Loginio ARBA Slygos
17
18
ios lentels stulpelyje Atlikimo iraikoje kryptis nurodoma tokio paties pirmumo lygio operatori atlikimo tvarka, jei iraikoje paeiliui j yra keletas. Taigi, raydami sudtingas iraikas ir nebdami tikri dl operatori pirmumo lygio, dkime skliaustus. Tokias iraikas yra lengviau skaityti.
27
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Viename ivedimo sakinyje operatorius << gali bti naudojamas kelet kart: cout << "Tai yra " << "C++ kalbos" << " isvedimo sakinys."; iuo sakiniu monitoriaus ekran bus ivestas tekstas: Tai yra C++ kalbos isvedimo sakinys. Imkime dar vien pavyzd, kuriuo ekran ivedama eilui ir kintamj reikmi kombinacija arba keli kintamj reikms: 28
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
cout << "Labas. Man " << amzius << " metai, " << "o mano ugis yra " << ugis << " cm."; Tarkime, kad kintamojo amzius reikm yra 24, o kintamojo ugis 195. Tuomet iuo sakiniu bus ivesta: Labas. Man 24 metai, o mano ugis yra 195 cm. Atkreipkime dmes, kad cout sakiniu ivedant duomenis nepereinama nauj eilut tol, kol aikiai to nenurodysime. Todl iais dviem sakiniais cout << "Tai yra pirmas sakinys."; cout << "Tai jau kitas sakinys."; duomenys bus ivedami vien eilut ir atrodys taip: Tai yra pirmas sakinys. Tai jau kitas sakinys. Rezultatai ivedami kelias eilutes tada, kai cout sakinyje yra aiks nurodymai. iam tikslui gali bti panaudotas specialus perjimo nauj eilut simbolis \n. Pvz., sakiniais cout << "Pirma teksto eilute.\n "; cout << "Antra eilute.\nTrecia eilute."; gausime tok rezultat ekrane: Pirma teksto eilute. Antra eilute. Trecia eilute. Pereiti nauj eilut galima ir panaudojus manipuliatori endl. Pvz.: cout << "Pirmas sakinys." << endl; cout << "Antras sakinys." << endl; ie du cout sakiniai rezultatus ives dvi atskiras eilutes: Pirmas sakinys. Antras sakinys. endl manipuliatoriaus ir specialaus perjimo nauj eilut simbolio \n skirtumas pasireikia srautuose, naudojaniuose ivedimo buferius: endl ivalo bufer. Neirint to, \n ir endl gali bti naudojami nedarant tarp j skirtumo. Ivedam rezultat formatui nustatyti naudojami standartiniame <iomanip> faile saugomi manipuliatoriai. tai du i j: setw(m), m lauko plotis reikmei ivesti; setprecision(n), n skaitmen skaiius ivedamoje reikmje. Jei setw nurodyto lauko ploio skaiiui ivesti nepakanka, is manipuliatorius ignoruojamas. Manipuliatorius setw galioja tik artimiausiai ivedamai reikmei, o setprecision iki naujo nurodymo.
29
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
emiau
pateiktoje
programoje
iliustruojamas
manipuliatori
setw
ir
setprecision veikimas: // manipuliatori setw ir setprecision naudojimas #include <iostream> // i ia ima cout #include <iomanip> using namespace std; int main() { float A = 378.236; cout << "0. A=" << A << endl; cout << "1. A=" << setw(9) << A << endl; cout << "2. A=" << setprecision(2)<< A << endl; cout << "3. A=" << setw(10) << setprecision(4) << A << endl; A = 12.345678; cout << "4. A=" << A << endl; return 0; } 0. A=378.236 1. A= 378.236 2. A=3.8e+02 3. A= 378.2 // i ia ima setw ir setprecision
4. A=12.35
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// vedimo/ivedimo pavyzdys #include <iostream> using namespace std; int main () {int i; cout << "Iveskite sveikaji skaiciu: "; cin >> i; Iveskite sveikaji skaiciu: 702 Ivestas skaicius yra
cout << "Ivestas skaicius yra " << i; cout << ", dvigubai didesnis yra " << i*2 << ".\n"; 702, dvigubai didesnis yra 1404. return 0; } Vienu cin sakiniu galima vesti reikmes daugiau kaip vienam kintamajam. cin >> a >> b; Tas pats bt jei raytume cin >> a; cin >> b; iais abiem raymo atvejais reikia vesti dvi reikmes: pirm - kintamajam a, antr kintamajam b. vedamos reikms turi bti atskirtos vienu i bd: tarpo simboliu, tabuliacijos simboliu (klavias tab) arba perjimu nauj eilut (klavias enter).
31
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// cin naudojimas simboli eilutms vesti #include <iostream> #include <string> using namespace std; int main () { string eilut; cout << "Koks jusu vardas ir pavarde? "; getline (cin, eilut); cout << "Labas " << eilut << ".\n"; cout << "Kokiu menu domites? "; getline (cin, eilut); cout << "As irgi domiuosi " << eilut << "!\n"; return 0; } Pastebkime, kad abiejuose kreipiniuose funkcij getline naudojamas tas pats eiluts vardas eilut. Antro kreipinio metu anksiau vesta eilut reikm keiiama naujai vedama. Koks jusu vardas ir pavarde? Jonas Pavardenis Labas Jonas Pavardenis. Kokiu menu domites? Muzika As irgi domiuosi Muzika!
32
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// stringstream naudojimo pavyzdys #include <iostream> #include <string> #include <sstream> using namespace std; int main () { string eilut float kaina=0; int kiekis=0; cout << "Iveskite kaina: "; getline (cin,eilut); stringstream(eilut) >> kaina; cout << "Iveskite kieki: "; getline (cin,eilut); stringstream(eilut) >> kiekis; cout << "Kaina is viso: " << kaina*kiekis << endl; return 0; } iame pavyzdyje standartiniu vedimo bdu skaitins kintamj kaina ir kiekis reikms gaunamos netiesiogiai. getline funkcija, naudodama standartin vedimo sraut cin, vest eilut patalpina kintamajame eilut. Po to stringstream funkcija ir operatorius >> transformuoja vestus simbolius int tipo reikmes (kaina, kiekis). Toks netiesioginis sveikj skaii reikmi vedimas int tipo kintamiesiems suteikia didesnes kontrols galimybes. vedus eilut, galima patikrinti, ar joje yra skaitmenys, ar nra neleistin simboli. Iveskite kaina: 22.25 // i ia ima stringstream
Iveskite kieki: 7
33
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Pastebkime, kad duomen ivedimo funkcijoje printf po ablono nurodomi kintamj vardai, o vedimo funkcijoje scanf - kintamj adresai. Pavyzdiui, jei turime kintamj vardu a, tai jo adresas atmintyje gaunamas uraius &a. ablonas tai simboli eiluts konstanta (ji raoma tarp dvigub kabui) su joje terptais duomen formatais ir valdaniaisiais simboliais. vedamiems/ivedamiems duomenims skiriam lauk struktra arba j interpretavimo bdas nurodomas duomen formatais. Tipin formato struktra yra tokia: % [poymis] [lauko_dydis] [.tikslumas] duomen_tipas ia staiakampiais skliaustais tik nurodoma, kad to formato elemento gali ir nebti. Formate daniausiai naudojami poymiai yra tokie: (minusas) - lygiuoti ivedamus duomenis pagal kairj lauko krat; + (pliusas) - nurodyti ivedamo skaiiaus enkl, net jei jis teigiamas. Jei poymis nenurodomas, ivedama reikm lygiuojama pagal deinj lauko krat, o prie ivedam teigiam skaii pliuso enklas nededamas. Formate duomen_tipai ymimi raidmis, parodytomis ioje lentelje: Duomen tipo raid d arba i o u x c f s e p Duomen tipas sveikasis skaiius (int); atuntainis sveikasis skaiius; sveikasis skaiius be enklo; eioliktainis sveikasis skaiius; simbolis (char); slankaus kablelio skaiius (float); simboli eilut (string); rodyklins formos skaiius (float); rodykl (pointer)
Ivedimo funkcijoje printf valdantieji simboliai gali bti terpiami bet kurioje ablono vietoje. Primename, kad valdaniojo simbolio uraymo sintaks yra \simbolis, pvz., \n , \t ir kt. Jeigu norime ablone turti dvigub kabut (") arba atbulai pasvirus brkn (\), jie turi bti raomi atitinkamai \" ir \\. To prieastis yra ta, kad kabute (") nurodoma eiluts pradia ir pabaiga, o simboliu \ - valdantysis simbolis. Programa, iliustruojanti funkcijos printf veikim: #include <cstdio> using namespace std; int main() { int a = 1023; long int b = 2222; short int c = 123; 34
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
unsigned int d = 1234; char e = X; float f = 3.14159; double g = 3.1415926535898; printf("1. a=%d\n", a); // deimtainis sveikasis printf("2. a=%o\n", a); // atuntainis sveikasis printf("3. a=%x\n", a); // eioliktainis sveikasis printf("4. b=%ld\n", b); // deimtainis ilgas printf("5. d=%u\n", d); // sveikasis be enklo printf("6. e=%c\n", e); // simbolis printf("7. f=%f\n", f); // realusis skaiius printf("8. f=%e\n", c); // realusis su eile printf("\n"); // tik pereiti kit eilut printf("9. a=%7d\n", a); // 7 pozicij laukas printf("10. a=%7d\n", a); // - veda nuo kaires c = 5; d = 8; printf("11. a=%*d\n",c,a); // lauko plotis 5 poz. printf("12. a=%*d\n",d,a); // lauko plotis 8 poz. printf("13. f=%f\n", f); // realusis skaiius printf("14. f=%10f\n", f); // 10 poz. realiam printf("15. f=%10.3f\n", f); // trupmenai 3 p. printf("16. g=%11.8f\n", g); // trupmenai 8 p. printf("17. g=%+11.8f\n", g); // su + printf("18. a=%d g=%5.2f\n", a, g); return 0; } 1. a=1023 2. a=1777 3. a=3ff 4. b=2222 5. d=1234 6. e=X 7. f=3.141590 8. f=3.141590e+000 9. a= 1023 10. a=1023 11. a= 1023 12. a= 1023 13. f=3.141590 14. f= 3.141590 15. f= 3.142 16. g= 3.14159265 17. g=+3.14159265 18. a=1023 g= 3.14
vedimo funkcijos scanf ablone daniausiai nurodomi tik vedam duomen formatai. Paiuose formatuose nurodomas tik duomen tipas. Pvz.: int a; float b; scanf("%d %f", &a, &b); iuo atveju klaviatra vedami nurodyto tipo skaiiai turi bti atskirti tarpu, tabuliacijos simboliu (\t) arba perjimu kit eilut (\n). Pvz., vedus 45 8.56, kintamasis a gis reikm 45, o kintamasis b 8.56. Jei funkcijos scanf ablone prie duomen formatus bus nurodyti kakokie simboliai, tai juos taip pat reiks vesti. Pvz.: scanf("a= %d f= %f", &a, &b); ia klaviatra vedami duomenys turs atrodyti taip: a= 45 f= 8.56 .
35
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
36
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Pastebkime, kad tarp kintamojo-failo vardo ir funkcijos vardo dedamas takas. Taip nurodoma, kur gi fail norime atidaryti ar udaryti, nes programa gali dirbti i karto su keletu fail. Vliau, kai susipainsime su objektinio programavimo pagrindais, matysime, kad ifstream, ofstream atitinka klasi vardus, open(), close() mint klasi nari-funkcij vardus, o failas1 ms paskelbto objekto vard. Pateikiame duomen ivedimo fail itis program: // pagrindins ivedimo fail operacijos #include <iostream> #include <fstream> using namespace std; int main () { ofstream isifa; isifa.open ("c:\\rezult.txt"); isifa << "Sis tekstas rasomas i faila.\n"; isifa.close(); return 0; }
ia ms paskelbtas isifa atitinka mums jau inom standartin cout, ivedant duomenis ekran. Analogikai yra ir su duomen vedimu i failo: // pagrindins vedimo i failo operacijos #include <iostream> #include <fstream> using namespace std; int main () { ifstream ivisfa; int a, b; ivisfa.open ("c:\\duom.txt"); ivisfa >> a >> b; // veda i failo cout << a << "+" << b << "=" << a+b << endl; ivisfa.close(); return 0; }
ioje programoje ivisfa atitinka standartin cin, vedant duomenis klaviatra. ia i failo vest skaii suma ivedama ekran standartiniu cout. Matome, kad prie duomen vedim ar ivedim failai turi bti atidaromi, o baigus darb - udaromi. Failo atidarymo prasm yra ta, kad, pvz., ivedant duomenis 37
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
disk, diske vis pirma turi bti parengta sritis kuriamam failui (kataloge raomas failo vardas, paskiriama jam vieta diske), programai atmintyje papildomai paskiriami laukai, kurie vadinami vedimo/ivedimo buferiais. Udarant fail, pvz., diske uraomas failo pabaigos poymis (jei failas buvo kuriamas), ilaisvinama vedimo/ivedimo buferiams skirta atminties sritis. Panagrinkime dar vien program, kuri prao nurodyti, i kurio failo norsime vesti duomenis ir kur fail norsime rayti rezultatus: #include <iostream> #include <fstream> using namespace std; int main () { ifstream aa; ofstream bb; char s [50]; int a, b; cout <<"Is kurio failo vesite duomenis?\n"; cin >> s; aa.open (s); cout <<"I kuri faila isvesite rezultatus?\n"; cin >> s; bb.open(s); aa >> a >> b; bb << a << "+" << b << "=" << a+b << endl; aa.close(); bb.close(); return 0; }
Is kurio failo vesite duomenis? c:\duom.txt I kuri faila isvesite rezultatus? C:\rez.txt [c:\duom.txt] 27 482 [c:\rez.txt] 27+482=509
Dirbant su failais gali atsitikti, kad norimo failo nepavyksta atidaryti, o vedant duomenis i fail pasiekiama failo pabaiga. ioms situacijoms kontroliuoti yra atitinkamai funkcijos is_open() ir eof(). Funkcijos is_open() reikm yra true, jei failas atidarytas, o eof() duoda false, jei dar nepasiekta failo pabaiga. i funkcij naudojimo pavyzdys: // tekstinio failo skaitymas #include <iostream> #include <fstream> #include <string> using namespace std;
38
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int main () { string eilut; ifstream manofa; manofa.open ("pavyz.txt"); if ( !manofa.is_open() ) { cout << "Failo atidaryti nepavyko"; return 1; } while ( !manofa.eof() ) { getline (manofa, eilut); cout << eilut << endl; } manofa.close(); return 0; } ia simboli eilutms vesti naudojome geltine() funkcij, tik jos argumentas yra ms paskelbtas kintamasis manofa, o ne cin, kaip t darme 5.3. cin ir simboli eiluts skyriuje. C++ kalboje yra ir daugiau priemoni duomenims vesti/ivesti. Pvz., funkcijomis read() ir write() perduodami dvejetainio (binarinio) pavidalo duomenys. vedimo/ivedimo metu jokia duomen transformacija i dvejetainio pavidalo simbolin pavidal ir atvirkiai neatliekama. Mintas funkcijas ir eil kit nagrinsime vliau, kai susipainsime su rodyklmis. Viena teksto faile eilute. Kita teksto faile eilute.
39
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
6. Valdantieji sakiniai
Programose sakiniai danai nra vykdomi tokia eils tvarka, kaip jie yra urayti. Jose galimi isiakojimai, sakini kartojimai, sprendim primimai. iam tikslui yra valdantieji sakiniai, kuriais nurodoma, kada ir k programa turi daryti esant tam tikroms aplinkybms. Prie praddami nagrinti valdaniuosius sakinius, vis pirma susipainkime su sudtinio sakinio arba bloko svoka. Blokas tai sakini grup, apkabinta riestiniais skliaustais {}. Jame sakiniai, kaip priimta C++ kalboje, vienas nuo kito skiriami kabliatakiais. Pvz.: { sakinys1; sakinys2; sakinys3; } Daugelyje valdymo sakini, kaip j sudtin dalis, yra kitas sakinys. Tas kitas sakinys gali bti paprastas (jis baigiamas kabliatakiu) arba sudtinis (keletas blok sudarani sakini). Tais atvejais, kai norime turti paprast sakin, apkabinti jo riestiniais skliaustais { } nereikia. Taiau sudtinio sakinio atveju riestiniai skliaustai { }, kuriais formuojamas blokas, btini.
40
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ekran bus ivesta x yra lygus 100 , jei x reikm yra 100. Kitais atvejais bus ivesta x nera lygus 100. Po else gali bti raomas naujas if sakinys. Toliau einantis pavyzdys rodo, kaip bus elgiamasi, kai x yra daugiau, lygus ir maiau u 0: if (x > 0) cout << "x yra teigiamas"; else if (x < 0) cout << "x yra neigiamas"; else cout << "x yra lygus 0"; Prisiminkime, kad akoje norint atlikti kelis sakinius, juos btina apskliausti riestiniais skliaustais {}.
8, 7, 6, 5, 4, 3, 2, 1,
Pirmyn!
41
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ios programos vykdymo pradioje vartotojui ekran ivedamas priminimas Iveskite pradini skaiciu. vedus skaii, while ciklo blokas (sudtinis sakinys) kartojamas tol, kol n>0. Pirmyn! Atkreipkime dmes tai, kad while ciklo bloke turi bti sakinys, turintis tak tam, kad ciklo slygos_iraikos rezultatas tapt false. Kitokiu atveju turtume nesibaigiant cikl. Todl ms turtoje programoje yra sakinys --n; Pastebkime, kad while ciklas gali bti neatliktas n karto, pvz., jei vestume neigiam n reikm. do-while ciklas. io ciklo bendrasis pavidalas yra toks: do sakinys while (slygos_iraika); Jis vydomas taip pat, kaip ir while ciklas. Skirtumas yra tik toks, kad ia slygos_iraika apskaiiuojama po to, kai vykdomas sakinys. Taip garantuojama, kad sakinys bus vykdytas bent vien kart. Pvz., emiau pateikiama programa prays vesti skaiius tol, kol nevesime 0. // programa su do-while ciklu #include <iostream> using namespace std; int main () { unsigned long n; cout << "Darbui baigti iveskite 0. \n"; do { cout << "Iveskite skaiciu: "; cin >> n; cout << "Jus ivedete: " << n << "\n"; } while (n != 0); return 0; } Kai tik n pasidaro lygus 0, ciklas nutraukiamas ir ekran ivedama
Darbui baigti iveskite 0. Iveskite skaiciu: 12345 Jus ivedete: 12345 Iveskite skaiciu: 160277 Jus ivedete: 160277 Iveskite skaiciu: 0 Jus ivedete: 0
do-while cikl nutraukimo slyga suformuojama ciklo bloke. Ms pavyzdyje tai vestas skaiius 0. for ciklas. io ciklo bendrasis pavidalas yra: for (inicializacija; slyga; reikms_keitimas) sakinys Jame sakinys kartojamas tol, kol slyga duoda reikm true. Kaip matome, jame dar yra inicializacijos sakinys ir reikms_keitimo sakinys. itoks ciklas specialiai yra sukurtas pakartotinam veiksm vykdymui vadovaujantis skaitikliu. Skaitiklis vis 42
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
pirma yra inicializuojamas (jam suteikiama pradin reikm), o vliau jo reikm keiiama nurodytu dydiu kiekvienos iteracijos metu. for ciklo veiksm sekos punktai yra tokie: 1. Atliekama inicializacija. Paprastai tai pradins reikms suteikimas skaitiklio kintamajam. is veiksmas atliekamas tik vien kart. 2. Tikrinama slyga, ar skaitiklio kintamojo reikm nra didesn (maesn) u nurodyt dyd. Jei gaunama reikm true, ciklo sakinys yra vykdomas. Prieingu atveju ciklas baigiamas ir sakinys nebevykdomas. 3. Vykdomas ciklo sakinys. Tai gali bti paprastas arba sudtinis sakinys (blokas). 4. Atlikus sakin, vykdomas reikms_keitimo sakinys. Daniausia keiiama skaitiklio kintamojo reikm (didinama arba mainama) ir grtama ciklo veiksm sekos 2 punkt. emiau pateikiama programa su for ciklu, kuriame kintamojo-skaitiklio n reikm yra mainama: // programa su for ciklu #include <iostream> using namespace std; int main () { for ( int n=10; n>0; n-- ) cout << n << ", "; cout << "\n Pirmyn!"; return 0; } for cikle inicializacijos ir reikms_keitimo sakini gali ir nebti. Jie gali bti tuti, taiau laukus skiriantys kabliatakiai (;) turi bti raomi. Pvz., gali bti raoma for ( ; n<10 ; ), jei nereikia inicializacijos ir reikms_keitimo sakini, arba for ( ; n<10; n++ ), jei nereikia tik inicializacijos sakinio. Galbt inicializacija buvo atlikta dar iki for ciklo. for cikle inicializacija ir reikms_keitimas gali susidti i keleto iraik. Iraikos skiriamos kableliu (,). Pvz., tarkime, cikle norime inicializuoti daugiau kaip vien kintamj: for ( n=0, i=100; n!=i; n++, i-- ) { // bloko sakiniai ... } is ciklas bus kartojamas 50 kart, jei n ir i reikms nebus keiiamos bloko sakiniais. 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, Pirmyn!
43
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
10, 9, 8, 7, 6, 5, 4, 3,
Ciklas nutrauktas!
ioje programoje for ciklas nutraukiamas, kai kintamojo-skaitiklio n reikm lygi 3. continue sakinys. continue sakinys galina nutraukti tik ciklo iteracij jos nebaigus, perokti kitos teracijos pradi ir tsti cikl, kol jis nesibaigs normaliai. Pavyzdys: // continue sakinio naudojimo pavyzdys #include <iostream> using namespace std; int main () { for ( int n=10; n>0; n-- ) { if (n==5) continue; cout << n << ", "; } cout << "\n Pirmyn!"; return 0; }
10, 9, 8, 7, 6, 4, 3, 2, 1, Pirmyn!
ia for ciklo iteracija, kai n lygu 5, nutraukiama, bet ciklas vykdomas toliau.
44
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
goto sakinys. goto sakiniu beslygikai perokama kit programos viet. Perokimo vieta nurodoma yme, kuri kaip argumentas nurodoma goto sakinyje. yms raomos tik prie tuos programos sakinius, kuriuos norsime perokti goto sakiniais. Tarp yms ir sakinio dedamas dvitakis. goto sakinyje po nurodytos yms dvitakis nededamas. Apskritai, struktriniame Pavyzdys: // goto sakinio vartojimo pavyzdys #include <iostream> using namespace std; int main () { int n=10; zym1: cout << n << ", "; n--; if (n>0) goto zym1; cout << "\n Pirmyn!"; return 0; } ir objektiniame programavime goto sakiniai
10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
Pirmyn!
ioje programoje ciklas yra suorganizuotas naudojant if ir goto sakinius. exit() funkcija. Atkreipkime dmes, kad exit() yra gatava funkcija ir laikoma bibliotekoje <cstdlib>. exit() funkcijos paskirtis yra stabdyti programos darb, nurodant specifin stabdymo kod. ios funkcijos prototipas (C++ kalboje prototipas tai funkcijos pirmasis sakinys- antrat) yra: void exit (int isejimokodas); isejimokodas reikm naudoja kai kurios operacins sistemos, ir ji gali bti naudojama kitose kvieiamose programose. Pagal susitarim isejimokodas lygus 0 (sakinys exit(0);) reikia, kad programa baig darb normaliai. Kitokios isejimokodas reikms rodo, kad programoje buvo klaid arba gauti nenumatyti rezultatai.
45
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
switch sakinys yra kakiek neprastas C++ kalboje, nes jame vartojamos yms, o ne blokai (sudtiniai sakiniai). Tai veria mus naudoti break po kiekvienos 46
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
sakini_grups, kuri reikia atlikti esant specifinei slygai. Praleidus break bt vykdoma ir kita i eils einanti sakini_grup, kol nepasiektume switch sakinio galo arba nesutiktume break. Pvz., jei mes neraysime break po pirmos sakini grups, tai programa automatikai neperoks switch sakinio pabaig, o vykdys toliau i eils einanius sakinius. Tokiu bdu ivengiama bereikaling riestini skliaust {} kiekvieno varianto sakini grupei. Taip pat tai gali bti naudinga norint vykdyti t pai sakini grup, esant vairioms iraikos reikmms. Pvz.: switch (x) { case 1: case 2: case 3: cout << "x lygu 1, 2 arba 3"; break; default: cout << "x nelygu 1, 2 nei 3"; } Pastebkime, kad switch sakinyje vietoje konstant negalima vartoti kintamj, pvz., n, arba reikmi interval, pvz., (1..5). Jei reikalingi skaiiavimai tikrinant reikmes i kakurio intervalo, naudokime if arba else if sakinius.
47
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
1 pavyzdys.
Ispausdinkime sveikj skaii nuo 1 iki N ingsniu 1 kvadrat, kb ir kvadratini akn lentel. N reikm veskime klaviatra.
/* Programa skaii laipsni lentelei ivesti. Autorius - V.Pavardenis, tel. 222555, data - 2007 06 26 */ #include <iostream> // i ia ims cin ir cout #include <cmath> // matematini funkcij biblioteka. Ims sqrt #include <cstdlib> // i ia ims funkcij system using namespace std; #define bruksnys "\n-----------------------------------\n" main () { int n, j, kvadratas, kubas; float saknis; cout << "Iveskite sveikaji skaiciu N: "; cin >> n ; // vedame skaii, iki kurio skaiiuosime laipsnius // toliau ivedame lentels antrat
cout << bruksnys; cout << "Skaic. Kvadr. Kubas Saknis \n"; cout << bruksnys; // toliau skaiiuojame ir ivedame rezultatus for ( j = 1; j <= n; j++ ) { kvadratas = j*j; kubas = kvadratas*j ; saknis = sqrt(j) ; // sqrt kvadr. aknies traukimo funkcija cout << j << "\t" << kvadratas << "\t" << kubas << "\t" << saknis << endl; } cout << bruksnys; system ("PAUSE"); // stabdo program rezultatams pairti return 0; }
48
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
2 pavyzdys.
S=
N k =1
1 1 1 1 + + ++ , 1 2 3 N
N! = 1 * 2 * 3 * * N ,
/* programa skaiiuoja sum ir faktorial; autorius - V.Pavardenis; tel. 2144555; data 2007 06 26 */ #include <iostream> #include <cstdlib> using namespace std; // i ia ims funkcij system
main () { int k, n; float suma; long fakt; cout << "Iveskite sveikaji skaiciu N: "; cin >> n; // toliau parengiami kintamieji suma ir fakt sumai ir faktorialui kaupti suma = 0 ; fakt = 1 ; for (k=1; k<=n; k++) { suma = suma + 1.0/k ; // 1.0, kad dalybos rezultatas btu float tipo fakt = fakt * k ; } // toliau ivedami skaiiavimo rezultatai cout << "Kai N = " << n << ", suma = " << suma << endl; cout << "Faktorialas = " << fakt << endl; system ("PAUSE"); // stabdoma programa rezultatams pairti return 0; }
49
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
3 pavyzdys.
/* programa isiakojanios funkcijos reikmei apskaiiuoti */ #include <iostream> #include <cmath> #include <cstdlib> using namespace std; // matematini funkcij biblioteka. Ims sin // i ia ims funkcij system
main () { float a, x, f; int k; cout << Iveskite x reikme: ; cin >> x; if (x < 1) f = x + (x+1)*(x+1) + (x+2)*(x+2)*(x+2); if ((1 <= x) && (x <= 3)) { f = 1; a = 1; for ( k=1; k<=10; k++ ) { a = a/x; f = f+a; } // vardiklyje augs x laipsnis
} if (x > 3) f = 1 + sin(x); // toliau ivedame skaiiavimo rezultatus cout << Kai x = << x << , funkcijos reiksme = << f << endl; system ("PAUSE"); // stabdoma programa rezultatams pairti return 0;
}
50
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
4 pavyzdys.
Trigonometrins funkcijos cos ( x ) , kai x ireikiamas radianais, reikm randama sumuojant tokios matematins eiluts narius: x2 x4 x6 cos( x ) 1 + + 2! 4! 6! Neirint to, kad C++ kalboje matematini funkcij bibliotekoje <cmath> yra cos(x) standartin funkcija, kosinusui apskaiiuoti sudarykime program patys. x reikm veskime klaviatra, o kosinus skaiiuokime tikslumu = 0.00001. Algoritmas. Matematins eiluts, kurios narius sumuojant gaunama cos(x) reikm, k-tasis x2 narys, remiantis prie buvusiu nariu, randamas taip: a k = a k 1 * , kur 2 k ( 2 k 1)
51
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// didinamas matem.eiluts nario numeris // gaunama eilinio sumos nario a reikm // kaupiama nari suma // fabs duoda a absoliutin dyd float tipo
cout << Musu programa gautas cos(x)= << s << endl; cout << Standart. f-ja gautas cos(x)= << cos(x) << endl; system ("PAUSE"); return 0; } // stabdoma programa rezultatams pairti
52
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
7. Funkcijos
Funkcijos galina skaidyti sudtingas programas atskiras dalis - modulius. Naudodami jas galime inaudoti vis C++ kalbos struktrinio programavimo potencial, geriau organizuoti programuotoj kolektyvo darb. Funkcija tai sakini grup, kuri gali bti vykdoma kreipusis j i bet kurios programos vietos. Bendrasis jos pavidalas yra toks: tipas vardas ( parametras1, parametras2, ...) { sakiniai } kur: tipas tai bazinis odis, nurodantis funkcijos apskaiiuotos ir grinamos reikms tip. Jis yra nebtinas (optional); - vardas, kur duodam funkcijai ir kuriuo reiks kreiptis j; - parametrai tai kintamieji (j gali bti tiek, kiek reikia), nurodant kiekvieno j tip (pvz., int a). ie kintamieji yra lokals ir galioja tik funkcijos ribose. Parametrai galina perduoti funkcijai argument reikmes, kai yra kreipiamasi j. Parametrai vienas nuo kito skiriami kableliu; - sakiniai, apkabinti riestiniais skliaustais {}. Jie dar vadinami funkcijos knu. tai pirmasis funkcijos pavyzdys:
-
// funkcijos pavyzdys #include <iostream> using namespace std; int sudetis (int a, int b) { int r; r=a+b; return (r); } int main () { int z; z = sudetis (5,3); cout << "Rezultatas yra " << z; return 0; }
Rezultatas yra 8
Praddami nagrinti pavyzd prisiminkime, kad C++ programa visada pradedama vykdyti nuo main funkcijos. ia main funkcija prasideda int tipo kintamojo z paskelbimu. Po to, priskyrimo sakinio deinje pusje yra kreipinys
53
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
funkcij sudetis. Pastebkime, kad kreipinys funkcij ir funkcijos antrat (pirmasis funkcijos sakinys) yra panas: int sudetis ( int a , int b ) z = sudetis ( 5, 3 ); Funkcijos antrats parametrai ir kreipinio funkcij argumentai turi aik atitikim. main funkcijoje kreipusis funkcij sudetis, programos vykdymas i main funkcijos persikelia funkcij sudetis, o abiej argument reikms 5 ir 3 atitinkamai perduodamos parametrams a ir b. Funkcijoje sudetis yra paskelbtas lokalus kintamasis int r , kuris priskyrimo sakiniu r=a+b; gyja kintamj a ir b sumos reikm, t.y. 8, nes kreipimosi funkcij sudetis metu a gijo reikm 5, o b reikm 3. Sakiniu return (r); baigiamas funkcijos sudetis darbas ir grtama t programos viet, i kur buvo kreiptasi (iuo atveju main funkcijos atitinkam viet). Tuo paiu kreipinio viet grinama return sakinyje nurodyto kintamojo r reikm 8. Pastaroji reikm main funkcijoje priskiriama kintamajam z ir ivedama ekran. Panagrinkime dar vien funkcijos pavyzd: // kitas funkcijos pavyzdys #include <iostream> using namespace std; int atimtis (int a, int b) { int r; r=a-b; return (r); } int main () { int x=5, y=3, z; z = atimtis(7,2); cout << "Pirmas rezultatas: " << z << '\n'; cout << "Antras rezultatas: " << atimtis(7,2) << '\n'; cout << "Trecias rezultatas:" << atimtis(x,y) << '\n'; z= 4 + atimtis(x,y); cout << "Ketvirtas rezultatas: " << z << '\n'; return 0; }
54
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
iame pavyzdyje turime funkcij atimtis. Ji skaiiuoja abiej parametr gaunam reikmi skirtum, kuris ir grinamas kaip rezultatas. Nagrindami pagrindin funkcij main pastebsime, kad joje yra keletas kreipini funkcij atimtis. Kreipinys funkcij pakeiiamas reikme, kuri ji grina return() sakiniu. Matome, kad kreipiniai funkcijas gali bti vairiose programos vietose, kur leistina rayti iraikas: cout sakinyje, priskyrimo sakinyje ir daug kur kitur.
55
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
parametr, skliaustai vis viena turi bti raomi. Todl kreipinys funkcij pranesu yra toks: pranesu (); Skliaustai aikiai parodo, kad tai yra kreipinys funkcij, o ne C++ kalbos kintamasis. Kreipinys pranesu; yra klaidingas.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
dvigub (x, y, z); cout << "x=" << x << ", y=" << y << ", z=" << z; return 0; }
Pirmas dalykas, k ia reikt atkreipti dmes, kad skelbiant funkcij dvigub, parametro tip nurodanio bazinio odio gale pridedamas simbolis &. Tai reikia, kad kreipiantis funkcij parametras atmintyje bus talpinamas tuo paiu adresu kaip ir kreipinio argumentas. Kadangi sutapatinamos argumento ir parametro atminties sritys, tai keiiant parametro reikm keisis ir argumento reikm. Taigi, turint toki funkcijos antrat ir kreipin j void dvigub ( int& a, int& b, int& c ) dvigub ( x, y, z ); reikmi perdavimas tarp argument ir parametr vyks abiem kryptimis: x a, y b, z c. Tai ir yra prieastis, kodl aukiau pateiktos programos main funkcijos kintamiesiems x, y ir z pradioje priskyrus reikmes 1, 3 ir 7 atitinkamai, po kreipinio funkcij dvigub ekran ivedami dvigubai didesni skaiiai. Jei funkcij dvigub btume paskelb po parametr tipo neraydami &, void dvigub (int a, int b, int c) tai main funkcijoje po kreipinio funkcij dvigub ekran bt ivestos nepakeistos kintamj x, y ir z reikms. Argument ir parametr atminties sutapatinimas yra efektyvus bdas pasiekti, kad funkcija apskaiiuot daugiau kaip vien reikm. emiau pateikiamoje programoje yra funkcija priespo, apskaiiuojanti prie ir po einanius skaiius duotam skaiiui. // daugiau kaip vien reikm apskaiiuojanti funkcija #include <iostream> using namespace std; void priespo (int x, int& pries, int& po) { pries = x-1; po = x+1; } int main () { int x=100, y, z; priespo (x, y, z); cout << "Skaicius=" << x << endl;
Skaicius=100
57
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
cout << "Ankstesnis=" << y << endl; << "Kitas=" << z; return 0; }
Ankstesnis=99 Kitas=101
6 5
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
7
10
iame pavyzdyje yra apibrtos dvi funkcijas tokiu paiu vardu daryk. Taiau vienos i j parametrai yra int tipo, o kitos - float tipo. kuri i j reikia kreiptis, kompiliatorius nustato inagrinjs kreipinio argument tipus. Pirmo kreipinio rezultatas yra argument reikmi suma 7, o antro sandauga 10. Atkreipkime dmes tai, kad negalima naudoti tokio paties vardo dviem funkcijoms, jei skiriasi tik j grainam reikmi tipai.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ablono parametras gali bti apibdinamas baziniu odiu typename arba class. Pvz., sudarykime ablon funkcijos, kuri i gaut dviej skaii graina didesnj: template <typename tpv> tpv didesnis (tpv a, tpv b) { tpv x; if (a>b) x=a; else x=b; return (x); } ia panaudotas ablono parametras tpv, skirtas duomen tipui nurodyti, taiau konkreti jo reikm dar nra aiki. Ji tampa aiki tik po kreipinio funkcij. Bendrasis kreipinio ablonu apibrt funkcij pavidalas yra: funkcijos_vardas <tipas> (argumentai); Todl ms funkcijos didesnis ablon turi bti kreipiamasi, pvz., taip: int j=5, k=6, m; m = didesnis <int> (j,k); Kompiliatorius, sutiks tok kreipin, funkcijos ablone automatikai vietoje parametro tpv stato ms atveju int ir tik tada kreipiasi funkcij. Imkime itisos programos pavyzd: // funkcijos ablonas #include <iostream> using namespace std; template <typename tpv> tpv didesnis (tpv a, tpv b) { tpv x; if (a>b) x=a; else x=b; return (x); } int main () { int j=5, k=6, m; float p=13.83, q=5.47, r; m = didesnis <int> (j,k); r = didesnis <float> (p,q); cout << m << endl;
6
60
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
13.83
ia funkcijos didesnis ablon kreipiamasi du kartus. Pirmo kreipinio argumentai yra int tipo, o antro float tipo. Todl kompiliatorius parengia dvi funkcijos versijas ir kiekvien kart kreipiamasi reikiam funkcijos versij. Turto pavyzdio atveju kompiliatorius sugeba parengti dvi funkcijos didesnis versijas, netgi jei kreipiniuose jas akivaizdiai nenurodysime tipo parametro, t.y. jei vietoje didesnis<int>(j,k) raysime tiesiog didesnis(j,k), o vietoje didesnis<float>(p,q) raysime didesnis(p,q). Jei kreipinyje yra, pvz., int tipo argumentai j ir k, tai ir funkcijos ablone juos atitinkantys parametrai a ir b taip pat turi bti int tipo. Todl ablono parametras tpv tampa int. Kadangi ms funkcijos ablone yra tik vienas ablono parametras tpv, o pati funkcija turi du parametrus a ir b, kurie yra vienodo tipo, mes negalime kreiptis funkcij naudodami skirtingo tipo argumentus. Pvz., int k; float p; q = didesnis (k,p);
// neleistinas kreipinys
Taiau galima apibrti funkcijos ablon, kuriame bt daugiau kaip vienas ablono parametras. Pvz.: // funkcijos ablonas su dviem ablono parametrais #include <iostream> using namespace std; template <typename t1, typename t2> t2 mazesnis (t1 a, t2 b) { float x; t2 y; if (a<b) x=a; else x=b; y=t2(x); // tam atvejui, kai t2 tampa int, nes x float tipo return (y); } int main () { int j=5, k=6, m, n; float p=13.83, q=5.47, r, v; r = mazesnis <int,float> (j,p);
61
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
m = mazesnis <float,int> (q,k); v = mazesnis <float,float> (p,q); n = mazesnis <int,int> (j,k); cout << r << endl; cout << m << endl; cout << v << endl; cout << n << endl; return 0; } iame pavyzdyje funkcijos mazesnis ablone yra du ablono parametrai t1 ir t2. Kreipiniai funkcij mazesnis taip pat gali bti raomi ir paprasiau, t.y. akivaizdiai nenurodant tip ablono parametrams: r = mazesnis(j,p); k = mazesnis(q,k); v = mazesnis(p,q); n = mazesnis(j,k); Pastebkime, kad funkcijos mazesnis grainamos reikms tipas sutampa su antro argumento tipu. Taip pat atkreipkime dmes funkcijos mazesnis ablono sakin y=t2(x); Jame t2 panaudotas kaip funkcijos vardas, kuri konvertuoja argumento x reikm i float tipo t2 tip (ir. 4.10 skyri Aikiai nurodomi duomens tipo keitimo operatoriai).
7.7. Rekursijos
Rekursija tai funkcijos savyb jos viduje esaniais sakiniais kreiptis save pai. Tai gali bti naudinga vairiuose udaviniuose, pvz., skaiiaus n faktorialui n! gauti:
62
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
n! = 1*2*3*(n-1)*n. Tai galima urayti ir taip: n! = n*(n-1)! Rekursyvi funkcija skaiiaus faktorialui skaiiuoti atrodo taip: // faktorialo skaiiavimas rekursyviai #include <iostream> using namespace std; long faktorialas (long a) { if (a > 1) return (a * faktorialas (a-1)); else return (1); } int main () { long skaicius; cout << "Iveskite skaiciu: "; cin >> skaicius; cout << skaicius << "! = " << faktorialas (skaicius); return 0; } Pastebkime, kad funkcijoje faktorialas kreipiamasi save pai, jei argumento reikm yra didesn u 1. Prieingu atveju funkcijos reikm bt lygi 0 ir turtume nesibaigiant cikl, nes toliau vykt daugyba i neigiam skaii, kol nevykt steko perpildymas. Apskritai, faktorialo skaiiavimo funkcijos ribotumas yra tas, kad ja, naudojant netgi long tipo kintamuosius, galima gauti rezultat, ne didesn kaip 15!.
Iveskite skaiciu: 9
9! = 362880
63
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
prototipe nurodomas tik jos tipas, vardas ir parametr tipai. To visikai pakanka kompiliatoriui. Taigi, bendrasis funkcijos prototipo pavidalas yra: tipas vardas ( parametro1_tipas, parametro2_tipas, ); Funkcijos prototipas - tai tik funkcijos antrat, kurioje gali bti praleisti parametr vardai (parametr tipai turi bti). Kadangi funkcijos sakiniai (knas) praleidiami, tai prototipo gale raomas kabliatakis (;). Pvz., funkcijos daugyba, turinios du int tipo parametrus a ir b, prototipas gali bti raomas vienu i dviej bd: int daugyba (int a, int b); int daugyba (int, int); Raant ir parametr vardus, funkcijos prototipas bna aikesnis. emiau pateikiamas C++ programos pavyzdys, kurioje naudojami funkcij prototipai, o patys funkcij tekstai raomi po pagrindins funkcijos main: // funkcij prototip naudojimas #include <iostream> using namespace std; void nelyg (int a); void lyg (int a); // funkcijos nelyg prototipas // funkcijos lyg prototipas
int main () { int i; cout << "Darbui baigti iveskite 0.\n" << endl; do { cout << "Iveskite skaiciu: "; cin >> i; nelyg (i); } while (i!=0); return 0; } void nelyg (int a) // visas funkcijos nelyg tekstas { if ((a%2)!=0) cout << "Skaicius nelyginis.\n"; else lyg (a); } void lyg (int a) // visas funkcijos lyg tekstas { if ((a%2)==0) cout << "Skaicius lyginis.\n"; else nelyg (a); }
Darbui baigti iveskite 0. Iveskite skaiciu: 9 Skaicius nelyginis. Iveskite skaiciu: 6 Skaicius lyginis. Iveskite skaiciu: 1030 Skaicius lyginis. Iveskite skaiciu: 0 Skaicius lyginis.
64
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Savo esme i programa nra efektyvi. Ja tik norta pailiustruoti prototip veikim. I pradi akis krenta funkcij nelyg ir lyg paskelbimas: void nelyg (int a); void lyg (int a); Tai galina kreiptis ias funkcijas, pvz., pagrindinje main funkcijoje. Daugumai moni atrodo logikiau, kai main funkcija, nuo kurios pradedamas visos programos darbas, yra priekyje. Vis programoje naudojam funkcij prototip skelbimas programos pradioje praktikai yra naudingas. Taip elgiasi dauguma programuotoj.
65
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
8. Masyvai
Masyvas tai tokio paties tipo element visuma, talpinam gretimose atminties srityse. Atskiras masyvo elementas nurodomas po masyvo vardo raant indeksus. Pvz., masyvas vardu skaiciai, turintis penkis int tipo elementus, gali bti pavaizduotas tokia schema:
0 1 2 3 4
skaiciai
int
ia kiekvienas staiakampis atitinka masyvo element, kuris ms atveju yra int tipo. Masyvo pirmojo elemento indeksas visada yra lygus 0, nepriklausomai nuo masyvo dydio. Kaip ir visi kintamieji, taip ir masyvai turi bti paskelbti prie naudojant juos. C++ kalboje bendrasis masyv paskelbimo pavidalas yra toks: tipas vardas [kiekis]; Staiakampiuose skliaustuose nurodoma, kiek element norime turti masyve. Aukiau schemoje pavaizduotas masyvas skaiciai turi bti skelbiamas taip: int skaiciai [5]; Atkreipkime dmes, kad masyvo element kiekis turi bti nurodomas konstanta. Apie kitokias galimybes ioje mokymo priemonje raoma vliau.
skaiciai
16
Reikmi kiekis tarp riestini skliaust {} turi bti ne didesnis, nei tarp staiakampi skliaust [] nurodytas masyvo element kiekis.
66
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Kai yra nurodomos masyvo element pradins reikms, masyvo element kiekio tarp staiakampi skliaust [ ] galima ir nenurodyti. Tokiu atveju kompiliatorius laikys, kad masyvo dydis yra toks, kiek pradini reikmi nurodyta riestiniuose skliaustuose {}: int skaiciai [] = { 16, 2, 77, 40, 1207 }; Taip paskelbtame masyve skaiciai bus 5 elementai, nes tiek pradini reikmi nurodme.
Skelbiant masyv, pradioje raomas tip nurodantis bazinis odis, o prie atskir masyvo element tokio odio niekada nebna.
67
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Toliau pateikama keletas su masyvais leistin veiksm: skaiciai [0] = a; skaiciai [a] = 75; b = skaiciai [a+2]; skaiciai [ skaiciai [a] ] = skaiciai [2] + 5; // programa su masyvu #include <iostream> using namespace std; int skaiciai [] = {16, 2, 77, 40, 1207}; int n, rezult=0; int main () { for ( n=0 ; n<5 ; n++ ) rezult += skaiciai [n]; cout << rezult; return 0; } i programa suskaiiuoja vis masyvo skaiciai element sum.
1342
ruta
1 2
ia pavaizduotas dvimatis 3 i 5 masyvas ruta. Toks int tipo skaii masyvas C++ kalboje skelbiamas taip: int ruta [3] [5]; Jo antros eiluts ketvirtas (ketvirto stulpelio) elementas nurodomas kaip ruta [1] [3] Atsiminkime, kad indeksai visada prasideda nuo 0. Daugiamaiai masyvai neapsiriboja dviem indeksais. J gali bti tiek, kiek reikia. Bet bkime atids. Masyvui reikalingas atminties dydis greitai didja sulig kiekvienu nauju indeksu.
68
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Daugiamaiai masyvai yra tik programuotoj abstrakcija. Tok pat rezultat galima gauti su vienmaiu masyvu, kurio dydis bt lygus daugiamaio masyvo indeks sandaugai: int ruta [3] [5]; int ruta [15]; // ekvivalentiki masyvai // 3 * 5 = 15
Panagrinkime toliau du program fragmentus, duodanius tok pat rezultat. Viename i j naudojamas dvimatis masyvas, kitame vienmatis masyvas. Dvimatis masyvas #define plotis 5 #define aukstis 3 int ruta [aukstis] [plotis]; int n,m; int main () { for (n=0; n<aukstis; n++) for (m=0; m<plotis; m++) ruta [n] [m] = (n+1)*(m+1); return 0; } Vienmatis masyvas #define plotis 5 #define aukstis 3 int ruta [aukstis * plotis]; int n,m; int main () { for (n=0; n<aukstis; n++) for (m=0; m<plotis; m++) ruta [n*plotis+m] = (n+1)*(m+1); return 0; }
N viena i i program neiveda rezultat ekran, taiau patalpina juos masyvui ruta skirtoje atmintyje tokia tvarka:
0 0 1 2 3
1
2 4 6
2 3 6 9
3 4 8 12
4 5 10 15
ruta
1 2
iose programose apibrtosios konstantos (#define) pavartotos tam, kad bt paprasiau modifikuoti program. Pvz., prireikus masyvo indekso aukstis reikm 3 pakeisti 4, tai galima padaryti labai paprastai. Tereikia programos eilut #define aukstis 3 pakeisti #define aukstis 4 Daugiau joki pakeitim programoje daryti nereikia.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
atmintyje tik kreipinio funkcij argumentams-masyvams skirtais adresais, t.y. vyksta tik argumento-masyvo adreso perdavimas funkcijai. Masyvas, kaip funkcijos parametras, skelbiamos funkcijos antratje nurodomas po jo vardo raant staiakampius skliaustus [] , taiau juose nieko nenurodant. Pvz.: void procedura ( int para [] ) ia parametras vardu para yra int tipo masyvas. Norint iai funkcijai perduoti masyv, paskelbt kaip int mas[40]; , pakanka tokio kreipinio: procedura (mas); emiau pateikiama programa, kurioje yra funkcija su parametru-masyvu: // masyvai kaip funkcij parametrai #include <iostream> using namespace std; void masyvo_isvedimas (int para [], int ilgis) { for ( int n=0; n<ilgis; n++ ) cout << para [n] << " "; cout << "\n"; } int main () { int mas1 [] = {5, 10, 15}; int mas2 [] = {2, 4, 6, 8, 10}; masyvo_isvedimas (mas1, 3); masyvo_isvedimas (mas2, 5); return 0; }
5 10 15 2 4 6 8 10
ia funkcijos masyvo_isvedimas pirmas parametras ( int para [] ) gali priimti bet kokio ilgio int tipo masyv. Tam yra vestas antras parametras, kuriuo funkcijai perduodamas apdorojamo masyvo ilgis. Tai galina for ciklu ivesti ekran tiek element, kokio dydio masyvas buvo kreipinyje funkcij masyvo_isvedimas. Funkcijos parametru gali bti ir daugiamatis masyvas. Pvz., trimaio masyvo, kaip parametro, formatas yra: tipas vardas [] [skaiius] [skaiius] Funkcijos su daugiamaiu masyvu kaip parametru antrats pavyzdys: void procedura ( int trimas [] [3] [4] ) Pastebkime, kad tarp pirmj staiakampi skliaust neraoma nieko, kai tuo tarpu kituose skliaustuose turi bti sveikieji skaiiai.
70
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Turime 20 skaii masyv. Klaviatra veskime juos kompiuterio atmint, o po to apskaiiuokime vest skaii vidurk bei raskime didiausi ir maiausi skaiius. Rezultatus iveskime monitori taip: vis pirma iveskime vis masyv po 8 skaiius kiekvienoje eilutje, o po to vidurk, didiausi ir maiausi skaiius. Algoritmas. Iekant didiausio elemento, vis pirma daroma prielaida, kad pirmas masyvo elementas (arba bet kuris kitas masyvo elementas) yra didiausias. Jis simenamas atskirame kintamajame. Po to io atskiro kintamojo reikm lyginama su visais masyvo elementais. Kai tik randamas dar didesnis masyvo elementas, atskirame kintamajame simenama jo reikm. Analogikai randamas ir maiausias elementas.
/* Skaii masyvo vidurkio, didiausio ir maiausio element radimas */ #include <iostream> #include <cstdlib> // i ia ima funkcij system using namespace std; #define KIEKIS 20 #define BRUKSNYS -------------------------------- float mas [KIEKIS]; float did, maz, vid; main () { int j; cout << Iveskite << KIEKIS << skaiciu: << endl; for (j=0; j<KIEKIS; j++) cin >> mas [j]; vid = 0; // skaii sumai kaupti did = mas [0]; // prielaida, kad didiausias elementas yra mas[0] maz = mas [0]; // prielaida, kad maiausias elementas yra mas[0] for ( j=0; j<KIEKIS; j++ ) { vid += ma s[j]; if (mas [j]>did) did = mas [j]; if (mas [j]<maz) maz = mas [j]; } vid /= KIEKIS; // gaunamas skaii vidurkis // toliau ivedame ekran masyv po 8 elementus eilutse cout << Skaiciu masyvas: << endl; cout << BRUKSNYS << BRUKSNYS << endl;
71
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
for (j=0; j<KIEKIS; j++) { if ( (j % 8) == 0 ) cout << endl; // pereinam nauj eilut cout << mas [j] << \t; } cout << endl << BRUKSNYS << BRUKSNYS << endl; // toliau ivedami rezultatai cout << Skaiciu vidurkis: << vid << endl; cout << Diziausias skaicius: << did << endl; cout << Maziausias skaicius: << maz << endl; system ("PAUSE"); // stabdo program rezultatams pairti return 0; }
2 pavyzdys.
Tarkime, turime ne didesn kaip 100 skaii masyv. veskime norim masyvo element kiek, o po to iveskime juos monitori, surikiuotus nemajimo tvarka (tolesnis elementas turi bti didesnis arba lygus prie buvusiam). Prie vedant masyvo elementus, vis pirma veskime masyvo element kiek nurodant skaii. Algoritmas. Masyvo elementams rikiuoti yra daug algoritm. Imkime vien i paprastesni burbulo algoritm. Rikiuojant lyginami du gretimi masyvo elementai ir, jeigu reikia, jie sukeiiami vietomis. Tokiu bdu prabgus vis masyv, didiausias elementas perkeliamas masyvo gal. Po to viskas daroma i naujo, ir antr viet nuo masyvo galo perkeliamas antras pagal dyd masyvo elementas, ir t.t. Tam programoje reikia ciklo cikle.
// skaii masyvo element rikiavimas #include <iostream> #include <cstdlib> // i ia ima funkcij system using namespace std; #define BRUKSNYS "--------------------------------" float skm [100]; main () { float t; int k, m, n;
72
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
cout << Kiek skaiciu noresite ivesti: ; cin >> k; cout << Iveskite << k << skaiciu: << endl; for (m=0; m<k; m++) cin >> skm [m]; // toliau rikiuojame masyvo skm elementus nemajimo tvarka for (m=0; m<(k-1); m++) for (n=0; n<(k-1-m); n++) if (skm [n] > skm [n+1]) { t = skm [n]; // masyvo element skm [n] = skm [n+1]; // keitimas skm [n+1] = t; // vietomis } // toliau ekran ivedamas surikiuot skaii masyvas cout << \nSurikiuoti skaiiai:\n; for (m=0; m<k; m++) cout << skm [m] << ; cout << endl; system ("PAUSE"); // stabdo program rezultatams pairti return 0; }
ios programos if sakinyje pakeitus palyginimo enkl prieingu, masyvo elementai bt rikiuojami nedidjimo tvarka.
3 pavyzdys.
Turime 6 x 8 dydio matric (dvimat masyv). Raskime jos didiausi element ir ekran iveskime visus to stulpelio ir tos eiluts elementus, kuriuose yra didiausias matricos elementas. Algoritmas. Matricos didiausias elementas iekomas panaiai, kaip ir vienmaio masyvo atveju (ir. 1 pavyzd iame skyriuje). Skirtumas toks, kad matricos atveju reikia ciklo cikle. ia mums rpi ne pati didiausio elemento reikm, bet jo vieta matricoje, t.y. indeksai. Todl pradioje, papildomam kintamajam suteikus kurio nors matricos elemento reikm (prielaida, kad jis yra didiausias), btina ufiksuoti ir jo indeksus. Tikrinimo metu radus didesn element, ufiksuojami ir jo indeksai.
73
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// matrica #include <iostream> #include <cstdlib> // i ia ima funkcij system using namespace std; #define STULP 8 #define EILUT 6 float matr [EILUT] [STULP]; main () { float t; int st, eil, m, n; cout << Iveskite << EILUT << x << STULP << dydzio matricos elementus:\n; for (m=0; m<EILUT; m++) for (n=0; n<STULP; n++) cin >> matr [m] [n]; cout << "\nIvesta matrica\n"; for (m=0; m<EILUT; m++) { for (n=0;n<STULP; n++) cout << matr [m] [n] <<"\t"; cout << endl; } // iekome didiausio elemento matricoje matr t = matr [0] [0]; // prielaida, kad didiausias elementas yra matr[0][0] st = 0; eil = 0; // didiausio elemento indeks reikmms for (m=0; m<EILUT; m++) for (n=0; n<STULP; n++) if (matr [m] [n] > t) { t = matr [m] [n]; st = n; eil = m; } // ivedame atitinkamo matricos matr stulpelio ir eiluts elementus cout << \nStulpelis su didz. matricos elementu:\n; for (m=0; m<STULP; m++) cout << matr [m] [st] << ; cout << \nEilute su didz. matricos elementu:\n; for (m=0; m<EILUT; m++) cout << matr [eil] [m] << ; cout << endl; system ("PAUSE"); // stabdo program rezultatams pairti return 0; }
74
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
9. Simboli sekos
C++ kalboje yra galinga standartin biblioteka <string>, kurioje yra patogios priemons darbui su simboli eilutmis. Apie tai trumpai rayta 2.6 skyriuje. Kadangi eiluts i tikro yra simboli sekos, jas galima pavaizduoti kaip char tipo element masyvus. Pvz., masyvas char mikas [20]; gali siminti 20 simboli. J galima pavaizduoti taip: mikas
Taigi, tokiame masyve galsime saugoti iki 20 simboli ilgio sekas. Kadangi simboli masyve galima saugoti ir trumpesnes simboli sekas nei nurodytas masyvo dydis, yra naudojamas specialus simbolis \0 (null) sekos pabaigai nurodyti. Ms char tipo 20 element dydio masyvui mikas priskirtas simboli sekas Labas ir Su sventemis galima bt pavaizduoti taip: mikas L S a u b a s s v \0 e n t e m i s \0
Pastebkime, kad priskirtos simboli sekos gale terpiamas null simbolis (\0). Po jo likusiuose baituose yra neapibrta informacija.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Dvigubomis kabutmis apkabinta eilut yra ne kas kita, kaip simboli seka, kurios pabaiga automatikai nurodoma null simboliu (\0). Todl turt char tipo masyv zodis lengviau yra inicializuoti taip: char zodis [] = "Labas"; Abiem inicializavimo atvejais masyvas zodis paskelbiamas 6 element dydio: 5 elementai odiui Labas plius jo pabaig nurodaniam null simboliui (\0). Pastebkime, kad po char tipo masyvo paskelbimo priskyrimas jam reikms priskyrimo sakiniu skiriasi nuo inicializacijos skelbimo metu. char tipo masyvai ir simboli eiluts yra itisi duomen blokai, o priskyrimo operatoriumi kopijuoti blok negalima. Todl tokie priskyrimo sakiniai, kaip zodis = "Labas"; zodis [] = "Labas"; zodis = { 'L', 'a', 'b', 'a', 's', '\0' }; yra neleistini. Viso to prieastis taps aikesn, kai susipainsime su rodyklmis (pointer).
76
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Kaip matome, ioje programoje yra paskelbti trys char tipo masyvai. Pirmieji du yra inicializuoti panaudojus eilutes, o treias paliktas neinicializuotas. Taiau bet kuriuo atveju turi bti nurodomas masyvo dydis. Pirm dviej masyv klausk ir atsakyk dydis nustatomas pagal inicializacijai panaudotas eilutes, o treio masyvo vardas dydis nurodytas aikiai 80. Belieka pridurti, kad char tipo masyvuose saugomos simboli sekos lengvai gali bti konvertuojamos eilutes, t.y. string tipo objektus, priskyrimo operatoriais: string eilut; char masyv [] = "kazkoks tekstas"; eilut = masyv;
77
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
78
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
daug kur naudojamos. Kaip itokie kintamieji paskelbiami ir naudojami, suinosime truput vliau.
Atkreipkime dmes adreso operatoriaus (&) ir duomens nurodytu adresu operatoriaus (*) skirtum: jie yra vienas kit papildantys ir kartu vienas kitam prieingi. Imkime tok atvej: a = 25; b = a; c = *&a; ia kintamieji a, b ir c gyja toki pai reikm. Uraas *&a reikia, kad operatoriumi & pirmiausiai gaunamas kintamojo a adresas, o po to operatoriumi * paimama reikm, urayta tuo adresu. Taigi, uraas *&a duoda t pat kaip ir a. Imkime dar vien pavyzd. Anksiau turjome tokius du priskyrimo sakinius: alge = 25; vyt = &alge; kur tarme, kad kintamojo alge adresas atmintyje yra 2476. vykdius juos, visos emiau parodytos palyginimo iraikos duos rezultat true. alge == 25 &alge == 2476 vyt == 2476 *vyt == 25
79
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Nors tiesiogiai n vinam i kintamj sk1 ir sk2 reikms nesuteikme, abu jie reikmes gijo netiesiogiai, naudojant rodykl rod.
80
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Imkime sudtingesn pavyzd: // programa su daugiau rodykli #include <iostream> using namespace std; int main () { int sk1 = 5, sk2 = 15; int *p1, *p2; p1 = &sk1; // p1 = sk1 adresas p2 = &sk2; // p2 = sk2 adresas *p1 = 10; // 10 raso adresu p1 *p2 = *p1; // ima reikm adresu p1 ir raso adresu p2 p1 = p2; // kopijuoja rodykls reikm *p1 = 20; // 20 rao adresu p1 cout << "Pirmas skaicius " << sk1 << endl; cout << "Antras skaicius " << sk2 << endl; return 0; } Atkreipkime dmes i eilut: int *p1, *p2; Joje yra paskelbtos dvi rodykls. Jei raytume int *p1, p2; p1 bt rodykl, o p2 int tipo kintamasis. Skelbiant rodykles, prie kiekvien btina rayti vaigdut (*).
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Toliau pateikiamame programos pavyzdyje visos iraikos, kuriose naudojamos rodykls, yra teisingos: // dar apie rodykles #include <iostream> using namespace std; int main () { int skaiciai [5]; int *p; p = skaiciai; *p = 10; p++; *p = 20; p = &skaiciai [2]; *p = 30; p = skaiciai + 3; *p = 40; p = skaiciai; *(p+4) = 50; for ( int n=0; n<5; n++ ) cout << skaiciai [n] << ", "; return 0; } Priskyrimo sakinyje p = skaiciai; uraas skaiciai atitinka &skaiciai [0], t. y. masyvo vardas reikia pirmojo elemento adres. Sakinio p++; rezultatas yra kito elemento adresas. Kadangi rodykl p yra int tipo, tai adreso skaitin reikm padidinama 4, nes int tipo kintamieji atmintyje uima 4 baitus. Iraikomis skaiciai+3 ir p+4 adresai padidinami tiek, kad gautume reikiamo masyvo elemento adres. Prisiminkime, kad masyvo elementas nurodomas po vardo staiakampiuose skliaustuose [] raant indeks. Todl iuos skliaustus galima traktuoti kaip reikms mimo/siminimo nurodytu adresu operatori, kuris, kaip inome, ymimas vaigdute (*). Pvz., iraikos a [5] = 0; *(a+5) = 0; yra ekvivalentikos, jei a yra rodykl arba masyvas.
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int skaic; int *tom; tom = &skaic; Masyv atveju inicializuoti rodykl galima priskiriant konstant. char *vera = "Labas"; ia vis pirma rezervuojama atminties sritis konstantai Labas saugoti, o po to jos pirmo simbolio adresas priskiriamas rodyklei vera. Rodykl vera nurodo simboli sekos (eiluts) pradi ir todl traktuojama kaip masyvas (prisiminkime, kad masyvas traktuojamas kaip rodykls konstanta). Todl turimos eiluts penkt element galima kreiptis tokiais bdais: *(vera+4) vera [4] Abiem atvejais gausime reikm s (penktoji eiluts Labas raid).
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
simb = simb + 1; trump = trump + 1; ilg = ilg + 1; Visi ie samprotavimai tinka ir atimties operacijos atveju. Reikms didinimo (++) ir mainimo (--) operatori prioritetas yra emesnis u duomens nurodytu adresu mimio/siminimo operatori (*). Taiau abu jie turi specifini ypatybi, kai raomi po kintamojo vardo (juk galime rayti a++ ir ++a). Taigi, uraas *p++ yra ekvivalentikas uraui *(p++) Tai reikia, kad pirma pasinaudojama esama rodykls reikme ir tik po to jos reikm yra didinama. Atkreipkime dmes tok ura: (*p)++ iuo atveju yra imamas duomuo nurodytu adresu, jis panaudojamas ir po to jo reikm didinama vienetu. Rodykls reikm lieka nepakitusi. Imkime dar vien pavyzd. Uraai *p++ = *q++; ir *p = *q; ++p; ++q; yra ekvivalentiki. Tokiais atvejais rekomenduojama naudoti skliaustus, kad ivengtume klaid.
84
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ia sakiniu b = &a; suinojome, kokiu adresu atmintyje patalpintas char tipo kintamasis a, o sakiniu c = &b; gavome atminties adres, kur laikoma rodykl b.
y, 1603
ia standartine sizeof() funkcija gaunamas jos argumento uimamos atminties srities dydis baitais. Pagrindinio tipo duomenims ie dydiai yra konstantos. Pvz., sizeof(char) reikm yra 1, nes char tipo duomuo atmintyje uima 1 bait. Funkcijos didink() parametras duomuo, kuris yra void tipo rodykl, prie naudojim iraikomis (char*)duomuo ir (int*)duomuo pakeiiamas reikiamo tipo rodykl.
85
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// rezultatas - 12 // rezultatas - 8
86
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
iame pavyzdyje minus yra globalioji du int tipo parametrus turinios funkcijos rodykl. Jai ia i karto suteikiama pradin reikm (ji inicializuojama), kuri lygi funkcijos atimk adresui. int (*minus) (int,int) = atimk; Pastebkime, kad funkcij vardai yra traktuojami kaip rodykls. Prisiminkime, kad panaiai yra ir su masyv vardais.
87
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
88
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Reikiamas dinamins atminties sritis sistema skiria laisvoje atminties dalyje (j dar vadina heap atmintim). Taiau kompiuterio atmintis yra riboto dydio, ir ji gali bti visa uimta. Todl svarbu turti tikrinimo priemon, ar praomo dydio atminties sritis i tikro buvo paskirta. C++ kalboje yra du standartiniai dinamins atminties skmingo paskyrimo kontrols bdai. Vienas i j yra neskming arba ypating situacij (exceptions) apdorojimas. Negaldama paskirti dinamins atminties srities, sistema suformuoja bad_alloc tipo situacij, susidarius kuriai programuotojas gali numatyti savo veiksmus. Ypating situacij apdorojimo ioje mokymo priemonje mes plaiau nenagrinsime. Taiau inokime, kad programuotojui nenumaius savo veiksm ypatingos situacijos atveju, programa nutraukiama. Programos nutraukimas yra ypatingos situacijos, skiriant dinamin atmint new operatoriumi, apdorojimo numatytasis (default) bdas. Jis naudojamas tokiuose sakiniuose, kaip, pvz., bob = new int [5]; Kitas dinamins atminties paskyrimo kontrols bdas yra inomas vardu nothrow. Neskms atveju new operatorius grina adres lyg 0 (null) ir programa tsiama. is kontrols bdas pradeda veikti, jei po new raomas parametras nothrow. Pvz: bob = new (nothrow) int [5]; Ar iuo sakiniu dinamin atmintis sritis nurodytam element kiekiui i tikro buvo paskirta, galima sitikinti patikrinus rodykls bob reikm: int *bob; bob = new (nothrow) int [5]; if (bob == 0) { // atminties nepaskyr. Reakcija tai. };
89
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Pirmoji iraika naudojama pavieniam elementui, o antroji element masyvui paskirtai dinaminei atminiai ilaisvinti. Iraikose nurodoma rodykl anksiau turi bti gijusi reikm new operatoriumi arba ji gali turti null reikm (esnt null rodyklei, operatorius delete nieko nedaro). Pavyzdys: // dinamins atminties skyrimas ir ilaisvinimas #include <iostream> using namespace std; int main () { int k,n; int * p; cout << "Kiek skaiciu vesite? "; cin >> k; p = new (nothrow) int [k]; // paskiria atmint if (p == 0) { cout << "Klaida: atmintis nepaskirta"; exit(0); } else { for (n=0; n<k; n++) { cout << "Iveskite skaiciu: "; cin >> p [n]; } cout << "Jus ivedete: "; for (n=0; n<k; n++) cout << p [n] << ", "; delete [] p; // ilaisvina atmint } return 0; } Atkreipkime dmes sakin p = new (nothrow) int [k]; Jame masyvo dydis nurodytas kintamuoju k, kuriam reikm vedama programos vykdymo metu. vedus didel kintamojo k reikm, gali trkti dinamins atminties ir ji nebus paskirta. Tai kontroliuojama nothrow metodu.
Iveskite skaiciu: 75 Iveskite skaiciu: 436 Iveskite skaiciu: 1067 Iveskite skaiciu: 8 Jus ivedete: 75, 436, 1067, 8,
90
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
91
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
92
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
struct produktas { int svoris; float kaina; } suris, desra, zuvis; Svarbu yra skirti, kur yra struktros tipo vardas ir kur yra tokios struktros objektas (kintamasis). Vieno struktros tipo objekt galime paskelbti daug. Kadangi mes paskelbme tris apibrtos struktros tipo objektus suris, mesa ir zuvis, tai galime tiesiogiai dirbti su kiekvieno i j elementais. Tam tarp objekto vardo ir elemento turi bti dedamas takas. Pvz., mes galime dirbti su bet kuriuo elementu, nes jie yra standartinio tipo kintamieji: suris.svoris suris.kaina desra.svoris desra.kaina zuvis.svoris zuvis.kaina
Kiekvieno i duomen tipas atitinka struktros elementui nurodyt tip. suris.svoris, desra.svoris ir zuvis.svoris yra int tipo, o suris.kaina, desra.kaina ir zuvis.kaina yra float tipo. Inagrinkime pavyzd, kuriame struktros tipas naudojamas lygiai taip pat, kaip ir pagrindiniai duomen tipai. // pavyzdys su struktromis #include <iostream> #include <string> #include <sstream> using namespace std; struct knyg_t { string pavadinimas; int metai; } mano, tavo; void spausdink (knyg_t knyga); // funkcijos prototipas
int main () { string eilut; mano.pavadinimas = "Odisejo keliones"; mano.metai = 1968; cout << "Iveskite pavadinima: "; getline (cin, tavo.pavadinimas); cout << "Iveskite metus: "; getline (cin, eilut);
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
stringstream (eilut) >> tavo.metai; cout << "Mano megiama knyga yra:\n "; spausdink (mano); cout << "Jusu megiama knyga yra:\n "; spausdink (tavo); return 0; } void spausdink (knyg_t knyga) { cout << knyga.pavadinimas; cout << " (" << knyga.metai << ")\n"; }
Mano megiama knyga yra: Odisejo keliones (1968) Jusu megiama knyga yra: Pelene (1979)
is pavyzdys rodo, kad objekt elementai gali bti naudojami kaip paprasti kintamieji. Pvz., tavo.metai yra int tipo kintamasis, o mano.pavadinimas yra string tipo kintamasis. Objektai mano ir tavo gali bti traktuojami kaip knyg_t tipo kintamieji. Pvz., mes juos, kaip ir prastus kintamuosius, naudojome kreipdamiesi funkcij spausdink. Taiau viena i svarbiausi duomen struktr savybi yra ta, kad mes galime kreiptis kiekvien jos element individualiai arba kreiptis vis struktr tik vienu vardu. Duomen struktros ypatingos tuo, kad jos gali bti naudojamos duomen bazms pavaizduoti, ypa jei tursime galvoje galimyb sudaryti duomen struktr masyvus: // struktr masyvas #include <iostream> #include <string> #include <sstream> using namespace std; #define N_KNYGU 3 struct knyg_t { string pavadinimas; int metai; } knygos [N_KNYGU]; void spausdink (knyg_t kng); // f-jos prototipas int main () { string eilut; int n;
94
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
for (n=0; n<N_KNYGU; n++) { cout << "Iveskite pavadinima: "; getline (cin,knygos [n].pavadinimas); cout << "Iveskite metus: "; getline (cin,eilut); stringstream(eilut) >> knygos [n].metai; } cout << "\n Jus ivedete siu knygu duomenis:" << endl; for (n=0; n<N_KNYGU; n++) spausdink (knygos [n]); return 0; } void spausdink (knyg_t kng) { cout << kng.pavadinimas; cout << " (" << kng.metai << ")\n"; }
Iveskite pavadinima: Kopos Iveskite metus: 1982 Iveskite pavadinima: Matrica Iveskite metus: 1999 Iveskite pavadinima: Taksi vairuotojas Iveskite metus: 1976 Jus ivedete siu knygu duomenis: Kopos (1982) Matrica (1999) Taksi vairuotojas (1976)
ia aknyga yra knyg_t tipo objektas, o pkn yra knyg_t tipo struktros rodykl. Todl sakinys pkn = &aknyga; yra teisingas. Rodyklei pkn bus priskirtas objekto aknyga adresas atmintyje. Panagrinkime programos su struktr rodyklmis pavyzd, kuris pads susipainti su nauju operatoriumi, t.y. rodykls operatoriumi (->): // struktr rodykls #include <iostream> #include <string> #include <sstream> using namespace std;
95
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
struct knyg_t { string pavadinimas; int metai; }; int main () { string eilut; knyg_t aknyga; knyg_t *pkn; pkn = &aknyga; cout << "Iveskite pavadinima: "; getline (cin, pkn->pavadinimas); cout << "Iveskite metus: "; getline (cin, eilut); stringstream(eilut) >> pkn->metai; cout << "\nJus ivedete:\n"; cout << pkn->pavadinimas; cout << " (" << pkn->metai << ")\n"; return 0; } iame pavyzdyje naudojamas rodykls operatorius (->) yra reikms nurodytu adresu mimo/siminimo operatorius, kuris iimtinai naudojamas tik struktr elementams. Rodykls operatoriumi kreipiamasi element to objekto, kurio adres turi siminusi struktros rodykl. Nepainiokime savok rodykls operatorius (->) ir rodykl (pointer). Pavyzdyje mes naudojome iraik pkn->pavadinimas kuri yra ekvivalentika tokiai iraikai: (*pkn).pavadinimas ios abi iraikos yra teisingos ir jomis kreipiamasi element pavadinimas tos struktros, kurios adres yra siminusi rodykl pkn. Btina aikiai skirti mintas iraikas nuo i dviej ekvivalentik iraik: *pkn.pavadinimas *(pkn.pavadinimas) Pastarosios reikalauja, kad pavadinimas bt rodykl (o ne string, kaip esame paskelb), ir todl bt kreipiamasi duomen, kurio adres ji nurodyt. Iveskite pavadinima: Altoriu sesely Iveskite metus: 1978
96
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
emiau lentelje reziumuojamos rodykli ir struktros element galimos kombinacijos: Iraika a.b a->b *a.b k kreipiamasi objekto a element b objekto, kurio adresas yra rodyklje a, element b duomen, kurio adresas yra objekto a elemente b (elementas b turt bti rodykl) (*a).b *(a.b) Ekvivalentas
97
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
rodykls, galinantys kurti vairias dinamines duomen struktras: tiesinius sraus, iedinius sraus, eiles, stekus, medius, piramides. Tiesinis sraas. Paprasiausio vienos krypties tiesinio srao elemente turi bti du laukai: duomenys (elemento informacija) ir rodykl (kur atmintyje laikomas kitas i eils srao elementas). Srao ilgis gali bti keiiamas terpiant bet kurioje srao vietoje nauj element arba paalinant bet kur esant. Nupiekime vienos krypties tiesin sra grafikai.
Pirmas elementas Duomenys Rodykl elementas Duomenys Rodykl elementas Duomenys Rodykl Paskutinis elementas Duomenys Rodykl null
inant kur yra pirmas srao elementas (ufiksavus atitinkamos rodykls reikm), galima susirasti bet kur srao element. Paskutiniame elemente esaniai rodyklei priskiriama null reikm, kaip poymis, kad sraas baigsi. Pavyzdiui, sudarykime C++ program gyventoj, kuri pavard prasideda raide A, telefon numeri sraui kaupti: // vienos krypties duomen srao sudarymas
#include <iostream> #include <string> using namespace std; struct telsar { string pavarde, adresas, tnr; telsar *kitorod; }; main() { telsar *p1, *x, *y; p1 = 0; do { x = new telsar; getline (cin, (*x).pavarde); // galima rayti ir x->pavarde getline (cin, (*x).adresas); getline (cin, (*x).tnr); (*x).kitorod = 0; if (p1 == 0) p1 = x; // ufiksuojam pirmo elemento adres p1 else (*y).kitorod = x; y = x; } while ( (*x).pavarde [0] == A );
98
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
if (y == p1) // jei nra n vieno elemento su A pavarde { cout << Nera ne vieno elemento << endl; exit(1); } x = p1; // toliau ivedame ekran srao elementus do { cout << (*x).pavarde << \t << (*x).adresas << \t << (*x).tnr << endl; x = (*x).kitorod; } while ( x != 0); return 0; }
Sudarykime kit program, kuri i sudaryto srao alina element su nurodyta pavarde. Pavard veskime klaviatra. // vienos krypties duomen srao elemento alinimas #include <iostream> #include <string> using namespace std; struct telsar { string pavarde, adresas, tnr; telsar *kitorod; }; main() { telsar *p1, *x, *y; p1 = 0; string salinti; // toliau vedam sra kaip ir prie buvusioje programoje do { x = new telsar; getline (cin, (*x).pavarde); getline (cin, (*x).adresas); getline (cin, (*x).tnr); (*x).kitorod = 0; if (p1 == 0) p1 = x; // p1 ufiksuojam viso srao pradios adres else (*y).kitorod = x; y = x; } while ( (*x).pavarde [0] == A ); if (y == p1) p1=0; // jei nra n vieno elemento su A pavarde
99
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// toliau i sukaupto srao aliname nurodyt element x = p1; y = 0; if (x == 0) { cout << Sarase nera ne vieno elemento << endl; system (PAUSE); exit(1); } cout << Iveskite pavarde, kurio duomenis salinsite: ; getline (cin, salinti); // vedame, ka reikes alinti do // iekom alinamojo elemento adreso { if ( (*x).pavarde != salinti ) { y = x; x = (*x).kitorod; } } while ( (x != 0) && ( (*x).pavarde != salinti) ); if ( (*x).pavarde == salinti ) // jei alinam: { if ( (*x).kitorod == 0 ) (*y).kitorod = 0; // paskutin else if (x == p1) p1 = (*x).kitorod; // pirm else (*y).kitorod = (*x).kitorod; // vidurin } else cout << Tokios pavardes sarase nera << endl; // ivedame ekran sra be jau paalinto elemento x = p1; do { cout << (*x).pavarde << \t << (*x).adresas << \t << (*x).tnr << endl; x = (*x).kitorod; } while ( x!=0); return 0; } Tiesinio srao elemente pavartojus dvi rodykles, kuri viena bt skirta nurodyti kitam i eils einaniam srao elementui, o antra - prie einaniam srao elementui, turtume dviej krypi tiesin sra. Pavaizduokime j grafikai.
Pirmas elementas Duomenys Rodykl-p null Rodykl-a elementas Duomenys Rodykl-p Rodykl-a elementas Duomenys Rodykl-p Rodykl-a Paskutinis elementas Duomenys Rodykl-p Rodykl-a null
100
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Trumpai apibdinkime kitokias dinamines duomen struktras: iedinis sraas yra panaus tiesin sra, taiau jame yra papildomas ryys (nuoroda) tarp paskutinio ir pirmo element; eil vienos krypties tiesinio srao variantas, kuriam leistini tik du veiksmai: naujo elemento pridjimas tik srao gale ir elemento alinimas tik nuo srao pradios; stekas vienos krypties tiesinio srao variantas, kuriame naujas elementas gali bti pridtas tik gale, o paalintas taip pat tik nuo galo. is elementas vadinamas steko virne; medis - tai pasirinktos konfigracijos hierarchin duomen struktra. Medio elementai vadinami virnmis (mazgais); piramid (surikiuotas medis) tai medis, kurio virni reikms visada nemaja arba nedidja pereinant kit lyg.
101
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ia mes apibrme keturis duomen tipus tokias vardais: SIMBOLIS, ZODIS, pChar ir laukas, kurie reikia char, unsigned int, char* ir char [50] tipus atitinkamai. Juos toliau galima naudoti skelbiant kintamuosius: SIMBOLIS raid, sp, *ptc1; ZODIS pavad; pChar ptc2; laukas vrd; iame pavyzdyje paskelbtas kintamasis ptc2 bus char tipo rodykl, o kintamasis vrd bus char tipo masyvas, turintis 50 element. typedf sakiniu nekuriami nauji tipai. Juo kuriami tik sinonimai esamiems tipams. Todl, pvz., ZODIS ir unsigned int faktikai nurodo tok pat duomen tip. typedef gali bti naudojamas duomen tipui pavadinti slaptaodiu, kas danai daroma programose. Jis taip pat gali bti naudingas, kai reikia suderinti duomen tipus skirtingose programos versijose arba kai vietoje pernelyg ilgo arba painaus tipo norime sukurti patogesn.
102
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
union bendros_srities_vardas { tipas1 elemento_vardas1; tipas2 elemento_vardas2; tipas3 elemento_vardas3; ... } objekt_vardai; Visi union sakinyje paskelbti elementai atmintyje bus talpinami toje paioje srityje. Jos dydis yra lygus didiausiam bait kiekiui, kuris reikalingas kakuriam i vardint kintamj. Pvz.: union mantip { char c; int k; float f; } mt; Apibria tris elementus: mt.c mt.k mt.f
kurie yra skirting tip. Kadangi j reikms saugomos toje paioje atminties vietoje, tai keiiant vieno elemento reikm keisis ir kit element reikms. Pastebkime, kad mantip yra bendros atminties srities tipo vardas, o mt io tipo kintamojo vardas. Tokio tipo kintamj galime paskelbti ir daugiau, pvz.: mantip dsa, laukas; Vienas i union naudojimo pavyzdi: union svk { long k; struct { short virs; short apat; } s; char c [4]; } mix; ia paskelbti trys elementai mix.k, mix.s ir mix.c, kurie naudos t pai 4 bait dydio atminties srit. Vienu atveju juose laikysime long tipo kintamj, kitu du
103
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
short tipo kintamuosius, o treiu char element masyv. Schemikai tai galima bt pavaizduoti taip: mix mix.k mix.virs mix.c [0] mix.c [1] mix.apat mix.c [2] mix.c [3]
ia dert prisiminti tai, kad simenant sveikuosius skaiius j dvejetainio pavidalo jauniausios skiltys dedamos kairje esant bait, o vyriausios skiltys deinje esant. Todl, pvz., priskyrus mix.k = 97, taiau ivedant mix.c [0], ekrane matysime raid a (raids a kodo skaitin reikm yra lygi 97). Ir atvirkiai, priskyrus mix.c [0] = a, taiau ivedant mix.k, ekrane gausime 97.
Skirtumas tarp i dviej programos fragment yra tas, kad kairiajame yra nurodytas union srities vardas kaina, o deiniajame ne. Todl i srii elementus litai ir eurai kreipiamasi nevienodai. Kairje esanio programos fragmento atveju kreipiamasi knyga.kaina.litai knyga.kaina.eurai o deinje esanio fragmento atveju knyga.litai knyga.eurai
104
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Prisiminkime, kad union nra tas pat kaip struct. Elementai litai ir eurai uims fizikai t pai atminties srit. Todl kain galima bus nurodyti arba litais, arba eurais, bet ne abiem valiutomis i karto.
Ivardintj reikmi tipas atitinka skaitinio tipo kintamuosius, todl ioms reikmms visada priskiriama ir skaitin reikm. Nesant papildom nurodym, pirmos reikms ekvivalentas yra 0, antros 1 ir t. t. Ms pavyzdyje ivardijimo tipe spalvos ivardintosios reikms gyja tokius skaitinius atitikmenis: juoda 0, melyna 1, zalia 2 ir t.t. Bet kuriai ivardintjai reikmei galima aikiai nurodyti j atitinkant sveikj skaii. Jei po ivardintosios reikms sveikasis skaiius nenurodomas, tai tokios ivardintosios reikms skaitinis atitikmuo yra vienetu didesnis nei prie buvusios ivardintosios reikms. Pvz.:
enum menesiai { sausis=1, vasaris, kovas, balandis, geguze, birzelis, liepa, rugpjutis, rugsejis, spalis, lapkritis, gruodis } m2007;
105
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
kreipties_atributas2: narys2; ... } objekto_vardas; ia klass_vardas tai klass pavadinimas, o objekto_vardas tai ios klass objekt vard sraas (ioje vietoje jo gali ir nebti). Klass nariai tai kintamj ir funkcij apraai, prie kuriuos nurodomi kreipties atributai. Kreipties (prieigos) atributas nurodomas baziniu odiu private, public arba protected. Juo apibriama klass nario galiojimo sritis:
- private narius gali kreiptis tik kiti tos klass nariai arba j draugai (friend,
apie juos vliau); - protected narius gali kreiptis tik kiti tos klass nariai arba j draugai, o taip pat ta klase paremt ivestini klasi nariai; - public narius galima kreiptis i bet kurios vietos, kur yra objekto galiojimo sritis. Kai kreipties atributas nenurodomas, numatytasis yra private. Pvz.: class Cstaciakampis { int x, y; public: void nurodyk_krastines (int, int); int plotas (void); } sta; ia apibrme klas (kitaip tariant tip), kuri pavadinome Cstaciakampis, ir ios klass objekt (kitaip tariant kintamj) sta. ioje klasje yra keturi nariai: du int tipo kintamieji (x ir y) ir dvi public kreipties funkcijos (nurodyk_krastines ir plotas). ia nurodme tik funkcij prototipus (antrates), nors galima bt rayti ir vis funkcijos programos tekst. Kadangi kintamiesiems x ir y kreipties atributo nenurodme, tai jiems galioja numatytasis private.
106
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Cstaciakampis klass sta objekto narius programoje galima kreiptis kaip prastus kintamuosius ar funkcijas, inoma, prie j vard dar nurodant objekto vard. Tarp i vard dedamas takas. Pvz.: sta.nurodyk_krastines (3,4); mapl = sta.plotas(); Tiesiogiai kreiptis ms pavyzdio narius x ir y negalsime, nes jie yra private kreipties. Panagrinkime sudtingesn programos su Cstaciakampis klase pavyzd: // Programos su klase pavyzdys #include <iostream> using namespace std; class Cstaciakampis { int x, y; public: void nurodyk_krastines (int,int); int plotas () { return (x*y); } }; void Cstaciakampis :: nurodyk_krastines (int a, int b) { x = a; y = b; } int main () { Cstaciakampis sta; sta.nurodyk_krastines (3,4); cout << "plotas: " << sta.plotas(); return 0; }
plotas: 12
ioje programoje nauja yra tai, kad joje pavartotas priklausymo klasei operatorius ( :: - du dvitakiai) funkcijos nurodyk_krastines aprae. Pastarasis operatorius naudojamas tada, kai klass nario apraas yra u klass rib, ir jis padeda atskirti klasms priklausanias funkcijas nuo prast globali funkcij. Pastbkime, kad ioje programoje klass Cstaciakampis viduje yra visas funkcijos plotas tekstas, nes jis labai paprastas, o funkcijos nurodyk_krastines - tik prototipas.
107
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Priklausymo klasei operatorius (::) nurodo, kuriai klasei aprayta funkcija priklauso. Todl tokioje funkcijoje galima naudoti tos klass private kreipties narius, kaip kad x ir y ms pavyzdyje. Jei klasje yra private kreipties nari, tai jiems reikms gali bti priskiriamos ir keiiamos tik tos klass funkcijomis. Tokiu bdu likusiose programos vietose tiesiogiai j reikmi keisti negalima. Tai padeda apsaugoti toki nari reikmes nuo nenumatyto pakeitimo. Didelis klasi privalumas yra tas, kad, kaip ir kitoki tip atveju, mes galime paskelbti kelet vienos klass objekt. Pvz., emiau pateikiamoje programoje klass Cstaciakampis objekt turime du: stc1 ir stc2: // viena klas, du objektai #include <iostream> using namespace std; class Cstaciakampis { int x, y; public: void nurodyk_krastines (int,int); int plotas () {return (x*y);} }; void Cstaciakampis :: nurodyk_krastines (int a, int b) { x = a; y = b; } int main () { Cstaciakampis stc1, stc2; stc1.nurodyk_krastines (3,4); stc2.nurodyk_krastines (5,6); cout << "stc1 plotas: " << stc1.plotas() << endl; cout << "stc2 plotas: " << stc2.plotas() << endl; return 0; }
Pastebkime, kad kreipiniai stc1.plotas() ir stc2.plotas() duoda skirtingus rezultatus. Taip yra todl, kad kiekvienas Cstaciakampis klass objektas operuoja su jam paskirtais kintamaisiais x ir y bei funkcijomis nurodyk_krastines ir plotas. Tai yra pagrindin objektinio programavimo idja, kai duomenys ir funkcijos yra objekto nariai. Pastebkime, kad kreipiniuose stc1.plotas() ir stc2.plotas() jau nebereikjo argument. ios funkcijos atitinkamai naudojo sav objekt stc1 ir stc2 duomenis.
108
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Matome, kad io pavyzdio programa duoda tokius paius rezultatus kaip ir ankstesnioji. Taiau ia mes paalinome funkcij nurodyk_krastines ir vietoje jos traukme konstruktori, kuris atlieka panaius veiksmus: inicializuoja x ir y, priskirdamas objekt stc1 ir stc2 aprauose nurodytas reikmes.
109
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Atkreipkime dmes tai, kaip nurodytos reikms perduodamos konstruktoriui skelbiant objekt:
Cstaciakampis stc1 (3,4); Cstaciakampis stc2 (5,6);
konstruktori, kaip funkcij, atvirai kreiptis negalima. Jis savo vaidmen atlieka tik tuomet, kai skelbiamas naujas duotos klass objektas. Tikriausiai pastebjote, kad prie konstruktoriaus prototip klass aprae ir konstruktoriaus aprae void nevartojamas. Destruktorius atlieka prieing vaidmen nei konstruktorius. j kreipiamasi automatikai, kai norima paalinti nebereikaling objekt (pvz., baigus darb kuriai nors programos funkcijai, naudojaniai lokaliuosius objektus). Destruktoriaus vardas turi bti toks pat, kaip ir klass vardas, taiau prie j dar turi bti bangels simbolis (~). Destruktoriai ypa naudingi yra tuomet, kai objektai naudoja dinamin atmint. Kai paskelbtas objektas tampa nebereikalingas, objekto uimama atmitis ilaisvinama. Pvz.:
// konstruktoriaus ir destruktoriaus pavyzdys #include <iostream> using namespace std; class Cstaciakampis { int *x, *y; public: Cstaciakampis (int,int); ~Cstaciakampis (); int plotas () { return (*x * *y); } }; Cstaciakampis :: Cstaciakampis (int a, int b) //konstruktorius { x = new int; y = new int; *x = a; *y = b; } Cstaciakampis :: ~Cstaciakampis () { delete x; delete y; } // destruktorius
int main () { Cstaciakampis stc1 (3,4), stc2 (5,6); cout << "stc1 plotas: " << stc1.plotas() << endl; cout << "stc2 plotas: " << stc2.plotas() << endl; return 0; }
110
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ia objektas stc2 paskelbtas nenurodant argument. Todl jis inicializuojamas parametr neturiniu konstruktoriumi, kuris x ir y priskiria reikm 5. Pastebkime, kad skelbiant nauj objekt ir naudojant numatytj (default) konstruktori (pastarasis neturi parametr), skliaust () rayti nereikia: Cstaciakampis stab; Cstaciakampis stab (); // teisingai // neteisingai!
111
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
jau bus neteisingas, nes klas turi aikiai nurodyt konstruktori, kuris pakeiia numatytj. Taiau kompiliatorius sukuria ne tik numatytj konstruktori, kai jo mes nenurodome, bet dar pateikia tris specialias funkcijas: kopijuojantj konstruktori, kopijuojantj priskyrimo operatori ir numatytj (default) destruktori. Kopijuojantysis konstruktorius ir kopijuojantysis priskyrimo operatorius nukopijuoja
112
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
visus kito objekto duomenis ir perkelia einamj objekt. Klasei Cpavyzdys kompiliatorius netiesiogiai sukurs kopijuojantj konstruktori pana : Cpavyzdys :: Cpavyzdys (const Cpavyzdys& rv) { a=rv.a; b=rv.b; c=rv.c; } Todl toliau parodyti du objekt skelbimai yra teisingi: Cpavyzdys abc1 (2,3); Cpavyzdys abc2 (abc1); /* kopijuojantysis konstruktorius duomenis kopijuos i abc1 */
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
c= &a; a.nurodyk_krastines (1,2); b->nurodyk_krastines (3,4); d->nurodyk_krastines (5,6); d [1].nurodyk_krastines (7,8); cout << "a plotas: " << a.plotas() << endl; cout << "*b plotas: " << b -> plotas() << endl; cout << "*c plotas: " << c -> plotas() << endl; cout << "d [0] plotas: " << d [0].plotas() << endl; cout << "d [1] plotas: " << d [1].plotas() << endl; return 0; } Toliau pateikiama suvestin lentel, kaip reikt suprasti kai kuriuos rodykli ir klasi operatorius ( *, &, ., ->, [ ] ), panaudotus ankstesniame pavyzdyje: iraika *x &x x.y x->y (*x).y x [0] x [1] x [n] reikm esanti adresu x x adresas objektui x priklausantis narys y objektui, kurio adresas yra rodyklje x, priklausantis narys y objektui, kurio adresas yra rodyklje x, priklausantis narys y ( ekvivalentika iraikai x->y ) pirmasis objektas, kurio adresas yra rodyklje x antrasis objektas, kurio adresas gaunamas remiantis rodyklje x esaniu adresu (n+1)-sis objektas, kurio adresas gaunamas remiantis rodyklje x esaniu adresu reikm a plotas: 2 *b plotas: 12 *c plotas: 2 d [0] plotas: 30 d [1] plotas: 56
114
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Bendrosios atminties srii union idja skiriasi nuo struct ir class, nes union saugo tik vien duomen nar duotu metu. Taiau union taip pat yra klas ir jis gali saugoti narius-funkcijas. Numatytoji kreiptis union klass narius yra public.
7 6
Faktikai static nariai turi tokias paias savybes kaip ir globalieji kintamieji, taiau j galiojimo sritis yra tik vienos klass objektai. Dl ios prieasties mes galime skelbti juos klasje, bet be inicializavimo. static poym turintys klass kintamieji inicializuojami u klass rib esaniu formaliu apibrimu, kaip parodyta turtame pavyzdyje: int Cpypke :: n=0;
115
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Kadangi n yra unikalus kintamasis, galiojantis visuose tos klass objektuose, j galima kreiptis dvejopai: kaip kakurio objekto nar arba kaip klass nar: cout << a.n; cout << Cpypke :: n; // kreipiamasi kaip objekto a nar // kreipiamasi kaip klass Cpypke nar
Klasse static poym gali turti ir funkcijos. Taiau tokios funkcijos gals operuoti tik su tos klass static kintamaisiais.
116
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// klasi ablonai #include <iostream> using namespace std; template <class T> class pora { T a, b; public: pora (T r1, T r2) { a=r1; b=r2; } T didesnis (); }; template <class T> T pora<T>::didesnis() { T gr; gr = a>b? a : b; return gr; } int main () { pora <int> aobj (100, 75); cout << aobj.didesnis(); return 0; } Atkreipkime dmes klass nario-funkcijos didesnis() apra template <class T> T pora<T>::didesnis() Jame yra net trys duomens tipo nuorodos T. Pirmasis T yra klass ablono parametras. Antruoju T nurodomas funkcijos grainamos reikms tipas. Treiasis T, kuris apskliaustas enklais <>, nurodo, kad is klass ablono parametras taip pat yra ir funkcijos ablono parametras.
100
117
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
24
118
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Funkcija keturgubas yra draugika klasei Cstaciakampis. ioje funkcijoje mes galime kreiptis vairi tos klass objekt narius x ir y, kurie yra private kreipties. Pastebkime, kad funkcijos keturgubas skelbime ir kreipinyje j pagrindinje funkcijoje (main) nra joki nuorod, kad ji bt klass Cstaciakampis narys. Ji paprastai kreipiasi private ir protected duomenis, nebdama tos klass narys. Draugikosios (friend) funkcijos gali praversti, pvz., atliekant operacijas su dviej skirting klasi objektais. Apskritai, draugikj funkcij naudojimas ieina u objektinio programavimo metodologijos rib, todl, jei tik manoma, geriau yra naudoti tos paios klass narius atliekant operacijas. Ms turtas programos pavyzdys bt trumpesnis, jei funkcija keturgubas bt klass Cstaciakampis narys.
119
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int main () { Ckvadratas kva; Cstaciakampis sta; kva.nurodyk_sona(4); sta.konvertuok(kva); cout << sta.plotas(); return 0; } iame pavyzdyje mes paskelbme klas Cstaciakampis, kuri yra draugika klasei Ckvadratas. Todl klass Cstaciakampis funkcija konvertuok gijo galimyb kreiptis klass Ckvadratas duomen sonas, kuris yra numatytosios private kreipties. Nauja ioje programoje yra dar ir tai, kad matome tui klass Ckvadratas skelbim, t.y. class Ckvadratas; Jis yra btinas, nes skelbiamos klass Cstaciakampis funkcijoje konvertuok() yra nuoroda Ckvadratas, o pati klas Ckvadratas aprayta vliau. Draugikumo tarp klasi nebus, jei to aikiai nenurodysime. Ms pavyzdyje Cstaciakampis yra draugikas klasei Ckvadratas, taiau Ckvadratas nra draugikas klasei Cstaciakampis. Jeigu reikt, tai ir pastarj draugikum galima bt nurodyti. Kita draugikumo savyb yra ta, kad jis nra perduodamas. Draugo draugas nra laikomas draugu, kol to aikiai nenurodysime. 16
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
class ivestins_klass_vardas : public bazins_klass_vardas { ivestins_klass_nariai } ia parodytas kreipties atributas public gali bti pakeistas private ar protected. Jais nurodomas minimalus kreipties lygis, kuris bus taikomas i bazins klass paveldtiems nariams. // ivestins klass #include <iostream> using namespace std; class Cdaugiakampis { protected: int x, y; // x plotis, y - auktis public: void nurodyk_matavimus (int a, int b) { x=a; y=b;} }; class Cstaciakampis : public Cdaugiakampis { public: int plotas () { return ( x * y ); } }; class Ctrikampis : public Cdaugiakampis { public: int plotas () { return ( x * y / 2 ); } }; int main () { Cstaciakampis sta; Ctrikampis trk; sta.nurodyk_matavimus (4,5); trk.nurodyk_matavimus (4,5); cout << sta.plotas() << endl; cout << trk.plotas() << endl; return 0; }
20 10
Klasi Cstaciakampis ir Ctrikampis objektai sta ir trk turi paveldtus narius i klass Cdaugiakampis. Tai duomenys x, y ir funkcija nurodyk_matavimus.
121
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Kreipties atributas protected yra panaus private. Skirtumas tarp j atsiranda tik paveldjimo atveju. Kai viena klas paveldi kitos klass narius, ivestins klass nariai gali kreiptis bazins klass protected narius, bet ne private narius. Kadangi mums reikjo, kad x ir y bt prieinamas ne tik bazins klass Cdaugiakampis nariams, bet ir ivestini klasi Cstaciakampis ir Ctrikampis nariams, vietoje private (jis yra numatytasis, kai nieko nenurodoma) panaudojome protected. Apibendrindami skirtingus kreipties tipus, emiau lentelje pateikiame, kas ir kokiu atveju gali kreiptis klass nar: Kas kreipiasi tos paios klass narys ivestins klass narys ne nariai public taip taip taip protected taip taip ne private taip ne ne
ioje lentelje ne nariai reikia bet kok kreipin i u klass rib, kaip i main() funkcijos, kitos klass ar funkcijos. Ms pavyzdyje narius, kuriuos paveldjo klass Cstaciakampis ir Ctrikampis, vienodas kreipimosi teises turi visos trys paskelbtos klass. Cdaugiakampis :: x // protected kreiptis Cstaciakampis :: x // protected kreiptis Cdaugiakampis :: nurodyk_matavimus() // public kreiptis Cstaciakampis :: nurodyk_matavimus() // public kreiptis Taip yra todl, kad ivestini klasi skelbimuose prie bazin klas rame public: class Cstaciakampis : public Cdaugiakampis { ... } Baziniu odiu public, raomu po dvitakio (:), paymimas minimalus kreipties lygis bazins klass narius, leistinas ivestinei klasei. Kadangi public reikia aukiausi kreipties lyg, todl ivestins klass kreipties bazins klass narius lygis yra toks pat kaip ir bazins klass. Jei ivestins klass skelbime prie bazin klas nurodytume protected kreipties lyg, visi bazins klass public nariai ivestinei klasei pasidaro protected lygio. Analogikai, jei nurodytume labiausiai apribojant kreipties lyg private, tai visi bazins klass nariai pasidaryt private lygio. Jei paveldint kreipties lygis prie bazin klas nenurodomas, kompiliatorius laiko, kad class baziniu odiu paskelbtoms klasms jis yra private, o struct baziniu odiu paskelbtoms public.
122
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
class Ctrikampis : public Cdaugiakampis, public Cisved { public: int plotas () { return (x * y / 2); } }; int main () { Cstaciakampis sta; Ctrikampis trk; sta.nurodyk_matavimus (4,5); trk.nurodyk_matavimus (4,5); sta.isved (sta.plotas()); trk.isved (trk.plotas()); return 0; }
124
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
16. Polimorfizmas
Skaitantieji skyri turt bti gerai susipain su rodyklmis ir klasi paveldimumu. Jei kurio nors i emiau pateikt ura prasm yra neaiki, perirkite nurodytus ios mokymo priemons skyrius: Uraas int a::b(c) {}; a->b class a : public b; irkite skyri
14. Klass ir objektai 10. Rodykls (pointers) 15. Draugikumas ir paveldimumas
125
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
class Ctrikampis : public Cdaugiakampis { public: int plotas () { return (x * y / 2); } }; int main () { Cstaciakampis sta; Ctrikampis trk; Cdaugiakampis * rodgk1 = &sta; Cdaugiakampis * rodgk2 = &trk; rodgk1->nurodyk_matavimus (4,5); rodgk2->nurodyk_matavimus (4,5); cout << sta.plotas() << endl; cout << trk.plotas() << endl; return 0; } Pagrindinje funkcijoje main mes paskelbme dvi Cdaugiakampis tipo rodykles rodgk1 ir rodgk2. Joms priskyrme objekt sta ir trk adresus. Kadangi ie abu objektai yra ivestini i Cdaugiakampis klasi tipo, tai abu priskyrimai yra teisingi. Vienintelis rodgk1 ir rodgk2 naudojimo vietoje sta ir trk ribotumas yra tas, kad rodgk1 ir rodgk2 yra Cdaugiakampis tipo, ir todl ias rodykles galima naudoti tik nariams, kuriuos Cstaciakampis ir Ctrikampis yra paveldj i Cdaugiakampis. Dl ios prieasties, kuomet programos pabaigoje mes kreipms narius plotas(), turjome tiesiogiai nurodyti objektus sta ir trk, o ne naudoti rodykles rodgk1 ir rodgk2. Kad funkcij plotas() galima bt naudoti drauge su Cdaugiakampis tipo rodyklmis, ji turt bti paskelbta bazins klass Cdaugiakampis viduje, o ne ivestinse klasse Cstaciakampis ir Ctrikampis. Bet problema yra ta, kad klasse Cstaciakampis ir Ctrikampis yra skirtingos funkcij plotas() versijos, todl perkelti j bazin klas negalima. Tokiais atvejais labai praveria virtuals klasi nariai.
20 10
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
// virtuals nariai #include <iostream> using namespace std; class Cdaugiakampis { protected: int x, y; // x plotis, y auktis public: void nurodyk_matavimus (int a, int b) { x=a; y=b; } virtual int plotas () { return (0); } }; class Cstaciakampis : public Cdaugiakampis { public: int plotas () { return (x * y); } }; class Ctrikampis : public Cdaugiakampis { public: int plotas () { return (x * y / 2); } }; int main () { Cstaciakampis sta; Ctrikampis trk; Cdaugiakampis dgk; Cdaugiakampis * rodgk1 = &sta; Cdaugiakampis * rodgk2 = &trk; Cdaugiakampis * rodgk3 = &dgk; rodgk1->nurodyk_matavimus (4,5); rodgk2->nurodyk_matavimus (4,5); rodgk3->nurodyk_matavimus (4,5); cout << rodgk1->plotas() << endl; cout << rodgk2->plotas() << endl; cout << rodgk3->plotas() << endl; return 0; }
20 10 0
127
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Dabar visos trys klass (Cdaugiakampis, Cstaciakampis, Ctrikampis) turi tuos paius narius: x, y, nurodyk_matavimus() ir plotas(). Funkcija plotas() yra paskelbta kaip virtualus bazins klass narys, nes vliau ji i naujo apibriama ivestinse klasse. Taigi, odis virtual galina kreiptis ne tik bazins klass nar, bet ir ivestins klass nar, kurio vardas sutampa su bazins klass nario vardu. kurios klass nar bus kreipiamasi priklausys nuo to, kokios klass objekto adresas priskirtas bazins klass rodyklei. Klass, kuriose yra paskelbtos arba kurios paveldi virtualias funkcijas, vadinamos polimorfinmis klasmis. Neirint virtualumo, mes taip pat galime skelbti klass Cdaugiakampis tipo objektus ir kreiptis jos nuosav funkcij plotas(), kuri visada grina 0.
128
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Taiau klass, kuri objektai negalimi, nra visikai beprasms. Mes galime kurti tokio tipo rodykles ir gauti naudos i polimorfikumo galimybi. Taigi, skelbimas pavidalo: Cdaugiakampis dgk; naudojant abstrakij bazin klas nra leistinas, nes juo norime paskelbti objekt. Taiau rodykli skelbimai: Cdaugiakampis * rodgk1; Cdaugiakampis * rodgk2; yra visikai leistini. Be to, klas Cdaugiakampis turi grynj virtuali funkcij ir todl ji yra abstrakioji bazin klas. Taiau ios bazins klass tipo rodykls gali bti naudojamos ivestini klasi objekt adresams siminti. Panagrinkime sudtingesn pavyzd: // abstrakioji bazin klas #include <iostream> using namespace std; class Cdaugiakampis { protected: int x, y; public: void nurodyk_matavimus (int a, int b) { x=a; y=b; } virtual int plotas (void) =0; }; class Cstaciakampis : public Cdaugiakampis { public: int plotas (void) { return (x * y); } }; class Ctrikampis : public Cdaugiakampis { public: int plotas (void) { return (x * y / 2); } };
129
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int main () { Cstaciakampis sta; Ctrikampis trk; Cdaugiakampis * rodgk1 = &sta; Cdaugiakampis * rodgk2 = &trk; rodgk1->nurodyk_matavimus (4,5); rodgk2->nurodyk_matavimus (4,5); cout << rodgk1->plotas() << endl; cout << rodgk2->plotas() << endl; return 0; }
20 10
Pasigilin i program pamatysime, kad mes kreipms skirting, bet susijusi klasi objektus, naudodami vien rodykls tip (Cdaugiakampis*). Tai gali duoti didiul naud. Pvz., dabar mes galime paskelbti abstrakiosios bazins klass Cdaugiakampis nauj nar-funkcij, kuri ivest ekran funkcijos plotas() rezultatus, netgi jei plotas() gyvendinamosios dalies klasje Cdaugiakampis nra. /* abstrakioji bazin klas gali kreiptis grynuosius virtualius narius */ #include <iostream> using namespace std; class Cdaugiakampis { protected: int x, y; // x- plotis, y auktis public: void nurodyk_matavimus (int a, int b) { x=a; y=b; } virtual int plotas (void) =0; void isved (void) { cout << this->plotas() << endl; } }; class Cstaciakampis : public Cdaugiakampis { public: int plotas (void) { return (x * y); } }; class Ctrikampis: public Cdaugiakampis { public: int plotas (void) { return (x * y / 2); } };
130
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int main () { Cstaciakampis sta; Ctrikampis trk; Cdaugiakampis * rodgk1 = &sta; Cdaugiakampis * rodgk2 = &trk; rodgk1->nurodyk_matavimus (4,5); rodgk2->nurodyk_matavimus (4,5); rodgk1->isved(); rodgk2->isved(); return 0; } Bazins klass Cdaugiakampis naryje-funkcijoje isved() pavartotas bazinis odis this, atitinkantis rodykl. Jis gyja to objekto rodykls reikm, kuris yra apdorojamas. Virtuals nariai ir abstrakiosios klass suteikia C++ kalbai polimorfines charakteristikas ir daro objektin programavim labai naudingu instrumentu dideliuose projektuose. inoma, ia mes susipainome tik su paprastu i savybi panaudojimu. ios savybs gali bti taikomos objekt masyvams ir dinaminiams objektams. Pabaigai pateikiame t pat pavyzd, taiau su dinaminiais objektais: // dinaminis atminties skyrimas ir polimorfizmas #include <iostream> using namespace std; class Cdaugiakampis { protected: int x, y; // x plotis, y - auktis public: void nurodyk_matavimus (int a, int b) { x=a; y=b; } virtual int plotas (void) =0; void isved (void) { cout << this->plotas() << endl; } }; class Cstaciakampis : public Cdaugiakampis { public: int plotas (void) { return (x * y); } }; 20 10
131
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
class Ctrikampis: public Cdaugiakampis { public: int plotas (void) { return (x * y / 2); } }; int main () { Cdaugiakampis * rodgk1 = new Cstaciakampis; Cdaugiakampis * rodgk2 = new Ctrikampis; rodgk1->nurodyk_matavimus (4,5); rodgk2->nurodyk_matavimus (4,5); rodgk1->isved(); rodgk2->isved(); delete rodgk1; delete rodgk2; return 0; } Pastebkime, kad rodykls rodgk1 ir rodgk2 yra Cdaugiakampis tipo, o patys objektai yra paskelbti dinamikai, nurodant tiesiog ivestini klasi tipus.
20 10
132
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
duomenis, po to skaito juos i sukurto failo ir iveda ekran. Funkcijose write() ir read() uraas (char*) nurodo kompiliatoriui, kad parametro rodykls reikm, pvz., &B, gali nurodyti bet kokio tipo duomenims skirt adres. // write() ir read() funkcij naudojimo pavyzdys #include <iostream> // i ios bibliotekos imami cin, cout #include <fstream> // i ios bibliotekos imami ifstream, ofstream, write, read using namespace std; struct Studentas { char pav [20]; int metai; float ugis; }; int main() { Studentas A; Studentas B = {"Pavardenis", 21, 187.5}; cout << B.pav << " " << B.metai << " " << B.ugis << endl; ofstream R ("c:\\katalog\\duom1.d"); ifstream D ("c:\\katalog\\duom1.d"); R.write ( (char *)&B, sizeof(Studentas) ); // rao fail duom1.d R.close(); D.read ( (char*)&A, sizeof(Studentas)); // skaito i failo duom1.d cout << A.pav << " " << A.metai << " " << A.ugis << endl; D.close(); return 0;
}
write() ir read() sakiniai i atminties nurodytu adresu perduoda nurodyt bait kiek, t.y. tiek, kiek uima struktra Studentas. Faile c:\katalog\duom1.d urayt duomen vizualiai pairti negalsime, nes jie ten urayti dvejetainiu pavidalu.
133
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
Stovio poym papildius raide t (raant rt, wt, at), failas bus paruotas darbui kaip tekstinis. Stovio reikm papildius raide b ( raant rb, wb, ab), failas bus paruotas darbui kaip binarinis. Jeigu nra nei t, nei b raids, failo parengimas darbui priklauso nuo globaliojo kintamojo fmode reikms (r. fail fcntl.h). Kiekviena stovio nuoroda gali bti papildyta enklu + , pvz., r+, w+, wt+. Tai reikia, kad failai gali bti atnaujinami, t.y. leidiama juos skaityti ir rayti. emiau lentelje pateikiame pagrindini buferizuot vedimo/ivedimo funkcij prototipus (antrates). Jos yra laikomos cstdio bibliotekoje. Funkcijos prototipas (antrat) int printf (const char *f [,kintamieji]); int scanf (const char *f [,kint._atminties_laukai]); int fclose (FILE *rod); int putc (int simbolis, FILE *rod); int getc (FILE *rod); Funkcijos atliekami veiksmai Iveda ekran kintamj reikmes pagal ablon f ; veda klaviatra reikmes kintamj atminties laukus pagal ablon f ; Udaro fail Iveda simbol fail rod veda simbol i failo rod
134
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
int putw (int sk, FILE *rod); int getw (FILE *rod); char *fgets (char*s, int n, FILE *rod); int fputs (const char *s, FILE *rod); int fread (void *buf, int t, int n, FILE *rod);
Iveda skaii fail rod veda skaii i failo rod veda n simboli ilgio eilut s i failo rod Iveda eilut s fail rod veda n blok, turini po t bait, i failo rod bufer buf; funkcijos fread reikm vest blok skaiius Iveda n blok, turini po t bait, i buferio buf fail rod; funkcijos fwrite reikm - ivest blok skaiius Iveda fail rod ivardinto srao element reikmes pagal ablon f ; ablonas f ir kintamj sraas sudaromi taip pat, kaip ir funkcijoje printf veda srao element reikmes i failo rod pagal ablon f; ablonas f ir element sraas sudaromi taip pat, kaip ir funkcijoje scanf. Funkcijos fscanf reikm vest srao element reikms Tikrina skaitomo failo rod pabaig. Jei dar ne failo pabaiga, funkcijos reikm nelygi nuliui Tikrina darbo su failu rod klaidas. Jei klaid nebuvo, funkcijos reikm lygi nuliui alina fail vardas
Programai apdorojam fail vardai gali bti perduodami per pagrindins funkcijos main parametrus. Tokios pagrindins funkcijos prototipas yra: int main ( int n, char *argv [] );
135
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
ia n argument skaiius, o argv argumentams skirto eilui masyvo rodykl. Argument reikms yra nurodomos programos ikvietimo komandoje ir yra atskiriamos tarpais. Nulin indekso reikm turinioje argument masyvo eilutje uraomas paios programos pavadinimas.
1 pavyzdys. Tarkime, turime skaii fail c:\ktlg\skc.txt. Reikia vesti skaiius
i io failo, urayti juos programoje paskelbt masyv ir ivesti ekran. Toliau apskaiiuoti masyvo element sum ir ivesti j ekran. Skaiiai faile yra mogui perskaitomo tekstinio (simboli) pavidalo. #include <cstdio> // i ios bibliotekos ims FILE, fscanf, fopen, foef, printf #include <cstdlib> // i ios bibliotekos ims system using namespace std; const int Kiek = 15; // ia konstanta apribojam apdorojam skaii kiek typedef int mas [Kiek]; FILE *Fskc; void Sp (mas, int); int Suma (mas, int); int main() { mas A; int n = 0; Fskc = fopen("c:\\ktlg\\skc.txt", "r"); if (Fskc == NULL) { printf("Failas neatidarytas"); exit (); } else { while ( !feof(Fskc) && ( n < Kiek) ) { fscanf ( Fskc, "%d", &A [n] ); // veda i failo Fskc if ( !feof(Fskc) ) n++; } Sp(A, n); printf ("\n \n Suma = %d \n ", Suma(A, n)); } system ("PAUSE"); // stabdo program jos rezultatams ekrane pairti return 0; } void Sp(mas X, int n) // masyvo ivedimo ekran funkcija { int i = 0; while (i<n) printf(" %d", X [i++]); } // masyvo ivedimo ekran funkcijos prototipas // masyvo element sumavimo funkcijos prototipas
136
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
failo vesti programoje paskelbt masyv. Po to masyvo element reikmes ivesti fail c:\ktlg\kitf.txt . #include <cstdio> #include <cstdlib> using namespace std; // i ios bibliotekos ims system
const int Kiek = 15; const char finved[] = "c:\\ktlg\\pradf.txt"; const char fisved[] = "c:\\ktlg\\kitf.txt"; typedef int mas [Kiek]; void SpF (mas, int, char); int Ivesti (mas, int *);
int main() { mas A; int n = 0; if ( Ivesti(A, &n) ) { printf ("\n** Failo neatidare arba nera duomenu\n"); system ("PAUSE"); exit(1); // exit() nutraukia program } SpF (A, n, 'A'); printf("Masyvas uzrasytas i faila %s\n", fisved); system ("PAUSE"); // stabdo program jos eigos praneimams pairti return(0); } int Ivesti (mas A, int *n) // vedimo i failo funkcija { FILE *Fin; Fin = fopen(finved, "r"); if ( Fin == NULL ) { printf ( " ** Failas neatidarytas" ); return 1; }
137
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
else while ( !feof(Fin) && (*n < Kiek) ) { fscanf(Fin, "%d", &A [*n]); if (!feof(Fin)) (*n)++; } fclose (Fin); if ( (*n) == 0 ) { printf ( " ** Faile nera duomenu" ); return 1; } return 0; } void SpF (mas X, int n, char R) // ivedimo fail funkcija { FILE *Fis; int i = 0; Fis = fopen (fisved, "w"); if (Fis == NULL) { printf ( "Failas neatidarytas isvedimui" ); exit(1); } else { while (i < n) fprintf (Fis, "%c[%2d]=%4d\n", R, i, X [i++]); fclose (Fis); } }
5 6 98 -5
138
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
altiniai
[Sou06] [Vid02] Juan Soulie. C++ Language Tutorial. 2006. http://www.cplusplus.com/doc/tutorial/ A. Vidinas. C++ ir C++ Builder pradmenys. Smaltijos leidykla, 2002.
C++ [BBK+01] J.Blonskis, V.Buknaitis, J.Konien, D.Rubliauskas. praktikumas. Kauno technologijos universitetas. Praktins informatikos katedra. Kaunas, 2001.
139
Vilniaus universitetas, Matematikos ir informatikos fakultetas, Program sistem katedra Valdas Undznas. INFORMATIKA. Programavimas C++ kalba. Mokymo priemon, Vilnius 2009 ________________________________________________________________________________________________________________
140