C programavimo kalbos ypatybės

1. I-OJI PASKAITA: Pradinės pastabos

1.1. C programavimo kalbos ypatybės

• Gerai išvystyta aukšto lygio programavimo kalba.• Dauguma (vos ne visos) komercinės programos parašytos būtent C arba C++ kalba. De facto tai pramoninių programų rašymo standartas• Kada atsirado C kalba? 1969 metais išleista C kalbos pirma versija. Sukurta kaip sudėtinė UNIX operacinės sistemos dalis. Vėlesnės UNIX versijos parašytos C kalba• Kodėl pavadinta C? Buvo dvi ankstesnės versijos – A ir B, bet jos buvo nevykusios. Iš trečio karto pasisekė sukurti pasisekusią programavimo kalbą. Todėl ir pavadinimas C.• C – tai nepriklausoma nuo mašinos tipo procedūrinė programavimo kalba• Koks skirtumas tarp C ir C++? C++ – tai objektinis procedūrinės programavimo kalbos C poaibis• Kokias programas galima parašyti naudojant C/C++?

1.2. Programavimo kalbų klasifikacija

• Kas yra kalba ? Ar pvz. matematika kalba ? • Kokios kalbos yra natūralios ir kokios dirbtinės ?• Kodėl programos nerašomos natūralia kalba ? Kas nulėmė tokią programavimo kalbų struktūrą kokia yra dabar ?

• Žemo lygio programavimo kalbos:• – mašininiai kodai• – asembleriai (ypatybės ?)

• Aukšto lygio programavimo kalbos:• -procedūrinės: Fortran, Pascal, C• -interpretatoriai: Basic• objektinės: C++, Java, Delphi (ypatybės ?)

1.3. Programavimo priemonių rinkinys

• Ką reikia turėti norint parašyti veikiančią programą ?

Trys pagrindiniai komponentai: Redaktorius – tam, kad parašyti programos išeities kodą. Tinka bet koks redaktorius (pvz. Microsoft Word), bet dažniausiai naudojami specializuoti Kompiliatorius – tam, kad parašytą programos kodą paversti į mašininius kodus, taip vadinamą objektinį modulį Linkeris – kad prie objektinio modulio prijungti kitus objektinius modulius, bibliotekose surinktą kodą ir gauti vykdomąją programą.

• Šiuolaikinėse sistemose dažniausiai naudojamos integruotos sistemos, apjungiančios visus tris komponentus• Vis dažniau naudojamas vizualinis programavimas. Tačiau sunkiausią dalį programuotojas vis tiek turi padaryti pats

1.4. C kalbos programavimo priemonės

Yra sukurta daug programavimo priemonių rašyti programas C kalba: Nemokamos: gcc kompiliatorius, Mars C, lcc ir t.t.  Komercinės: Microsoft C, Borland C, Symantec C ir t.t.  Įprastinės: Turbo C, Borland C, Symantec C Vizualinio programavimo: Microsoft Visual C, Borland C Builder

• Kurios geriausios ? Tos, prie kurių labiausiai esi pripratęs ir gali greičiausiai pasiekti reikiamą tikslą.

1.5. Programos leksika ir sintaksė

• Programą, parašytą C kalba, sudaro vienas arba keli failai • Kiekvieną failą sudaro funkcijų ir kintamųjų bei veiksmų su jais aprašymas• Leksiškai programa susideda iš bazinių arba raktinių žodžių (angl. keywords) specialių ženklų, identifikatorių, konstantų ir komentarų• C kalboje naudojamos tiek didžiosios, tiek mažosios raidės, tačiau yra priimta eilė neoficialių susitarimų, kurių pravartu laikytis

1.6. Kintamieji ir konstantos

• Duomenys, kuriuos apdoroja kompiuteris – tai konstantos ir kintamieji• C kalboje visi kintamieji turi būti aiškiai aprašyti • Kintamojo aprašymas – tai jo tipo specifikavimas, kintamojo vardo uždavimas, eilė neprivalomų modifikatorių, kurie apibrėžia vidines kintamojo vaizdavimo ypatybes arba jo saugojimo klasę.• Aprašant kintamąjį galima nurodyti jo pradinę reikšmę • Identifikatorius – tai seka raidžių arba skaičių, kurie prasideda raide arba pabraukimo ženklu _• Kintamojo vardas – tai identifikatorius . Vardas gali būti bet kokio ilgio, bet tik pirmi 32 simboliai bus reikšminiai

1.7. Kintamųjų tipai

• Tipas – bet kuriai programavimo kalbai fundamentali sąvoka• C kalboje skiriami 4 kategorijų tipai• Tuščias tipas (void)• Skaliarinis tipas:– aritmetiniai tipai– išvardijimai (enumerations)– rodikliai (pointers)– nuorodos (references)• Tipas funkcija• Agreguotas tipas:– masyvai (arrays)– struktūros ir sąjungos– klasės (tik C++ poaibyje)

• Kitaip kintamieji gali būti skirstomi į :– pagrindinius– išvestinius

• Pagrindiniai tipai C kalboje yra: void char int float double ir jų variantai su raktiniais žodžiais short long signed unsigned • Išvestiniai tipai:– rodikliai ir nuorodos į kitus duomenų tipus– funkcijos– struktūros ir sąjungos– klasės

1.8. Duomenų tipas int

• C kalboje duomenų tipas int (integer, integral ?) savyje apjungia duomenų tipus char, short, long

• Pats duomenų tipas int yra bazinis ir priklauso nuo operacinės sistemos skiltiškumo: jo dydis lygus operacinės sistemos adresavimo skiltiškumui (16 bitų Win16, 32 bitai Win32, ateityje 64 bitai ?)• bitai min maxchar 8 -128 127unsigned char 8 0 255short int 16 -32768 32767int 16 -32768 32767unsigned int 16 0 65535long 32 -2147413648 2147483647unsigned long 32 0 4294967295

1.9. Sveiko tipo konstantos

• Sveiko tipo (int) konstantos gali būti užrašomos dešimtaine, aštuntaine arba šešioliktaine sistema:• 15,5,65,156,253• 015,05,065,0156,0253• 0x15,0x5,0x65,0x156,0x25af• Dešimtainės konstantos paprastoje formoje suprantamos kaip short int kintamieji. • Jeigu reikia užrašyti didesnius kintamuosius, reikia naudoti tipo modifikatorius U(u) – unsigned arba L(l) – long

• Pvz.: negalima rašyti 40156 , 1256789, -35674 ir t.t.• Reikia rašyti 40156u, 1256789l, -35674l ir t.t.• Galima naudoti tiek U ir L, tiek u ir l

1.10. Slankaus kablelio konstantos

• Sveikais tipais negalima aprašyti trupmeninių skaičių: reikia naudoti slankaus kablelio tipus• C kalboje naudojami trys slankaus kablelio duomenų tipai: float, double, long double

bitai min max tikslumasfloat 32 3,4*10-38 3.4*1038 7double 64 1.7*10-308 1.7*10308 15long double 80 3.4*10-4932 3.4*104932 19

1.11. Kintamųjų aprašymo pavyzdžiai

Keli kintamųjų aprašymo pavyzdžiai:• int i; • signed short a; unsigned short k;• short a, b=125, abcd=0xabcd;• unsigned char b1=156;• float bb, c=0.0,z=1.e-5; • double pi=3.1415928;• long double c1; double _z1erw=123.4561;

1.12. Priėjimo modifikatoriai const ir volatile

• Neprivalomi modifikatoriai padeda apibrėžti kintamuosius, kurie programos vykdymo metu gali arba negali pakeisti savo reikšmes• const – negali• volatile – gali (naudojamas pagal nutylėjimą)• • Pvz: const int max_const=32767;• Naudojama, kuomet norima apsidrausti, kad programos vykdymo metu netyčia nebūtų pakeista reikalinga kintamojo reikšmė

1.13. Komentarai

• C/ C++ kalboje komentarus galima įterpti dviem būdais:1) /* ….. */ – komentarai rašomi tarp slešo ir žvaigždės ir žvaigždės ir slešo. Komentarų kiekis neribojamas2) // po dviejų slešų visa eilutė iki galo traktuojama kaip komentaraiPvz. /* aš čia dabar rašau komentaruskiek noriu tiek rašau. ir čia komentaras int a/c;dabar baigiu */int a; // o dabar komentarai , int a – čia irgi komentaras

1.14. Gero stiliaus reikalavimai

Naudoti prasmingus pavadinimus globaliniams kintamiesiems ir trumpus pavadinimus – lokaliniamsPatartina globalinių kintamųjų aprašymus paydėti trumpu komentaru• Pvz: int npending=0; // ivedimo srauto einamas ilgis• Pvz: numberOfPoints – globalinis kintamasis • nPoints – tiek globalinis, tiek lokalinis• n –lokalinis kintamasisEgzistuoja daug susitarimų ir vietinių tradicijų kaip reikėtų parinkti pavadinimus kintamiesiems įvairiose sistemose ir uždaviniuose• Būkite nuoseklūs: panašios kilmės objektams reikėtų parinkti atitinkamus pavadinimus, parodančius jų panašumus ir skirtumus• Būkite tikslūs: vardas reiškia ne tik objektą, bet ir jo prasmę !!!

1.15. Operacijos ir išraiškos

Išraiška – tai seka operandų, operacijų ir skiriamųjų ženklų.Skiriamieji simboliai: [ ] { } , ; : … * = #Išraiškas kompiliatorius interpretuoja griežtai besilaikydamas vyresniškumo taisykliųVyresniškumo taisyklės kaip matematikoje priimtos

1.16. Pagrindinės operacijos: aritmetinės operacijos

Tipinės operacijos:• Sumavimo operacija +• Atėmimo operacija –• Daugybos operacija *• Dalybos operacija /C kalbos specifinės operacijos:• Liekanos nustatymo operacija %• Inkremento operacija ++• Dekremento operacija —

1.17. Pagrindinės operacijos: poskiltinės loginės operacijos

• Vadinamos poskiltinėmis todėl, kad loginiai veiksmai atliekami su kiekviena kintamojo arba konstantos skiltimi atskirai• Yra keturios:• & – loginis IR (AND operacija)• ^ – poskiltinis sumavimas moduliu 2 (XOR operacija)• | – loginis ARBA (OR operacija)• ~ poskiltinė inversija

1 operandas 2 operandas AND OR XOR0 0 0 0 01 0 0 1 10 1 0 1 11 1 1 1 0

1.18. Pagrindinės operacijos: postūmio operacijos

• Poskiltinio postūmio operacijos: >> – postūmis dešinėn << – postūmis kairėn

Pvz: half = addr>>1;double = addr<<1;Pvz: 5 – > 101 <<1 -> 1010 -> 10 12 -> 1100>>1 -> 110 -> 6 3 -> 11 <<3 -> 11000 -> 24Priskyrimo operacija =. Pvz. a=b;1.19. Pagrindinės operacijos: loginės operacijos ir santykio operacijos

Santykio operacijos:• > – daugiau• < – mažiau• == – tapačiai lygu• >= – daugiau arba lygu• <= – mažiau arba lygu• != – nelygu

• Teisinga, jei operandas iš kairės tenkina sąlygą

Loginės operacijos:• && – loginis IR• || – loginis ARBA• ! – loginis NE• Šios operacijos naudojamos sudarant logines išraiškas, turinčias tik dvi reikšmes: 1, jei išraiška teisinga ir 0, jei išraiška neteisinga

1.20. Sąlygos operacija ? :

• Sąlygos operacija ? : apibrėžiama kaip:cond ? TRUE_statement : FALSE_statement

• Pvz: int a=4, b=3;int i; i=a>b ? a: b;

1.21. Duomenų tipų nurodymo operacija (kastingavimas)

• C kalboje duomenų tipus (operandų tipus) galima nurodyti aiškiai• Toje operacijoje kintamasis bus traktuojamas kaip nurodyta privedimo operacijoje• C++ operuojant su skirtingo tipo operandais duomenų tipus būtina kastinguoti• Kintamasis įgis nurodytą tipą tik duotoje operacijoje;

pvz.: int a=8,b=5;float var1,var2;var1=a/b; // var1=1.0;var2=(float)a/b; // var2=1.6;var2=(float)a/(float)b; // var2=1.6;

1.22. Mnimali programa C kalba

• int main() { }• int main() {}• int main(){}

Pastabos: failo pavadinimas baigiasi plėtiniu .c arba .cppTarpus kompiliatorius ignoruojaOrientuotas į leksemas, o ne pozicijas faile

1.23. Pirmos programos pavyzdys

#include

int main() {unsigned int count;count=1;printf(“Hello world !!! n count=%d”,count ); }Rezultatas: Hello world !!! count=12. II-OJI PASKAITA

2.1. Bazinio įvedimo/ išvedimo metodai

• Skirtingi metodai naudojami konsoliniame įvedime/išvedime ir programose su langais• Čia kalbame apie konsolinį I/O• C++ turi savus operatorius, C specialių operatorių neturi• Naudojamos bibliotekinės funkcijos• Kas yra biblioteka, kas yra funkcija ?• Standartinė įvedimo / išvedimo biblioteka:• #include • Konsolinio įvedimo / išvedimo biblioteka• # include

2.2. Formatuotas išvedimas

• Pavadinimas: printf()• Sinopsė:• #include • int printf(const format[,arg]…)• Aprašymas: į standartinį išvedimo įrenginį (koks įrenginys yra standartinis ?) išveda nurodytą duomenų srautą, sutinkamai su nurodytu formatu format: tai gali būti literaliniai simboliai ir transformavimo specifikatoriai:• %d – dešimtainis sveikas skaičius• %f – slankaus kablelio skaičius• %o – aštuntainis skaičius be ženklo• %x – šešioliktainis skaičius be ženklo

2.3. Formatuotas išvedimas

• Pavadinimas: printf()• Sinopsė:• #include • int printf(const format[,arg]…)• Aprašymas: į standartinį išvedimo įrenginį (koks įrenginys yra standartinis ?) išveda nurodytą duomenų srautą, sutinkamai su nurodytu formatu format: tai gali būti literaliniai simboliai ir transformavimo specifikatoriai:• %d – dešimtainis sveikas skaičius• %f – slankaus kablelio skaičius

• %o – aštuntainis skaičius be ženklo• %x – šešioliktainis skaičius be ženkloPavyzdžiai:• printf(“iveskite varda:”);• printf(“turimas akciju skaicius %dn”,num);• printf(“n sio menesio %2d diena nupirkta %3d akcijun”,diena, num);• printf(“vieneto kaina %f”, kaina);• printf(“vieneto kaina %4.2f bendra kaina %6.2fn”,kaina, total);• printf(“vienetu skaicius %d vieneto kaina %4.2d bendra kaina %6.2fn”,kiekis, kaina, total);• printf(“ | vienetu skaicius %d vieneto kaina %4.2d bendra kaina %6.2f | n”,kiekis, kaina, total);

2.4. Konsolinis įvedimas

• Pavadinimas: scanf()• Sinopsė:• #include • int scanf(const format[,arg]…)• Aprašymas: iš standartinio įvedimo įrenginio (koks įrenginys yra standartinis ?) nuskaito nurodytą duomenų srautą, sutinkamai su nurodytu formatu format:

• %d – dešimtainis sveikas skaičius• %f – slankaus kablelio skaičius• %o – aštuntainis skaičius be ženklo• %x – šešioliktainis skaičius be ženklo• %c – simbolis

• scanf(“%d”, &num);• scanf(“%f”,&price);• scanf(“%d %d”,&diena, &num);• scanf(“%4.2f %6.2f”,&kaina, &total);• scanf(“%d %f %f”,&kiekis, &kaina, &total);• scanf(“%c”,&raide);• scanf(“%d”,a[i]);• scanf(“%s” pavadin);

2.5. Simbolinis įvedimas/ išvedimas

• Pavadinimas: getchar – įvedimo funkcija• Sinopsė: • #include • int getchar(void)

Aprašymas: nuskaito ir gražina eilinį simbolį iš standartinio nuskaitymo įrenginioDiagnostika: gražina EOF simbolį, jeigu pasiektas failo galas arba klaidos simbolį, įvykus įvedimo klaidai. Visais kitais atvejais gražina nuskaitytą simbolį

• Pavadinimas: putchar – išvedimo funkcija• Sinopsė: • #include • int putchar(int c)

Aprašymas: išveda eilinį simbolį į standartinį išvedimo įrenginįDiagnostika: gražina išvestą simbolį, jeigu išvedimas atliktas sėkmingai, priešingu atveju gražina EOF simbolį.

• Pavyzdžiai#include int main() {int c;

c=getchar(); /* nuskaito simboli ir priskiria ji kintamajam c */

putchar(c);putchar(‘m’);putchar(‘t’);putchar(‘07’);}

2.6. Skaičiavimo proceso valdymo operatoriai

• Skaičiavimo procesas – tai programos operatorių vykdymo seka• Paprastai programos operatoriai vykdomi elės tvarka: iš viršaus į apačią, iš kairės į dešinę• Kartais normalią veiksmų vykdymo seką reikia pakeisti• Kam reikia pakeisti valdymo seką ? Uždavinio sprendimas reikalauja• Naudojami specialūs operatoriai – skaičiavimo proceso valdymo operatoriai• Šakojimosi operatoriai, sąlygos operatoriai, ciklo operatoriai• if, if-else, while, do while, switch – case – break, for, break, continue, goto, return

2.7. Operatorius if

• Šakojimosi operatoriai išrenka programoje galimą proceso tąsą iš eilės alternatyvų• C kalboje yra du šakojimosi operatoriai – if ir switch• if – paprasčiausias sąlygos operatorius• if operatoriaus apibrėžimas:

if(cond_expression) TRUE_statement;• cond_expession – sąlygos išraiška• TRUE_statement – išraiška, kuri vykdoma jei sąlyga teisinga

• Pavyzdžiai:• if(x>largest) largest=x;

• if( valmax) {printf(“reiksme %d iseina uz leidziamo diapazono ribun”,val);printf(“leidziamas diapazonas %d %dn”, min, max); }

• if(num<0) num=-num;

• c=getchar();if(c==‘n’) lines+=1;• ekvivalentinis if((c=getchar()) ==‘n’) lines+=1;• neekvivaletinis if(c=getchar()==‘n’) lines+=1;

2.8. Operatorius if-else

if ir else – raktiniai žodžiai• Jeigu išraiška teisinga – vykdoma pirmoji išraiška, jeigu išraiška neteisinga – pirmoji išraiška praleidžiama ir vykdoma antroji išraiška• Tiek pirmoji, tiek antroji išraiškos gali būti paprastos arba blokinės• Apibrėžimas:• if(cond_expression) True_statement;else False_statement;

• cond_expession – sąlygos išraiška• TRUE_statement – išraiška, kuri vykdoma jei sąlyga teisinga• FALSE_statement – išraiška, kuri vykdoma, jei sąlyga neteisinga

Pavyzdžiai • if(kiekis<100) printf(“atsargu kiekis mazas”);else printf(“atsargu kiekis pakankamas”);

• if(x!=0) y=y/x;else {printf(“klaida: dalyba is nulio”);y=0; }

• if(hour>=3 && hour<17)rate*=1.02;else if(hour>=17 && hour<23) rate*=1.01;else rate*=0.99;

Pastaba: operatoriai if-else yra inkliuzyviniai: į vieną if-else operatorių galima įstatyti kitą. Inkliuzyvų kiekis neribojamas

2.9. Else atskyrimo problemos: klaidų šaltinis

• if(c>’ ‘) if(c>=‘0’ && c<=‘9’) digits+=1; else count+=1;

• Kuriam if priskiriamas else ?

• if(c>’ ‘) { if(c>=‘0’ && c<=‘9’) digits+=1; } else count+=1;

2.10. Operatoriai switch-case- break

• Dažnai pasitaikantis programavimo uždavinys: išrinkti vieną alternatyvą iš daugelio galimų variantų• Tai patogu atlikti naudojant switch-case operatorių• Operatoriaus sintaksė:

switch(switch_expression) { case const1: statement1; [break;] case const2: statement2; [break;] …. case constn: statementn; [break;] [default: statemnt n+1;] }• Iliustracija

• input=getchar(); switch(input) { case ‘d’: z=z*5; case ‘a’: case ‘A’: z-=1; break; case ‘p’: case ‘P’: z+=1; break; default: printf(“neteisingas pasirinkimasn”); break; }

2.11. Ciklo operatoriai

• Ciklas – tai tų pačių veiksmų pakartojimas nurodytą skaičių kartų• C kalba turi tris ciklo užrašymo formas:

• while(cond_expression) operators;• do operators while(cond_expression);• for(init_expr; cond_expr; incr_expr) operators;

• Kuri užrašymo forma geriausia ? Priklauso nuo konkrečių sąlygų• Visomis užrašymo formomis galima užrašyti bet kurį ciklą

2.12. Besąlyginio perėjimo operatoriai

• Yra keturi besąlyginio perėjimo operatoriai C kalboje: break, continue, goto, return• Besąlyginio perėjimo operatoriai – sutikus tokį operatorių programos valdymas automatiškai perduodamas į apibrėžtą vietą• break – išeina iš duoto bloko ir tęsia vykdymą iš karto nuo sekančio operatoriaus už bloko• continue – naudojamas cikle, automatiškai pereina prie sekančios ciklo iteracijos• return – grįžta iš funkcijos. valdymas perduodamas į funkcijos iškvietimo tašką• goto label – valdymas automatiškai perduodamas į programos tašką, kurį žymi markeris label

2.13. Gero stiliaus reikalavimai

1) Formatuokite kodą taip, kad pabrėžti jo struktūrą• Blogas formatavimas:for(n++;n<100;n++) field[n++]=‘’; *i=‘’; return(‘n’);

• Geras formatavimas: for(n++;n<100;n++) field[n++]=‘’; *i=‘’; return ‘n’;

2) rašykite išraiškas natūralia forma: rašykite taip, kaip skaitytumėte• Blogai: if(!(block_id=unblock))

• Gerai: if((block_id>=actblk) || (block_id>(bitoff>>3)<<3));• Gerai: subkey=subkey>>(bitoff&0x7)); subkey>>=bitoff&0x7; Absoliučiai mįslinga konstrukcija:child=(!LC&&!RC)?0:!(LC?RC:LC);Paprastai: if(LC==0 && RC==0) child=0; else if(LC==0) child=RC; else child=LC;6) Būkite atsargūs u pašaliniais efektais: ++ tipo operacijos turi pašalinius efektus: jos ne tik gražina reikšmę, bet ir pakeičia operando reikšmę

• Blogai: str[i++]=str[i++]=‘A’; (blogai, nes nėra apibrėžta ++ operacijos vykdymo tvarka)

• Gerai: str[i++]=‘A’;• str[i++]=‘A’;

3. III-IOJI PASKAITA: Rodikliai. Nuorodos. Masyvai.

3.1. Rodiklio sąvoka

• Idėja panaudoti adresus – labai sena.• Programose rašomose mašininiais kodais arba asembleriu dažnai sutinkamas uždavinys – perkelti duomenis iš vieno adreso į kitą• Tokiose programose tai atliekama paprastai• Aukšto lygio programavimo kalbose dažnai apie adresus negalvojama, o kai kuriose ir nėra jokių priemonių operuoti su adresais • C kalboje yra abiejų būdų komponentų: tiek darbui su adresais, tiek ir ne tiesioginio adresavimo galimybių

• Kas yra rodiklis? Kintamasis, kuriame saugomas adresas• Apibrėžimas: kntamasis-rodiklis (arba tiesiog vadinama rodikliu) – ta kintamasis, skirtas adreso saugojimui atmintyje• Kam naudojami rodikliai?  Kad efektyviai prieiti prie duomenų Lanksčios programos parašymui Kintamųjų, perduodamų į funkciją, reikšmių pakeitimui Darbui su dinamiškai paskirstoma atmintimi Priėjimui prie aparatinių kompiuterio resursų arba papildomų įrenginių

3.2. Rodikliai ir nuorodos C kalboje

• C kalboje apibrėžtos dvi specialios operacijos kintamųjų adresavimui per rodikliuso operacija & – nuorodos (reference) operacijao operacija * – rodiklio (pointer) operacija

Operacijos & rezultatas – tai objekto, kuriam taikoma i operacija, adresasOperacija * – tai kreipinys į atminties ląstelę, kurios adresas saugomas tame objekte3.3. Rodiklių aprašymas, inicializavimas ir naudojimas

• Kintamasis p aprašomas kaip rodiklis į sveiko tipo kintamąjį. Tai reiškia kad jame bus saugomas sveiko tipo kintamojo adresas• int num1=3, num2=6, *p;• Visi rodikliai turi būti inicializuoti • p=&num1; • Rodiklis p dabar “rodys” į kintamąjį num1• Dabar kintamąjį num1 bus galima adresuoti tiesiogiai, naudojant priskyrimo operaciją = , arba kaip rodiklį, naudojant operatorių *

3.4. Dar apie rodiklius

• Svarbu prisiminti, kad ženklas * – tai operatorius• Kuomet jis naudojamas su dviem operandais (binarinis operatorius) – tai daugybos operatorius• Kuomet jis naudojamas kaip unarinis operatorius – laikoma, kad tai rodiklis, nurodantis į ženklą• Negalima sumaišyti • Sudėtingose išraiškose kartais gali būti painu suprasti kaip reikia perskaityti

• Pvz: p= a* *b *c **d;

3.5. Pratimai su rodikliais: operacijos & ir *

• Kas neteisinga žemiau pateiktoje programoje#iclude int main() }{int num1=100, *p;printf(“num1 is %dn”,num1);printf(“*p is %dn”,*p);}

Ar tokia programa bus sukompiliuota?Ar bus įvykdyta ?Kas bus išspausdinta ?

3.6. Rodiklių aritmetika

• Svarbu aprašant rodiklius su teisingu duomenų tipu• Naudojama padidinant / sumažinant rodiklio reikšmę, palyginant rodiklius tarpusavyje, atimant vieną rodiklį iš kito ir pan

• char *p;• *p – tai simbolis• p++ ekvivalentiška p=p+1• short *p;• *p – tai trumpas sveikas skaičius• p++ – ekvivalentiška p=p+2

3.7. Masyvai

• Masyvas – tai eilės tvarka, vienas paskui kitą, atmintyje išdėstyti vieno ir to paties tipo elementai. • Kiekvienas masyvas turi nuosavą unikalų pavadinimą • Priėjimas prie masyvo elementų atliekamas naudojant masyvo pavadinimą ir elemento eilės numerį• Pagrindinis masyvo privalumas: leidžia saugoti aibę elementų, aiškiai nenurodant kiekvieno iš elementų pavadinimų• Masyvai gali būti vienmačiai arba daugiamačiai (dvimačiai, trimačiai, ir t.t. Kada pabaiga ?)• Masyvo požymis – kvadratinių skliaustelių buvimas šalia pavadinimo: char buffer[256]; int a[3]; ir t.t.

• Pagrindinės masyvų savybės C kalboje:1) Visi masyvo elementai yra vieno ir to paties tipo2) Aprašant masyvą nurodomas jo elementų tipas, masyvo pavadinimas ir bendras masyvo elementų skaičius3) Pirmo masyvo elemento indeksas visada yra lygus 0, paskutinio n-14) Masyvo elementai į atmintį surašomi nuosekliai (pvz. 3 elementas atmintyje visada bus po 2)5) Dvimačiai masyvai surašomi eilutėmis: pirmiausia pirmos eilutės elementai, po to antros ir t.t.

• Masyvo vardas yra rodiklis-konstantė (tiesiog rodiklis) ir visada lygus masyvo pradžios adresui

3.8. Masyvo inicializavimo būdai

• C kalboje numatyti du masyvų inicializavimo būdai:• Inicializavimas pagal nutylėjimą: taikomas tik statiniams arba išoriniams masyvams • Tiesioginė elementų inicializacija:

• char array[10]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,’j’};

• char array[]={1,2,3,4,5};• char array[5]; array[0]=1; array[1]=2; array[2]=3;• char array[10]; int i; for(i=0;i<10;i++) array[i]=i;

3.9. Nuorodos į masyvo elementus

• Darbas su atskirais masyvo elementais arba indekso, arba operacijos * pagalba• Abu darbo su masyvo elementais būdai yra lygiaverčiai

• Naudojant indeksus• masyvo_vardas[sveikaskaitinė_išraiška] • Short a[15]; a[0]=5; a[2]=7; a[5]=a[0]+a[2]; a[7]=a[5];

• Naudojant rodiklius:• short a[15]; *a=5; *(a+2)=7; *(a+5)=*a+*(a+2); *(a+7)=*(a+5);

3.10. Daugiamačiai masyvai

• C kalba palaiko ir daugiamačius masyvus• Masyvo matiškumas – tai indeksų, naudojamų adresuojant masyvo elementą, skaičius• Daugiamačių masyvų elementai saugomi atmintyje dešiniausio indekso didėjimo tvarka• Dvimačio masyvo vardas yra rodiklis į rodiklių masyvą. Masyvo elementai yra rodikliai į kiekvienos eilutės pradžios elemento adresą• Matiškumų skaičius nėra ribojamas, praktiškai niekada nenaudojami didesni nei trimačiai masyvai

3.11. Programos su masyvais pavyzdys

#include int main() {const float investment=6000, interest=.085;float rate; double value[5];int year;

rate=1+interest; value[0]=investment; year=1; while(year<5) { value[year]=value[year-1]*rate; year+=1; } printf(“pradinis indelis %.2fn”,value[0]);year=1; while(year<5) { printf(“metai %d: %.2fn”,year,value[year]); year+=1; } }

3.12. Kelios pastabos apie masyvus

• C kalboje nėra atliekamas joks masyvų adresavimo korektiškumas• Tai dažna klaidų priežastis: adresuoti į tuos masyvų elementus, kurių pagal pradinį masyvo aprašymą paprasčiausiai nėra• Viena iš daugiamačių masyvų reto naudojimo priežasčių – didesnis adresavimo sudėtingumas ir didesnė klaidų tikimybė

short a[30]; for(i=0;i<30;i++) a[i]=i*i; //gerai a[30]=a[29]; // blogai , tik 30 elementu galima a[7*7]=a[5*5] // blogai

Visa atsakomybė už indeksų naudojimo teisingumą išimtinai priklauso programos autoriuiJei adresuojama į masyvo elementą su didesniu indeksu, programa nulūžta

3.13. Masyvų kopijavimas

• Masyvai turi būti kopijuojami elementas po elemento• Int prev[20],current[20];

• Neteisingai: prev=current; // kompiliavimo klaida

• Teisingai: i=0; while(i<20) { prev[i]=current[i]; i+=1; }

3.14. Inkremento ir dekremento operatoriai masyvuose

• Dėl savo patogumo ir efektyvumo inkremento/ dekremento operatoriai dažnai naudojami veiksmuose su masyvais• Prefiksinė forma ++x, –x; postfiksinė forma x++,x—• Prefiksinė forma – reikšmė pakeičiama nedelsiant, postfiksinė – reikšmė pakeičiama atlikus kitus veiksmus• x=3; y=++x; // y? x? • x=3; y=x++; // y? x? • Pvz: i=0; i=0;while( while(i• Keli pavyzdžiai: • strcpy(src,dest) – perkopijuoti vieną eilutę į kitą• strcmp(src,dest) – palyginti vieną eilutę su kita• strcat(str1,str2) – prijungti vieną eilutę prie kitos• Ir dar daug kitų funkcijų

Pavyzdys su stringais#include

int main() { int i; char first[11];

printf(“prasau ivesti varda:”); i=0; while(i<10 && (first[i]=getchar()) !=‘n’) i+=1; first[i]=‘’; printf(“ivestas vardas: %sn”,first);}

3.18. Masyvai kaip rodikliai

• Masyvų aprašymas su kvadratiniais skliausteliais paprastas ir patogus būdas tačiau turi trūkumų:• Negalima rezervuoti didelių masyvų (didesnių negu 32676 elementai)• Masyvo dydį reikia nurodyti iš karto ir negalima vėliau jo keisti (dažnai nelengva iškarto nustatyti kokio dydžio masyvo mums reikės)• Yra antras masyvų aprašymo būdas, neturintis tokių apribojimų – masyvų aprašymas per rodiklius:• Pvz: short *a; long *b;

Tačiau kol kas neužduotas masyvo dydis. Tą būtina padaryti !!!

3.19. Masyvų dydžio nurodymas

• Naudojamos standartinės funkcijos, aprašytos header faile alloc.h:• #include • Atminties rezervavimui naudojamos funkcijos malloc() ir farmalloc(), atminties atlaisvinimui naudojamos funkcijos free() ir farfree().• Atmintį atlaisvinti būtina, kai ji nėra reikalinga• Reikalingos atminties dydis šiose funkcijose visada užduodamas baitais . Todėl reikia pačiam apskaičiuoti reikalingą baitų skaičių arba pasinaudoti komanda sizeof()Masyvų dydžio nurodymo pavyzdys

• Reikia 100 elementų trumpų skaičių masyvo ir 300 elementų slankaus kablelio skaičių masyvo • Pvz:#include int main() {short *a;float *b; a=malloc(200); // nes kiekvienas short tipo elementas 2 baitai a=malloc(100*sizeof(short)); // arba taip b=farmalloc(1200); // nes kiekvienas float elementas 4 baitai b=farmalloc(300*sizeof(float)) // arba taip……free(a); farfree(b); }

3.20. Dinaminiai masyvai

• Aprašant masyvus kaip rodiklius galima pakeisti masyvui išskirtos atminties kiekį programos vykdymo metu• Tam dažniausiai naudojamos funkcijos realloc() arba farrealloc();• Dydis ir vėl nurodomas baitais• Pvz: short *a; a=malloc(10); a=realloc(a,20);• Pastaba: nepriklausomai nuo masyvo aprašymo būdo, masyvo elementus galima adresuoti abiem anksčiau nurodytais būdais

4. IV-OJI PASKAITA: Funkcijos.

4.1. Bendros sąvokos apie funkcijas

• Kas yra funkcija ?• Vieną funkcijos sąvoką žinote iš matematikos. Ką reiškia funkcija matematikoje ?• Programavime funkcija turi panašumų, bet turi ir daug esminių skirtumų• Sąvoka paprogramė (subroutine) naudota daugelyje ankstyvųjų programavimo kalbų (pvz. Fortran, PL/1, Cobol ir t.t.)• Paprogramė – tai programos dalis , gebanti atlikti analogiškus veiksmus su skirtingais kintamaisiais• Funkcija kiek platesnė sąvoka nei paprogramė

4.2. Funkcijos apibrėžimas

• Egzistuoja keletas funkcijos apibrėžimų• Funkcija – tai operatorių grupė, atliekančių išbaigtą veiksmų seką. Į funkciją galimą kreiptis pagal pavadinimą, perduoti jai argumentus ir gauti iš jos reikšmę• Funkcija – tai logikai savarankiška programos dalis, turinti savo pavadinimą, kuriai gali būti perduodami parametrai ir kuri gali gražinti reikšmę• Pirmas apbrėžimas techniškesnis, antras – labiau atspindintis reikalo turinį

4.3. Funkcijos

• C kalba parašyta programa – tai iš esmės funkcijų rinkinys. Funkcijos išdėstytos bet kuria tvarka. Faktiškai funkcijos gali būti išdėstytos keliuose failuose. • C kalbos koncepcijoje numatyti visi paprogramių tipai: funkcijos ir procedūros• Funkcijos leidžia rašyti programą moduliniu būdu: kiekviena funkcija atlieką tam tikrą uždavinį. Tokias programas žymiai lengviau skaityti• Funkcijos leidžia išvengti analogiškų veiksmų dubliavimo• Daugelis programų gali naudoti tas pačias funkcijas, todėl nereikia perrašinėti kiekvieną kartą.

4.4. Funkcijos aprašymas

Funkcijos aprašymo standartas atrodo taip:• [duomenu_tipas] funkcijos_vardas(argumentu_sarasas) { kintamuju aprasymai; ……. // funkcijos_kunas operatoriai; [return (israiska)]; }

[] – skliausteliuose pateikti neprivalomi funkcijos elementai

4.5. Funkcijos aprašymo paaiškinimas

• Laukas “duomenų tipas” nurodo funkcijos gražinamos reikšmės tipą jeigu jis nėra nurodytas, pagal nutylėjimą laikoma, kad funkcija gražina int tipo reikšmę. Jeigu lauke “duomenų tipas” nurodytas raktinis žodis void, tuomet funkcija negražina jokios reikšmės. • Laukas “funkcijos pavadinimas” – tai ypatingas rodiklio tipas, vadinamas rodikliu į funkciją. Jo reikšmė yra lygi įėjimo į funkciją pradžios adresui. Funkcijos pavadinimas be to yra identifikatorius ir sudaromas pagal identifikatoriams C kalboje keliamus reikalavimus.• Laukas “argumentų sąrašas” apibrėžia argumentus (kartais vadinami parametrais), perduodamus į funkciją. Argumentų sąrašas gali būti sudarytas iš bet kokios duomenų tipų jų vardų kombinacijos. Argumentų skaičius neribojamas. Argumentai tarpusavyje skiriami kableliais. Jeigu argumentai nenaudojami, sąraše rašomas žodis void

4.6. Funkcijos prototipas

• C kalbos standartas reikalauja, kad dar iki pirmo funkcijos iškvietimo programoje būtų pateiktas funkcijos apibrėžimas• Toks pirminis funkcijos apibrėžimas vadinamas funkcijos prototipu.• Prototipas praneša kompiliatoriui apie gražinamos reikšmės tipą, argumentų kiekį ir tipus.• Po prototipo dedamas kabliataškis;• Dažnai prototipai talpinami į atskirus failus, turinčius plėtinį .h ir vadinamus header-failais• Standartinių funkcijų prototipai pateikti header failuose, kurie įtraukiami su direktyva include

4.7. Pirmas funkcijos pavyzdys

• Užduotis: apskaičiuoti skritulio plotą, kai spindulys r=5,10,27• Galima taip:

void main() {int r1=5,r2=10,r3=27;float s1,s2,s3;

s1=3.14159*r1*r1;s2=3.14159*r2*r2;s3=3.14159*r3*r3;}Funkcijos nenaudojamos

4.8. Formalūs ir aktualūs argumentai

• Kuomet aprašome funkcijos kūną, nurodome argumentų, kurie turėtų būti perduoti į funkciją, sąrašą. • Šie argumentai vadinami formaliais, su jais veiksmai programos vykdymo metu nebus atliekami• Kuomet iškviečiame funkciją, nurodome į funkciją perduodamų argumentų sąrašą. • Šie argumentai (tiksliau – jų kopijos) programos vykdymo metu bus perduoti į funkciją ir su jais atliekami veiksmai. Jie vadinami aktualiais argumentais.• Privalo sutapti formalių ir aktualių argumentų tipai.• Kompiliatorius pasirūpins, kad atitinkamas aktualus argumentas atsidurtų atitinkamo formalaus argumento vietoje.

4.9. Funkcijos iškvietimas

• funkcijos_vardas(argumentų sąrašas)• Vykdymas perduodamas į funkciją• Atliekami eilės tvarka funkcijos kūne aprašyti veiksmai• Įvykdžius sugrįžtama į sekančią po funkcijos iškvietimo einančią operaciją

void intro(void);int main() {……intro();…..}void intro(void) {printf(“pradedamas programos vykdymasn”);printf(“programos autorius jonukasn”” }

4.10. Funkcijos argumentai

• Naudojami informacijos perdavimui į funkciją• Į funkciją perduodamos reikšmės, o ne patys kintamieji• Yra lokaliniai funkcijos kintamieji• Iškviečiant funkciją reikia nurodyti tikslų jų skaičių, tipus, ir eilės tvarkąint main() { float amount=250, interest=0.075;print_growth(amount,interest);printf(main: amount= %.2fn”,amount); }

void print_growth(float val,float rate) {val=1+rate)*val;}

4.11. Tipų kastingavimas funkcijose

• Tipų kastingavimas naudojamas laikinam duomenų tipo pakeitimui• Naudojamas aiškiam teisingo funkcijos tipo nurodymui

float func(float x);void func1(int x);

int man() {int x;

func((float)x);funcą(x); }

4.12. Duomenų perdavimas į funkciją

• Parametrų perdavimui į funkciją egzistuoja du stiliai:1) funkcijų iškvietimas su reikšmių perdavimu (call-by-value); 2) funkcijų iškvietimas su kintamųjų adresų perdavimu (call-by-reference);

• Iškvietimas su reikšmių perdavimu – tai kintamųjų reikšmių kopijų perdavimas į funkcijos kūną. Tai niekaip neleidžia pakeisti kintamųjų reikšmes iškvietimo taške• Iškvietimas su adresų perdavimu – tai kintamųjų adresų kopijų perdavimas į funkcijos kūną. Tokiu būdu mes galime keisti reikšmes saugomas nurodytais adresais

4.13. Kintamųjų reikšmių perdavimo pavyzdys

void suma(int a,int b,int suma);

void main() {int a=5,b=7,sum=5;printf(“sum=%dn”,sum);suma(a,b,sum);printf(“sum=%dn”,sum);}

void suma(int a,int b,int suma) {suma=a+b;}

void suma(int a,int b,int suma);

void main() {int a=5,b=7,sum=5;printf(“sum=%dn”,sum);suma(&a,&b,∑);printf(“sum=%dn”,sum);}

void suma(int *a,int *b,int *suma) {*suma=*a+*b;}

4.14. Keli pavyzdžiai

• Kas neteisinga šiame funkcijos aprašyme ?

int compute(int , int ){int x;double y; ….. }

Kas bus išspausdinta įvykdžius sekančią programą ?

void square(int val);int main() {int x=5;square(x);printf(“x lygu %dn”,x);}void square(int val) {val=val*val:printf(“%dn”,val); }

4.15. Steko reikšmė

• Stekas – ta atminties sritis, kurią vykdanti programa naudojama laikinam saugojimui;

• Kuomet iškviečiama funkcija, visi šios funkcijos argumentai patalpinami į steką, po to patalpinamos esamų registrų reikšmės ir kiti parametrai• Toks argumentų, registrų ir automatinių kintamųjų rinkinys, skirtas vienai funkcijai, vadinamas freimu.• Jei iškviesta funkcija viduje iškviečią dar vieną funkciją, tai jai sukuriamas dar vienas freimas ir anksčiau steke buvę parametrai perstumiami tolyn• C kalba parašytoms programoms reikia daug steko, neretai stekas persipildo ir dėl to gali “nulūžti” programa

4.16. Operatorius return

• Gražina reikšmę į iškviečiančią funkciją return išraiška;• Nėra privalomas operatorius• Negražina jokios reikšmės jeigu naudojama išraiška return;

int main(){int len=50, width=4, area;area=area_rect(len,width);printf(“plotas lygus %dn”,area); return 0; }int area_rect(int l, in w) {return l*w; }

4.17. Masyvai kaip funkcijos argumentai

• Į funkcija neperduodama viso masyvo kopija• Perduodamas tik pirmo elemento adresas• Per šį adresą funkcija gali prieiti prie masyvo elementų, juos modifikuoti.void main() {char current[30], target[0];…stringcopy(target,current);… }

void stringcopy(char str1[], char str2[]) {int i;for(i=0; str2[i]!=‘’;i++) str1[i]=str2[i];str1[i]=‘’;}

4.18. Vienmačių masyvų perdavimas į funkciją

• Duoti du sveikų skaičių masyvai. Rasti kuriame iš jų yra daugiau teigiamų skaičių• int n_posit(const int *a, const int n) {int main() {int i,n;int a[50], b[50];

printf(“iveskite elementu skaiciu:”);scanf(“%d”,&n);printf(“iveskite elementus:”);

for(i=0;in_posit(b,n) printf(“pirame daugiau teigiamu elementu);else if ..

}

int n_posit(const int *a, const int n) {int i, count=0;for(i=0;i0) count++;return count; }

4.19. Stringų perdavimas į funkcijas

• Parašyti programą, kuri nustatytų kiek simbolių yra eilutėje

int string_elem(char *str);

void main() { char strp[256];int elem;printf(“iveskite simboliu eilute”);gets(strp);

elem=string(elem);printf(“stringe yra %d eleementun”,elem);}

int string_elem(char *str) {int elem;for(i=0;str[i]!=‘’;i++)elem++;return(elem); }

4.20. Parametrų perdavimas į funkciją main

• Kai kada reikia perduoti parametrus į pagrindinę funkciją main• tai naudoja pvz. archyvavimo programos, dirbančios iš komandinės eilutės

• [tipas] main(int argc, char **argv) { funkcijos kunas}

arba

• [tipas] main(int argc, char **argv, char **env) { funkcijos kunas}

4.21. Standartinės funkcijos

• Kiekvienoje C programų kūrimo sistemoje yra daug standartinių funkcijų• Su visa eile standartinių funkcijų jau teko susitikti: printf, scanf• Šios funkcijos yra sudėtos į bibliotekas, jų prototipai – į header-failus, kuriuos reikia įtraukti naudojant direktyvą include• Standartinės funkcijos sugrupuotos pagal tematiką į grupes, programuotojui reikėtų pasirūpinti reikalingų funkcijų paieška• Pats programuotojas taip pat gali kurti nuosavas funkcijų bibliotekas

4.22. Parametrų perdavimas į funkciją main

• Komandinės eilutės žodžiai tai transformuotos į ASCII formatą simbolių sekos, atskirtos tarpais, užduodamos programos paleidimo metu• Programos aplinka – tai seka ASCII simboliais išreikštų sekų, kuri tam prieinama programai, jos paleidimo metu• Į funkciją perduodamų parametrų prasmė:

int argc – žodžių skaičius komandinėje eilutėjechar **argv – rodiklis į rodiklių masyvą iš argc elementų. nulinis elementas – visada programos pavadinimaschar **env – rodiklis į kintamo dydžio masyvų rodiklį

Pavyzdys programos su argumentų perdavimu į funkciją main:

#include void main(int argc, char **argv) {

printf(“i programa perduota %d argumentun”,argc);printf(“ perduoti duomenys irasyti faile %sn”, argv[1]);printf(“paleista programa vadinasi %sn”, argv[0]);}

4.23. Rekursinės funkcijos

• C kalba leidžia funkcijai iškviesti pačiai save.• Funkcija, besikreipianti pati į save vadinama rekursija• Kiekvienu atveju steke išskiriama atminties sritis saugoti kintmųjų kopijas ir kitus parametrus• Klasika tapusi faktorialo skaičiavimo funkcija:

f(n) {

if(n) return n*f(n-1);else return 1; }

5. V-OJI PASKAITA. Priešprocesorius. Grafika.

5.1. Kompiliacijos etapai

• Priešprocesorius (include failai)• Išplėstinis Pradinis programos kodas • programos kodas C kalba• C kompiliatorius• Kodas asemblerio kalba• Asemblerio kompiliatorius• Objektinis kodas• Linkeris, objektų biblioteka• Vykdomas kodas

5.2. Priešprocesorius

Praktiškai kartu su kiekvienu C kalbos kompiliatoriumi pateikiamas taip vadinama priešprocesorius (angl. preprocessor)Priešprocesorius ieško jam skirtų direktyvų dar iki programos kompiliavimo pradžios ir atlieka veiksmus, kurių reikalauja panaudotos direktyvos.Priešprocesoriaus direktyvų vykdymas – tai atitinkamas programos išeities kodo sutvarkymas bet jokiu būdu ne kompiliavimas, t.y. Programos kodo vertimas į mašinines komandasPreišprocesorius – tai galinga priemonė, leidžianti pagerinti programos skaitymąVisos priešprocesoriaus direktyvos pradedamos komanda #

5.3. Priešprocesoriaus apibendrinimas

• Tai pirmas kompiliavimo etapas• Pranašumai: Skaitymo patogumas Programos palaikymo palengvinimas Lankstumas Mobilumas• Direktyvos: Pradedamos simboliu # Gali būti bet kurioje programos vietoje, nors dažniausiai naudojamos pradžioje

5.4. Prešprocesoriaus priemonės

Priemonės:• Komentarų pašalinimas• Konstantų ir makrosų (arba makrokomandų) apibrėžimas• Failų įtraukimas (file inclusion)• Sąlyginė kompiliacija (conditional compilation)

5.5. Simbolinės konstantos

• Apibrėžus simbolinę konstantą, priešprocesorius pakeičia visas faile aptiktas nuorodas į šią konstantą jos faktine reikšme• Negalima pakeisti komentarų arba dvigubų kabučių• Pvz. , jeigu programoje buvo apibrėžta simbolinė konstanta vardu MAXITEMS , visur, kur programoje priešprocesorius aptiks tokiu vardu esančią konstantą, jis pakeis ją priskirta reikšme• Reikšmė turi būti nurodyta aprašant simbolinę konstantą

5.6. Makrosai

• Makrosai (taip pat dažnai vadinami makrokomandomis) – tai trumpa programa, kuriai gali būti perduoti argumentai• Sintaksė panaši kaip ir simbolinių konstantų, tačiau makrosuose egzistuoja eilė parametrų, einančių iš karto po identifikatoriaus• Tie parametrai gali būti argumentų pavadinimai• Tarp identifikatoriaus ir atidarančio skliaustelio ( jokiu būdu negali būti tarpo• Kuomet priešprocesorius išskleidžia makrosą, jis atitinkamoje vietoje įstato kodą su atitinkamais parametrais

5.7. Makrosų tęsinys

• Jeigu makrokomandos užima daugiau negu vieną eilutę, reikia naudoti simbolį jų apjungimui• Keliems sakiniams naudokite bloką

#define SWAP(A,B) { int temp; temp=A; A=B; B=temp; }int main() { int num1=30, num2=50; if(num2>num1) SWAP(num1,num2); }

• Leksemos makrokomandose gali būti apjungtos naudojant operatorių ##• Makrososuose naudojami trigrafai – trijų simbolių sekos, kurios reiškia vieną simbolį• Trigrafai naudojami norint surinkti simboliu, kurių nėra kai kuriose klaviatūrose:

• ??= # ??> } ??- ~?? ( [ ??/ ?? ) ] ??’ ^?? < { ??! |

#define WheatBread 0#define RyeBread 1#define WhiteBread 2#define PumopernickeBread 3#define Bread(x) x## Bread

int main() {printf(“Value of WheatBread is %dn”, Bread(Wheat)); printf(“Value of RyeBread is %dn”, Bread(Rye));printf(“Value of WhiteBread is %dn”, Bread(White));printf(“%cn”, ‘??-’);}

5.8. Funkcijų ir makrokomandų palyginimas

• Greitaeigiškumas:1) Makrosai greitesni, įterpiami atitinkamose vietose2) Funkcijos lėtesnės, naudoja steką• Vykdomos programos dydis:1) Mažesnis, jei naudojamos funkcijos, kodas pasikartoja tik vieną kartą• Kiti faktoriai:1) Funkcijos gali sugražinti reikšmę operatoriuje return, makrosai negali2) Makrosai neleidžia rekursijos3) Makrosai dažnai sudėtingesni programos derinimo metu

5.9. Failų įtraukimas

#include #include “filename.xxx”

Į programą įtraukiama nurodyto failo kopija: aptikęs šią direktyvą priešprocesorius toje vietoje įdės nurodyto C kalba parašyto failo kopijąDažnai naudojama header failų įtraukimui.Header failai turi funkcijų prototipusGali būti naudojama ir bet kokių kitų programų failų įtraukimui į kompiliuojamą išeities programą

5.10. Naujo duomenų tipo pavadinimo apibrėžimas

• Komanda typedef – tai naujo, sinoniminio, pavadinimo suteikimas egzistuojančiam duomenų tipui• typedef egzistuojantis_tipas naujas_tipas• Naudojama skaitomumui ir mobilumui pagerinti• Sintaksė analogiška kintamųjų aprašymui• Rekomenduojama naudoti didžiąsias raides

typedef char BYTE;typedef unsigned short USHORT;typedef int WORD;

int main() {BYTE input;WORD buf[512];USHORT a;

}

5.11. Sąlyginė kompiliacija

• #if, #else, #elseif, #endif, #ifdef, #ifndef -tai sąlyginės kompiliacijos direktyvos• Leidžia sukurti keletą tos pačios programos versijų• Kompiliuojama ta versija, kuriai patenkinamos užduotos sąlygos• Sąlygos paprastai užduodamos naudojant direktyvą define• Kai kuriais atvejais gali būti naudojamos kitos direktyvos

#define WINDOWS32

int main() {#ifdef WINDOWS32 printf(“ Programa skirta Win32 operacinei aplinkain”);#endif

#ifdef UNIXprintf(“programa skirta Unix operacinei aplinkain”); #endif….. }

5.12. Kontroliniai pratimai

5.13. Darbas su grafika

• Informacija į standartinį išvedimo įrenginį (dažniausiai monitoriaus ekraną) gali būti išvedama dviem skirtingais režimais: tekstiniu ir grafiniu.• Grafiniame režime informacija išvedama taškais, tekstiniame – simboliais• Bet kuriuo atveju išvedimas, ypač grafiniame režime, labai priklauso nuo techninės įrangos• Negalima padaryti universalių, nepriklausančių nuo aparatinės įrangos, išvedimo modulių.• Todėl C kalboje nėra specialių grafikos apdorojimo metodų, o grafiniam išvedimui naudojamos standartinių bibliotekų funkcijos• Esminis elementas grafikos apdorojime – draiverio sąvoka• Draiveris – tai speciali programa, atliekanti tarpininko vaidmenį, t.y. Perimanti programos pateikiamus duomenis, atitinkamu būdu transformuojanti juos, ir perduodanti techniniams įrenginiams, kurie išveda atitinkantį grafinį vaizdą į ekraną.• Kaip taisyklė, savo programoje autorius turi nurodyti kokį grafinį draiverį reikia naudoti !!!• Programiniu požiūriu, bazinis grafikos elementas vadinamas pikseliu (sutrumpinimas nuo picture element).• Pikselių kiekis užduoda naudojamą grafinę rezoliuciją.• Kokius grafinius režimus (rezoliucijas) žinote ?

5.14. Darbas su grafinėmis funkcijomis

• Labai priklauso nuo konkrečios programavimo aplinkos• Mūsų funkcijos aprašytos faile graphics.h , todėl reikia naudoti direktyvą:#include • Programiniu požiūriu grafiko programavimas: nurodyti ką su kiekvienu ekrano pikseliu reikia daryti• Programavimą visada sudaro trys pagrindiniai etapai:1. Grafinio įrenginio atidarymas2. Grafikos apdorojimo veiksmų programavimas3. Grafinio įrenginio uždarymas

5.15. Grafinio įrenginio atidarymas

• Grafinio įrenginio inicializavimo funkcija: • void initgraph(int *graphdriver, int *graphmode chat *pathtodriver);

graphdriver – skaičius, žymintis grafinio draiverio pavadinimą. Galima naudoti simbolinius pavadinimus DETECT, CGA, VGA, MCGA ir t.t.gmode – kintamasis, reiškiantis pradinį grafinį režimąpathtodriver – kelias iki direktorijos, kur įrašyti grafiniai draiveriai. Pas mus c:bcbgi

Pvz: int gdriver=DETECT, gmode;initgraph(&gdriver, &gmode, ”c:\bc\bgi”);

5.16. Grafinio įrenginio uždarymas

• Pabaigus darbą su grafiniu režimu, reikia uždaryti grafinį įrenginį• Uždarymui naudojama funkcija closegraph:• void closegraph(void);• Pvz:

#include void main() {int gdriver=detect, gmode;initgraph(&gdriver, &gmode, ”c:\bc\bgi”); …. // cia rasomi garfikos apdorojimo veiksmaiclosegraph();}

5.17. Kai kurios grafinės funkcijos

Ekrano išvalymo funkcija:• void cleardevice(void);Kursoriaus pozicijos valdymo funkcijos:• void moveto(int x, int y);• void moverel(int dx, int dy);Tiesių braižymo funkcijos:• void line(int x1, int y1, int x2, int y2);• void linerel(int dx, int dy);

• void linerel(int x, int y);• Vieno pikselio išvedimo funkcija:• void putpixel(int x, int y, int color);Grafinių figūrų paišymo funkcijos: • void rectangle(int left, int top, int right, int bottom);• void circle(int x, int y, int radius);• void arc(int x, int y, int stangle, int endangle, int radius);• void drawpoly(int numpoints, int *polypoints);• void bar(int left, int top, int right, int bottom);• void fillpoly(int numpoints, int *polypoints);

5.18. Spalvų valdymo funkcijos

• Fono spalvos nustatymas: void setbkcolor(int color);• Objekto spalvos nustatymas: void setcolor(int color);• Spalva – tai sveikas skaičius iš intervalo 0 – 15 (kur 0 – juoda spalva, 15 – balta spalva).• Be to galima naudoti šiuos simbolinius spalvų pavadinimus:• BLACK , BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE.• Atskiras spalvos modifikatorius: BLINK

5.19. Teksto valdymas grafiniame režime

Teksto išvedimo funkcijos:• outtext(char *textstring);• outtextxy(int x, int y, char *textstring);Teksto dydžio, stiliaus valdymo funkcijos:• void setextstyle(int font, int direction, int charsize);• Font: TRIPLEX_FONT, SMALL_FONT, SANS_SERIF_FONT, GOTHIC_FONT• Direction: HORIZ_DIR, VERT_DIR• Charsize: 0,1 (8×8), 2 (16×16), 3 (32×32) ir t.t.

5.20. Paprastos programos su grafika pavyzdys

6. VI-OJI PASKAITA. Matomumo sritis. Kintamųjų klasės.

6.1. Matomumo sritis

• Aprašėme programoje kintamąjį, tegul int a. Kurioje programos dalyje šis kintamasis yra matomas, tai yra juo galima naudotis (priskirti reikšmes, naudoti operanduose ir pan.) ?• C kalboje egzistuoja pagrindinė taisyklė: visi kintamieji yra matomi blokuose.• Blokas – tai programos dalis, apimta riestiniais skliausteliais { }• Kiek blokų gali būti vienoje programoje ?• Kokio tipo blokai dažniausiai sutinkami programoje ? • Dažniausiai pasitaikantis blokas programose yra funkcija, tokiu atveju ir kintamasis yra matomas funkcijos ribose• Tačiau tai nėra privaloma • Funkcijos viduje galima padaryti atskirus blokus: t.y. kintamasis bus matomas tik dalyje funkcijos• Tačiau toks skaidymas naudojamas retai.• Žymiai dažniau naudojami globaliniai kintamieji – kintamieji , kurie yra matomi ne tik vieno bloko viduje, bet platesnėje programos dalyje

6.2. Lokaliniai ir globaliniai kintamieji

• Pasikartosime: kintamieji apibrėžti bloke yra matomi tik to bloko ribose• Tokie kintamieji vadinami lokaliniais • Jų priešingybė – globaliniai kintamieji• Globaliniai kintamieji yra apibrėžiami už bloko ribų (todėl nepriklauso jokiam blokui) ir yra matomi … • Kur yra matomi globaliniai kintamieji • Priklauso nuo apibrėžimo: paprastai už bloko ribų aprašyti kintamieji yra matomi duoto failo ribose.• Matomi visuose blokuose, t.y. visose tame faile aprašytose funkcijose

6.3. Globaliniai kintamieji

• Globaliniai kintamieji – vienas iš būdų perduoti į funkciją kintamuosius ir gauti iš funkcijos reikšmes.int a;void main() {int c,b; a=7; b=5; c=a+b; func(c); printf(“%dn”,a); }

void func(int c) {int b; b=a+c; a=b; }

6.4. Lokalinių ir globalinių kintamųjų vardų sutapimas

• Neretai pasitaiko situacijo, kuomet programoje yra lokalinių ir globalinių pavadinimų tais pačiais vardais:int a,b;void main() {int c; a=7; b=5; c=a+b; func(c); printf(“%dn”,a); }

void func(int c) {int b; b=a+c; a=b; }Jeigu yra lokalinis ir globalinis kintamasis tuo pačiu vardu, pagal nutylėjimą naudojamas lokalinis kintamasis.

• Jeigu norime panaudoti globalinį kintamąjį, prieš jo pavadinimą reikia parašyti modifikatorių :: (du dvitaškiai):int a,b;void main() {int c; a=7; b=5; c=a+b; func(c); printf(“%dn”,a); }

void func(int c) {int b; b=a+c; ::b=b; }

6.5. Atminties klasių apžvalga

• Atminties klasės – tai alternatyvūs duomenų saugojimo variantai• Atminties klasės:o automatiniaio registriniaio išoriniaio statiniai• Veikimo sritis: sakiniai, kuriuose galima naudoti nurodytą kintamąjį• Gyvavimo laikas: laiko tarpas, kurio metu išsaugoma kintamojo reikšmė

6.6. Automatiniai kintamieji

• Veikimo sritis: lokaliniai, blokas, aprašomi naudojant raktinį žodį auto• Gyvavimo laikas: sukuriami įeinant į bloką. Nustoja gyvuot (sunaikinami) išeinant iš bloko• Vidiniai aprašymai išstumia išorinius

void print_cube(int);int main(){ int x; x=getchar():if(x==‘c’) { ….}print_cube(100); }

void print_cube(int x) { // x zinoma tiktai funkcijoje print_cubeprintf(“%dn”,x*x*x); }

6.7. Registriniai kintamieji

• Registriniai kintamieji naudojami siekiant pasiekti aukštesnį programos veikimo našumą• Aprašomi naudojant raktinį žodį register• Kompiliatoriui generuojama užklausa, kad šis kintamasis būtų saugomas ne steke, o registre (kitaip sakant procesoriuje)• Ta automatinių kintamųjų poaibis, todėl gali būti aprašyti tik lokaliniai kintamieji • Registrų nedaug, galima priskirti tik tuos kintamuosius, kurie tikrai naudojami programoje labai dažnai• Patartina tokia galimybe naudotis tik labai patyrusiems programuotojams, nes naujokams tai kaip taisyklė neduos jokios naudos.• Šiuolaikiniai kompiliatoriai labai efektyviai optimizuoja registrinių kintamųjų priskyrimo procesą• Greitis ir efektyvumas• Naudojami procesoriaus registrai vietoj steko kintamųjų saugojimui• Naudotini funkcijų parametrams ir automatiniams kintamiesiems• Matomumo sritis ir gyvavimo laikas: kaip automatiniams kintamiesiems• Leidžiamų registrų skaičius priklauso nuo procesoriaus tipo

f(register int count, register int num) {register int i;for(i=0;i • Šis operatorius nenaudojamas niekam kitam, nes rodikliai į struktūras naudojami labai dažnai

• sp->salary=2750.50;

7.7. Alternatyvūs struktūrų aprašymo būdai

• Tego uždavimas ir kintamųjų aprašymas toje pačioje vietoje

struct emp { char name[12]; char id[8]; double salary; } prgmr employe[100], *p;

• Aprašymas be tego

struct { char name[12]; char id[8]; double salary; } prgmr, employe[100], *p;

• Tipo modifikatoriaus panaudojimas

typedef struct { char name[12]; char id[8]; double salary; } EMPLOYEE;EMPLOYEE prgmr,employe[100], *p;

7.8. Struktūros ir funkcijos

7.9. Pratimas – rodikliai į struktūras

• Prieš tai pateikta programa būtų žymiai efektyvesnė, jeigu į funkciją raise() būtų perduotas rodiklis į struktūrą, o ne pati struktūra Pakeiskite brūkšnelius, kad į funkciją būtų perduodamas rodiklis į struktūrą

#include #include “emp.h”void main() {

struct emp progmr; —– raise(struct emp —, double);

…..printf(“senas atlyginimas: %.2fn”, prgmr.salary);prgmr=raise(—- prgmr, 0.12);printf(“naujas atlyginimas: %.2fn”, prgmr.salary);}

—— raise(struct emp —person, double increase) {person—salary*=(1+increase);return person;}

7.10. Struktūrų inicializavimas

• Struktūros gali būti inicializuojamos aprašymo metu• Struktūros laukams priskiriamos reikšmės pateikiamos kaip sąrašas, atskiriamos kableliais ir apskliaudžiamos riestiniais skliausteliais• Neinicializuoti struktūrų elementai pagal nutylėjimą lygūs 0• Neinicializuoti automatinių struktūrų elementai pagal nutylėjimą nėra apibrėžti

struct course { char name[30]; int number; char nickname[30]; } title = { “c for programmers”, 1001, “my guide” };

struct mailinfo { char name[25]; char mail_addr[30]; } proj_member[]= {{“jean griffin”, “ first 25” } {“sue armani”, “second 13” }{ “frank kruk”, “boulevard 6” }};int f(void) {

static struct mailinfo admin= {“administartor”, “computer 7” };}

7.11. Struktūros su struktūromis

• Struktūros lauku gali būti struktūra• Struktūros elementu gali būti rodiklis į jos pačios tipą• Naudojama susietiems sąrašams ir medžiams• Susietas sąrašas:struct info { int num; float sum; struct info *next; };• Medis:struct node { int key; char description[50]; struct node *left, *right; };

7.12. Apjungimai

• Visi struktūrų aprašymo ir panaudojimo aspektai (tegai, šablonai, priėjimas), kurie buvo aprašyti kalbant apie struktūras, tinka ir apjungimams.• Vienintelis skirtumas – naudojamas ne raktinis žodis struct, bet raktinis žodis union.• Lietuviškai kartais vadinama apjungimais, kartais vadinama sąjungomis• Skirtingai negu struktūrose, apjungimas turi tik vieną iš savo elementų kiekvienu laiko momentu. • Apjungimas panaudoja vieną atminties sritį skirtingų kintamųjų saugojimui skirtingais laiko momentais• Faktiškai apjungimas – tai struktūra, kurios visi elementai pradedami su postūmiu lygiu 0 ir skirtingais momentais konceptualiai persidengia.

7.13. Apjungimų palyginimas su struktūromis

• Aprašymas, tegas, šablonai – viskas taip, kaip ir su struktūromis.• Aprašymui naudojamas raktinis žodis union• Duotu laiko momentu saugo tik vieną elementą• Pakankamai didelis, kad saugotų didžiausią galimą elementąstruct s_tag { union u_tag { char c; char c; int i; int i; double d; double d;} s_item; } u_item;

printf(“s_tem dydis %dn”,sizeof(s_item)); printf(“u_tem dydis %dn”,sizeof(u_item));7.14. Apjungimų pranašumai

• Apjungimai neretai įtraukiami į struktūras, o vienas iš struktūros elementų naudojamas kaip raktas, kad parodyti kuris iš apjungimo elementų bus naudojamas• Lankstumas – gali saugoti skirtingo tipo objektus atmintyje• Dažnai naudojama, kad taupyti atmintįstruct mail { char id; // a- active, r – retired union { struct { char name[30]; char dept[10]; char location[3]; } active; struct { char name[30]; char street[20]; char city_code[5]; } retired; } info; } person;

7.15. Išvardijimai

• Naudojami tuomet, kada reikia konstantų sekos ir nenorime sukurti naujo duomenų tipo. • Įvedami išvardinti tipai (enumerated types) • Aprašomi naudojant raktinį žodį enum. • Tarkime mums reikia mėnesių sekos metuose “masyvo”:

enum e_months {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}; typedef enum e_months month; month currentmonth; currentmonth = JUN; /* same as currentmonth = 6; */ printf(“%dn”, currentmonth);

• Mes išvardijame mėnesius metuose naujame tipe vadinamame month. • Mes nesukuriame naujo tipo, nes išvardijimai yra paprasti int tipo skaičiai. Todėl printf funkcija naudoja %d, o ne %s. • Dėmesio, jeigu JAN=1 pasako C kompiliatoriui išvardijimą pradėti nuo 1 vietoj 0. • Pastaba: Tai bus beveik tas pats , kas:

#define JAN 1 #define FEB 2 #define MAR 3 /* … etc … */

7.16. Struktūrų masyvo surūšiavimas

7.16. Kai kurie praktiniai patarimai: komentarai

1) Nerašykite akivaizdžių dalykų: pvz: /* gražinam SUCCESS reikšmę */ return SUCCESS; zerocount+; // padidinam zerocount reikšmę vienetu

Tokie komentarai ne padeda, o tik trukdo.

2) Komentuokite funkcijas ir globalinius kintamuosius. Kadangi globaliniai kintamieji pasirodo įvairiose programos vietose, patartina kartais priminti jų reikšmę ir paskirtį. Prie funkcijos kūno visada patartina pateikti jos trumpą charakteristiką. Jei funkcija sudėtinga, patartina nurodyti šaltinį, kuriame aprašytas algoritmas.3) Nekomentuokite blogo kodo, o perrašykite tą kodą kartais nepavykus parašyti kodo fragmento sėkmingai, jis paliekamas, tik užkomentuojamas. Tuo tarpu komentarai paliekami, ir dažnai nebeaišku kam tie komentarai priklauso.4) Neprieštaraukite kodui: paprastai parašius programą, komentarai atitinką kodo prasmę, tačiau vėliau padarius kokias nors modifikacijas, kodas pataisomas, o komentarai paliekami.5) Komentarai turi įvesti aiškumą ne sumaištį.

7.16. Kai kurie patarimai: vieningas stilius ir idiomos

• Būkite nuoseklūs naudodami atitraukimus ir figūrinius (riestinius) skliaustelius• Naudokite idiomas vieningam stiliui palaikyti: yra tam tikri stiliai – idiomos, kurie yra priimtini ir naudojami, nors yra teisingi ir kiti

Galima: a) i=0;while(i<=n-1) array[i]=1.0;b) for(i=0;i=65 && c<=90) Geriau naudoti: if(c>=‘A’ && c<=‘Z’) Dar geriau: if(isupper(c))

Objekto dydžio nurodymui naudokite programavimo kalbos priemones:#define NELEMS(array) (sizeof(array)/sizeof(array[0]))

8. VIII-OJI PASKAITA

Objektinio programavimo principai

8.1. Objektinis programavimas

• Objektiškai orientuoto (objektinio) projektavimo principai• Sąvokų įsisavinimas: klasė, objektas, sąryšis• Objektinio programavimo instrumentų panaudojimas• Projekto, sukurto naudojant objektinius principus, kokybės įvertinimas• Tinkamo modelio objektiniam projektui parinkimas• Objektinio projekto dokumentavimas (aprašymas)• Objektinio projekto gyvavimo ciklas

8.2. C ir C++ kalbos

• Sutinkami dažnai terminai – C ir C++. Tai ta pati kalba, ar dvi skirtingos kalbos ?• C – tai įprastinė procedūrinė (kartais vadinam struktūrinė) aukšto lygio programavimo kalba. Giminiškos kalbos Pascal, Fortran, PL/1 ir t.t.• C++ – tai objektiškai orientuota programavimo kalba. Giminiškos kalbos – Delphi, Smalltalk, šiek tiek Java ir t.t.• C++ sukurta panaudojant C kalbos sintaksė, leksemas ir visa iki tol sukaupta tos kalbos patirtį.• Prie klasikinių C kalbos savybių C++ buvo prijungtos objektinio programavimo galimybės• Teisinga teigti, kad C – tai C++ poaibis, realizuojantis procedūrinio programavimo principus

8.3. Kam reikalingas objektinis programavimas ?

• Visų pirma naudojamas dideliuose projektuose• Labiausiai nauda juntama, kai programinį produktą kuria dideli žmonių kolektyvai• Daugumą šiuolaikinių programų kuria būtent dideli programuotojų kolektyvai• Tačiau pakanka ir dviejų programuotojų kad nauda būtų akivaizdžiai juntama• Kolektyvinio programavimo principas – skirtingi asmenys būna atsakingi už skirtingas projekto dalis ir reikia, kad jų dalys būtų tarpusavyje suderintos• Objektinis programavimas leidžia programą rašyti objektais (realizuoti atskirais objektais), kurie su kitais objektais bendrauja per tam tikrus interfeisus

8.4. Objektinio programavimo principai

• Kuriant objektinio programavimo principus, stengtasi įvertinti žmogiško mąstymo principus• Žmonės dažnai skirsto stebimus objektus į klases, tos pačios klasės objektai turi bendrų savybių; bendresnės klasės objektus galima skirstyti į smulkesnių klasių objektus; smulkesnių klasių objektai paprastai paveldi stambesnių klasių objektų savybes ir įgyja naujų savybių• Skirtingų klasių objektai turi bendras savybes, bet jos būna išreikštos per skirtingo tipo parametrus.• Panašūs principai buvo realizuoti, kuriant objektinio programavimo principus.

8.5. Objektinio programavimo procesas

• Objektinio programavimo stilius projektuojant – tai iteracinis aplikacijos vystymas• Faktiškai tai priešingybė “kulinarinių receptų” stiliui• Projektuojant objektiniu principu reikia atlikti sekančius veiksmus: Išorinių reikalavimų nustatymas Esybių identifikavimas Jų savybių ir elgesio identifikavimas Esminių ryšių ir savybių identifikavimas

Iteracijos baigiamos, kai visas projektas tampa pinu ir korektišku

8.6. Išorinis aprašymas

• Sudaromas aukšto lygio koncepcinis projektuojamo objekto modelis

• Išorinis aprašymas: Sąskaitų tipai, kuriuos padoroja bankas1. Komercinės sąskaitos (max 7 procentai palūkanų priklausomai nuo kitų sąlygų)2. Nekomercinės sąskaitos (palūkanos nemokamos, min indėlio dydis 200) Finansinių operacijų tipai:1. Indėlio atidarymas, uždarymas, pakeitimas2. Finansinės ataskaitos sudarymas Bankomato funkcijos:1. Kortelės tikrumo patikrinimas2. Sąskaitos būklės patikrinimas3. Finansinių operacijų vykdymas

8.7. Esybių identifikavimas

• Žodyno sudarymas: Reikalavimų analizė Bendravimas su ekspertais• Esminių abstrakcijų nustatymas, kurios gali būti potencialių pakitimų šaltiniais Procedūrų abstrakcijos Duomenų abstrakcijos• Esybės, kurios žymimos daiktavardžiais: gali būti realios arba irrealios Gali būti specialiai išrastos Ne visos priskiriamos konkrečioms klasėms Bendru atveju yra kandidatais konkrečiai klasei

Esybių identifikavimo pavyzdys• Procedūros:

• Visų finansinių deklaracijų spausdinimas

• Objektai:• Komercinės sąskaitos • Nekomercinės sąskaitos

8.8. Esybių elgesio identifikavimas

• Išnagrinėti kiekvieną esybę atskirai nuo kitų• Identifikuoti duotos esybės elgesį• Esybės ribos gali būti pakeistos dėl: Kai kurių esybių didelio sudėtingumo Esybių apjungimo Kitų esybių reikšmių pasikeitimo

• Esybių elgesio identifikavimas – tai visada iteracinis procesas• Esybių identifikavimo stadija kaip taisyklė sudėtingesnė, negu esybių aibės nustatymo stadija

8.9. Esybių požymių nustatymas

• Sumažinti abstrahavimo lygį• Išnagrinėti kiekvieną esybę iš išorės• Nustatyti požymius• Nustatyti naujas esybes• Objektiškai orientuoto projektavimo principas nepalaiko grynųjų “iš viršaus – į apačią” arba “iš apačios – į viršų” projektavimo strategijų• Nustatant požymius dažnai tena grįžti į ankstesnes stadijas• Nustatant požymius galimos projektavimo proceso iteracijos

8.10. Ryšių identifikavimas

• Objektų integravimo į sistemą būdų nustatymas:– bendrumų, panašumų nustatymas– statinės ir dinaminės semantikos nustatymas– matomumo nustatymasRyšių identifikavimo metodai:Iš apačios į viršųIš viršaus į apačiąKombinuotas8.11. Objektinio projektavimo būdo apibendrinimas

• OOP procesas yra iteracinis, jame realizuota mišri projektavimo strategija• OOP palaiko projektuotojo darbą keliuose projekto abstrahavimo lygiuose• Objektinis projektavimas – tai “kulinarinių receptų knygos antitezė• Pagrindiniai OOP etapai:o išorinis projektavimas ir reikalavimų sistemai nustatymaso Esybių identifikavimaso Esybių elgesio nustatymas, jų požymių ir charakteristikų aptikimaso Ryšių ir struktūrų identifikavimas

• OOP procesas sustabdomas po užbaigto ir korektiško projekto sugeneravimo

8.12. Objekto sąvokos įsisavinimas

• Objektas yra tam tikros objektų klasės realizacija

• Objektas gali turėti būseną• Objektas gali turėti elgseną• Objektas gali turėti pavadinimą arba likti bevardis• Objektas – tai tam tikros klasės egzempliorius• Objekto matomumas yra apibotas kitų objektų atžvilgiu• Objektas gali būti nagrinėjamas specifikavimo ir realizavimo požiūriu

8.13. Objekto būsena

8.14. Objektų rolės

• Objektai gali funkcionuoti keliuose režimuose:

• Operatoriaus režimas: Operatorius veikia į kitus objektus ir nepatiria poveikio iš jų pusės. Bankinis automatas gali būti vertinamas kaip kortelių apdorojimo interfeisas• Serverio režimas. Serveris – tai toks objektas, kuris patiria išorinius poveikius ir nedaro poveikio kitiems objektams. • Tarpininko režimas. Tarpininkas – ta objektas, kuris priima kitų objektų poveikius ir pats daro poveikius kitiems objektams.

• Didelę įtaką turi poveikių seka

8.15. Objektų elgesys

• Visiškai izoliuotų objektų neegzistuoja. Objektai priima poveikius ir perduoda poveikius kitiems objektams

• Vartotojo požiūriu galima išskirti penkias poveikių klases:• Modifikatoriai – operaotoriai, kurie pakeičia objekto būseną• Selektoriai – operatoriai, kurie įgalina prieiti prie objekto būsenos• Iteratoriai – leidžia prieiti prie visų objekto dalių griežtai apibrėžta tvarka• Konstruktoriai – operatoriai, kurie inicializuoja objektą• Destruktoriai – operatoriai, kurie sunaikina objektą.

• Konstruktoriai ir destruktoriai C++ kalboje sukuriami automatiškai

8.16. Klasės

• Klasė:• Tai abstrakti sąvoka (duomenų tipas)• Apibrėžiama objektų, kurie turi panašią elgseną ir panašią struktūrą, aibei• Interfeisas aprašo išorines klasės savybes. Interfeiso elementai visada turi modifikatorių public. Interfeiso elementais gali būti:• – operatoriai• – klasių aprašymai• – konstantės• -kintamieji

• Realizacija parašo klasės sandarą. Realizacijos elementai turi modifikatorių private. Realizacijos elementai – tai:• – operatoriai• – klasių aprašymai• – konstantės• – kintamieji

• Klasė aprašoma naudojant raktinį žodį class• Konkreti klasės realizacija vadinama objektu

8.17. Klasių ir objektų ryšiai

• Klasių ryšiai• – IS-A (ryšio tipas “yra)• – HAS –A (ryšio tipas “turi”)• – USES – A (ryšio tipas “naudoja”)• – LIKE – A (ryšio tipas “panašus”)• – CREATE – A (ryšio tipas “sukuria)

Objektų ryšiai:– HAS – A– USES – A

8.18. Trys objektinio programavimo banginiai

• Dažnai teigiama, kad objektinis programavimas remiasi trimis banginiais (trimis pagrindiniais principais):• – inkapsuliacija• – paveldėjimu• – polimorfizmu

• Inkapsuliacija – tai duomenų kintamųjų) ir jų apdorojimo procedūrų susiejimas į vieną objektą. C++ kalboje inkapsuliacijos principą realizuoja klasės. Klasės susieja kintamuosius (duomenis) ir funkcijas (procedūras) veiksmams su jais į vieną objektą. C++ terminologijoje funkcijos, priklausančios klasėms, vadinamos metodais

8.19. Klasės

• C kalboje duomenys ir funkcijos apibrėžiami atskirai. Toks atskyrimas apsunkina programų struktūrinį skaidymą.• C++ įvesta nauja sąvoka – klasė. Klasė leidžia apjungti duomenis ir struktūras, kurios operuoja su jais, į vieną struktūrą. Toks apjungimas vadinamas duomenų inkapsuliacija. Inkapsuliacija leidžia paslėpti konkrečią klasės realizaciją, palengvinant programų derinimą ir modifikavimą. • Klasės apibrėžimas:class [] {< member – list>}

• < tag> – klasės pavadinimas• – klasės narių sąrašas. Funkcijos, priklausančios klasei, vadinamo funkcijomis- elementais arba metodais.• – vieno arba daugaiu tos klass objektų apibrėžimai

• Raktinis žodelis this – tai rodiklis į einamą klasės objektą. Rodiklis this yra pastovus dydis ir programoje negali būti keičiamas.• Aprašius klasę ir sukūrus tos klasės objektus, jais galima manipuliuoti. Kai kuriuos duomenis ir metodus galima padaryti nematomais už klasės ribų

8.20. Klasei priklausančių elementų matomumas

• Priėjimo prie klasės elementų valdymui naudojami trys operatoriai: public, private ir protect. • Public tipo elementai prieinami visiems klasės metodams ir kitų klasių objektams• Private tipo elementai prieinami tik tos klasės metodams• Protected tipo elementai prienami visiems tos klasės metodams ir kitų klasių objektams, bet jų prieinamumas neperduodamas paveldėjimo metu

• Šie raktiniai žodžiai aprašant klasę gali būti pateikti bet kuria tvarka, po jo turi būti dvitaškis ir visi po to aprašyti klasės elementai yra nurodyto tipo

Klasės aprašymo pavyzdys

8.21. Klasei priklausantys metodai

• Jeigu metodo kūnas yra trumpas, toks metodas dažniausiai apibrėžiamas klasės viduje. Taip pat galima vietoj iškvietimo naudoti metodo kūno įstatymą, naudojant raktinį žodį inline

• Pvz: class Line { public: void setlength(int newLength) { length= newLength; } int getLength() { return length; } private: int length; }

• Jeigu metodo išeities tekstas nėra toks trumpas, tuomet jis užduodamas už klasės ribų. Taip užduodant metodą prieš jo pavadinimą turi eiti klasės vardas ir matomumo srities operatorius ::

• Pvz: void convert:: ConvertString(void) { int i;

for(i=0; sText[i]!=‘’;i++) { sText[i]=tolower(sText[i]); }return i; }

8.22. Klasei priklausančių metodų iškvietimas

• Metodų iškvietimas:klasės_pavadinimas.metodo_pavadinimas(argumentų sąrašas); klasės_pavadinimas -> metodo_pavadinimas(argumentų sąrašas);Ką primena tokia metodų iškvietimo procedūra ?Jeigu metodas iškviečiamas iš kito tos pačios klasės metodo, tuomet klasės pavadinimo nurodyti neprivaloma.

Pvz: class A { void fun1(); void fun2(); }

A.fun1();

8.23. Metodai, nekeičiantys klasės objekto

• Jeigu metodas nekeičia objekto, kuriam yra iškviečiamas, tuomet jį galima aprašyti su raktiniu žodeliu const. • Tokie metodai negali keisti klasės elementų arba kveisti kitus metodus, apibrėžtus be raktinio žodžio const.

• Pvz: class ClassMem {• public: • void setWeight(int newWeight);• int getWeight() const;• private:• int weight; }

8.24. Statiniai metodai

• Kai kuriuos klasės elementus galima apibrėžti statiniais, naudojant raktinį žodį static.• Jiems taikomi apribojimai: • – statiniai metodai gali tiesiogiai kreiptis tik į statinius klasės narius;• – statinis metodas negali būti paskelbtas virtualiu metodu• Negalima apibrėžti statinio metodo su tuo pačiu pavadinimu ir tuo pačiu parametrų rinkiniu kaip ir statinį klasės metodą• Statinių metodų ypatybė – juos galima iškviesti nesukuriant klasės objektų• Pvz: class Circle {

public:

static void GetPi() { return fPI; } private: static float fPi; };

float fNumber;fNumber = Circle::getPi();

9. IX-OJI PASKAITA

Naujos C++ savybės. Objektų klasifikavimas.

9.1. Naujos C++ savybės

• C++ kalboje įvesta keletas naujų savybių, kurių neturi C programavimo kalba.• Šios savybės nėra objektinio programavimo dalis, tiesiog dalinis C kalbos patobulinimas• Pvz. komentarų tipas // pirmiausia buvo įvestas C++ kalboje, tačiau vėliau sėkmingai perkeliavo į C kalbą• Čia kalbėsime apie panašias C++ kalbos modifikacijas• Jų nėra C programavimo kalboje, todėl nesistenkite jų ir taikyti rašydami C programas

9.2. Įvedimas/ išvedimas

• C++ įvesti teksto įvedimo iš klaviatūros arba teksto išvedimo į ekraną modifikatoriai konsoliniame režime:• cout << – teksto išvedimas į ekraną• cin >> – teksto įvedimas iš klaviatūros

• int iNum;• cout << “iveskite sveika skaiciu”;• Cin<> “jus ivedete skaiciu”>>iNum>>”n”;

• Reikia panaudoti header failą iostream.h, t.y. , į programą įtraukti eilutę • #include

9.3. Konstantos

• Jei standartinėje C kalboje apibrėžti pastoviems dydžiams reikia naudoti priešprocesoriaus direktyvą #define, tai C++ įvestas raktinis žodis const. • Jo pranašumas prieš direktyvą tai, kad kompiliatorius visada patikrina jo tipą• Pvz: const int max_number=256;

• Pažymėtina, kad C++ const tipo objektas gali būti pakeistas:

• Pvz: int iNumber; int *const ptrNumber = &iNumber;

9.4. Nuorodos

• C++ galima apibrėžti nuorodą į objektą-kintamąjį arba klasės objektą. • Nuorodai sukurti naudojamas operatorius &• Nuoroda saugo objekto adresą, bet ją galima naudoti ir kaip patį objektą

9.5. Kintamųjų aprašymas

• C kalboje reikalaujama visus lokalinius kintamuosius apibrėžti funkcijos pradžioje, t.y. iki pirmojo toje funkcijoje atliekamo operatoriaus.• C++ šis reikalavimas suprastintas: kintamasis turi būti aprašytas iki pirmo duoto kintamojo panaudojimo programoje

• Pvz: void main() { int a, b, c; a=5; b=7; c=a+b; for (int i=0, int sum=0;i<10;i++) sum+=i;}

9.6. Atminties paskirstymas

• Standartinė C kompiliatoriaus biblioteka turi specialias funkcijas (malloc, free) atminties valdymui (rezervavimui, atlaisvinimui).• C++ kalboje atminties valdymui įtraukti specialūs operatoriai atminties valdymui – new ir delete• new operatorius sukuria užduoto tipo objektą• Operatoriaus new formatas:• new type_name [initializer] new (type_name) [initializer];

Initializer sako, kad sukurtam objektui galima priskirti pradinę reikšmę

Pvz: char *litera; int *pi; litera= new char; pi=new int(3.1415);

Kad atlaisvinti anksčiau užrezervuotą atmintį operatoriumi new, naudojamas operatorius deletepvz: delete pointer;

Operatorius new leidžia sukurti bei atlaisvinti ir dinaminius masyvus:pvz: long *pdatažnew long[100]; delete [] pointer;

9.7. Funkcijų pavadinimų perkrovimas

• C++ leidžia sukurti ir naudoti keletą funkcijų su vienodais pavadinimais, bet skirtingu parametrų rinkiniu ir skirtingu funkcijos turiniu.• C variante toks elgesys negalimas• Pvz: int Square(int a, int b); int Square (int a);int Square(nt a, int b) { return (a*b); }int Square(int a) { return(a*a); }

9.8. Funkcijos parametrų uždavimas pagal nutylėjimą

• C++ galima užduoti funkcijos argumentus pagal nutylėjimą:• Pvz:int Summa(int first, int second, int third=0, int fourth=0) { return(first+second+third+fourth); }

void main() { int value1=10, value2=20, value3=30, value4=40; int result; result=Summa(value1, value2, value3, value4); result=Summa(value1, value2, value3); result=Summa(value1, value2);

9.9. Abstrakcijų klasifikavimas

• Esybių grupavimas klasėse gali būti atliekamas atsižvelgiant į:• – apibendrinimą• – specializavimą• – agregavimą• Klasifikavimo procesas apima savyje:• – esminių abstrakcijų identifikavimą (sąskaitos, indėliai, depozitai)• – abstrakcijų išradimą (duomenų bazė, terminalo ekranas, banko valdytojas)

• Klasifikavimo procesas visada yra reliatyvus ir priklauso nuo kategorizacijos tikslų

9.10. Skirstymas į klases priklauso nuo klasifikavimo tikslų

9.11. Klasifikavimo šablonai

9.12. Mechanizmų klasifikacija

• Mechanizmas – tai suderinta objektų klasių sąveika, tenkinanti tam tikrus išorinius reikalavimus• Specifinės sudėtingų, painių objektų savybės išreiškiamos per priklausomybę nuo projektinių sprendimų• Mechanizmų klasifikacija atliekama per:– Esminių mechanizmų identifikaciją– Naujų mechanizmų išradimą

9.13. Konstruktoriai ir destruktoriai

• Dažnai sukuriant objektą, reikia atlikti pradinę objekto inicializavimą, pvz. išskirti atminties sritis masyvams, priskirti kintamiesiems pradines reikšmes.• Objektą sunaikinant atminties sritis reikia atlaisvinti

• C++ tuo tikslu yra sukurt specialūs metodai, vadinami konstruktoriais ir destruktoriais

• Funkcija-konstruktorius visada turi ta patį pavadinimą, kaip ir klasė. Ji leidžia atlikti objekto inicializavimą jo sukūrimo metu• Funkcija-destruktorius taip pat turi tą patį pavadinimą kaip ir klasė, bet prieš pavadinimą visada dedamas tildės ~ ženklas. Ji atlieka objekto sunaikinimą.

9.14. Bendri klasės objektų nariai

• Kai kada yra patogu, kad visi duotos klasės objektai turėtų bendrus duomenų elementus, kurie ir yra naudojami bendrai.• Bendri klasės duomenų elementai apibrėžiami naudojant raktinį žodį static• Pvz: class CWindow { public: int xLeftTop, xRightBottom; int yLeftTop, yRightBottom; static char title[80]; void SetTitle(char *); }

char CWindow::title[80]=“lango pavadinimas”;Kiekvienas klasės CWindow objektas turės unikalias lango koordinates ir tą patį lango pavadinimą

9.15. Draugiškos klasės ir draugiškos funkcijos

• C++ galima užduoti draugišką klase funkciją, naudojant raktinį žodį friend. • Aprašant klasę nurodomas tiktai funkcijos pavadinimas.• Draugiška funkcija nėra klasės elementas, bet ji gali prieiti prie visų klasės elementų, įskaitant ir private bei protected elementusclass point { public: friend void point:::Clear(point *); private: int m_x; int m_y; };

void Clear(point *ptr) {

ptrPoint -> m_x=0; ptrPouint -> m_y=0; return; }

• Analogiškai galima užduoti ir draugiškas klases: class point { ……………};

class line { public: friend class point; // klasė pouint skelbiama // draugiška klasei line}

9.16. Paveldėjimas

• Prisiminkime tris bazinius objektinio programavimo principus: inkapsuliaciją, paveldėjimą ir polimorfizmą• Paveldėjimas – antrasis iš šių bazinių principų• Iš kur kilo idėja panaudoti paveldėjimą ? Be abejo iš gamtos• Ką gamtoje reiškia paveldėjimas ?• Objektiniame programavime paveldėjimas reiškia beveik tą patį, ką ir gamtoje• Motininės klasės perduoda savo savybes dukterinėms klasėms• Dažniausiai naudojami pavadinimai: bazinė klasė ir išvestinė klasė; kartais naudojamos sąvokos – motininė klasė ir dukterinė klasė• Iš anksčiau išvestų klasių galima išvedinėti ir naujas išvestines klases• Išvestinė klasė apima savyje visus bazinės klasės elementus ir metodus, bei gali juos papildyti nuosavais elementais ir metodais• Išvestinė klasė pati gali tapti bazine klase kitoms išvestinėms klasėms. Tokiu atveju išvestinė klasė paveldės visų bazinių klasių elementus ir metodus

9.17. Vienetinis paveldėjimas

• Vienetinio paveldėjimo atveju išvestinė klasė paveldi elementus tik iš vienos bazinės klasės• Paveldėjimas apibrėžiamas taip:

class [] [: ] ] {

} []

Angliškoje literatūroje paveldėjimas vadinamas inheritanceSukurtoje klasėje galima apibrėžti elementus, kurių vadai sutampa su bazinės lasės elementų vardais• Vienetinio paveldėjimo pavyzdys:

class Base { // klasės Base elementai };

classs DerivedFirst: Base { // klasės DerivedFirst elementai }; class DerivedSecond : Base { // klasės DerivedSecond elementai };9.20. Daugybinis paveldėjimas

• Daugybinis paveldėjimas atliekamas paveldėjimas. Išvestinė klasė šiuo atveju gali turėti keletą bazinių klasių panašiai kaip vienetinis• Vietoj vienos bazinės klasės pavadinimo, nurodomas bazinių klasių pavadinimų sąrašas• Apibrėžimas:• class [ [: [} []

• Daugybinio paveldėjimo parašymo pavyzdys:

class BaseFirst { // klasės BaseFirst elementai}; class BaseSecond { // lasės BaseSecod elementai}class Derived: BaseFirst, BaseSecond {// klasės Derived nuosavi elementai }

9.21. Priėjimo prie bazinės klasės elementų apribojimas

• Priėjimą prie klasės elementų galima valdyti naudojant priėjimo modifikatorius• Kuomet paveldima bazinė klasė, priėjimą galima valdyti prie bazinės klasės elementų• Tokiu atveju yra svarbu su kokiais specifikatoriais yra aprašyti bazinės klasės elementaiBazinės klasės elemento specifikatorius Bazinės klasės priėjimo specifikatorius public protected privatepublic public protected privateprotected protected protected privateprivate – – –

9.22. Bazinės klasės metodų perdefinavimas

• Išvestinėje klasėje galima apibrėžti metodus ir duomenų elementus tais pačiais vardais, kurie jau buvo panaudoti bazinėje klasėje• Tokiu atveju tie bazinės klasės elementai tampa paslėptais• Norint operuoti su paslėptais elementais, reikia naudoti pilną vardą: bazinės_klasės_vardas:: elemento_vardasPvz: class C: A,B { a=A::a}

9.23. Daugybinio paveldėjimopavyzdys

9.24. Rodikliai į klases

• C++ leidžiama apibrėžti rodiklius į klases.• Apibrėžta klasės tampa veikiančiu duomenų tipu• Apibrėžti rodiklį į klasę paprasčiausiai reikia panaudoti klasės pavadinimą ir rodiklio ženklą • CRectangle * prect; //is a pointer to an object of class • // CRectangle. Kaip ir su kitais agreguotais duomenų tipais, norint prieiti prie rodiklių į klases elementų, reikia naudoti ženklą ->

10. X-OJI PASKAITA

Paveldėjimas. Operatorių perkrovimas.

10.1. Išvestinės klasės

• Sudaro prielaidas sukūrimui naujos klasės, kuri yra anksčiau sukurtos klasės variacija• Išvestinė klasė gali prieiti prie bazinės klasės atvirų ir uždarų narių• Išvestinėje klasėje nustatomi private, protected ir public bazinės klasės narių apribojimai• Pagal nutylėjimą nustatomi private apribojimai• Pilnai atitinka įprastinės klasės apribojimus, bet papildomai turi bazinės klasės elementus su nuosavais priėjimo apribojimais

10.2. Išvestinių ir bazinių klasių elementai

• Grafiškai elementų apribojimai gali būti pavaizduoti taip:• Private Base Derived private —— private protected —- private public ——– private• Protected private ——- private protected —- protected public ——– protected• Public private ——– private protected —– protected public ———- public

10.3. Išvestinės klasės funkcijos- nariai

• Išvestinėse klasėse gali pasitaikyti funkcijos-nariai, turinčios tuos pačius pavadinimus kaip ir bazinės klasės nariai• Argumentų kiekis ir jų tipai, o taip pat gražinamos reikšmės tipas gali skirtis nuo bazinės klasės metodo argumentų skaičiaus, tipai ir gražinamos reikšmės tipas

• class PayPhone: public Phone { // …… public: // …… void GiveDialTone(); }; Phone home(516,555,8858); PayPhone booth(708,555,5444); //…..

home.GiveDialTone(); // Phone::GiveDialTone(); booth.GiveDialTone(); // payPhone::GiveDialTone();• Išvestinės klasės funkcijos-nariai gali kreiptis į bazinės klasės funkcijas-narius.• Galima kreiptis net į tas funkcijas – narius, kurių pavadinimai sutampa• Pvz: void PayPhone::GiveDialTone() { // atli Phone::GiveDialTone(); // iškviečia bazinės klasės metodą}

10.4. Priėjimo valdymas

10.5. Virtualios funkcijos-nariai

• Leidžia išrinkti narius su tais pačiais pavadinimais per rodiklį į funkciją, priklausomai nuo objekto tipo, į kurį nurodo rodiklis, o ne nuo rodiklio tipo• Leidžia naudoti objektinę programavimo paradigmą• Argumentų tipai, jų skaičius, o taip pat gražinamos reikšmės tipas, gali būti tokie patys kaip ir to paties pavadinimo bazinės klasės funkcijoje• Negali būti statinėmis• Gali būti naudojamos abstrakčių bazinių klasių sudarymui• Abstrakti bazinė klasė – tai klasė, turinti bent vieną virtualią funkciją- narį (metodą)

• Pilnai virtuali funkcija – narys – tai virtuali funkcija-narys, kuriai yra deklaruotas interfeisas, o jo realizacija parašyta išvestinėje klasėje• Tam reikia metodo apibrėžimą prilyginti nuliui• Abstrakčios klasės destruktorius visada privalo būti virtualus• Anstyvosios C++ versijos nepalaikė abstrakčių bazinių klasių• Negalima apibrėžti abstrakčios klasės objekto. Galima apibrėžti tik išvestinės klasės objektą• Pilnai virtuali funkcija niekada negali aiškiai arba netiesiogiai iškviesta iš konstruktoriaus• Iš konstruktoriaus gali būt iškviesta tik per ne virtualią klasės funkciją-narę. Tačiau bus iškviesta duotoje klasėje apibrėžta funkcija

10.6. Pilnai virtualios funkcijos – nariai

10.7. Virtualios klasės ir kostruktoriai

10.8. Bazinių klasių konstruktoriai

• Iškviečiami prieš išvestinių klasių konstruktorių iškvietimą• Turi būti aiškiai nurodyti kiekviename išvestinės klasės apibrėžime, jeigu bazinėje klasėje nėra konstruktoriaus pagal nutylėjimą• Bazinės klasės konstruktoriaus pavadinimas ir jo argumentai atskiriami nuo išvestinės klasės konstruktoriaus pavadinimo dvitaškiu• Daugybinių bazinių klasių konstruktoriai atskiriami vienas nuo kito dvitaškiais• Niekada tiesiogiai arba netiesiogiai iškviesti virtualios bazinės klasės metodus

10.9. Bazinių klasių destruktoriai

• Iškviečiami po išvestinių klasių destruktorių• Gali būti virtualiais. Abstrakčios klasės destruktorius gali būti virtualiu• Gali per ne virtualias funkcijas- narius tiesiogiai arba netiesiogiai iškviesti virtualius metodus• Tačiau šiuo atveju iškviečiama funkcijos versija duotai klasei arba bazinei klasei, jeigu tokia egzistuoja, ir niekuomet išvestinei klasei

10.10. Daugybinės bazinės klasės

• Leidžia išvesti naują klasę daugiau negu iš vienos bazinės klasės• Bazinių klasių išvardijimo tvarka sąraše neturi įtakos.• Priėjimas prie bazinių klasių elementų, turinčių vienodus pavadinimus, turi būti atliekamas per bazinių klasių pavadinimus

class A { public: void f(); };class B { public: void f(); };class C: public A, public B { /* …. */ };// …..C c;c.f(); // klaida: kur f ?c. A:f(); // teisingai

• Patogiausia dviprasmybes spręsti abiejų funkcijų perdengimu išvestinėje klasėje class C: public A, public B {// …. public: void f() { A::f(); B::f(); }}; // …C c;c.f(); // dabar teisingai

• Klasėms, kurios yra išvestos iš klasių su bendra baze, pagal nutylėjimą egzistuoja du bendros bazės objekto egzemplioriai• Į bendros bazinės klasės elementus galima kreiptis per bet kurios iš išvestinių klasių pavadinimą

10.11. Virtualios bazinės klasės

• Klasėms, kurios yra išvestos iš išvestinių klasių su bendra virtualia bazine klase, egzistuoja tiktai vienas bendros bazinės klasės elementas• Apibrėžiami raktinio žodžio virtual panaudojimu bazinės klasės priėjimo lygio specifikatoriuje• Prieinant prie bazinės klasės elementų nebereikia nieko nurodyti papildomai• Jų konstruktoriai iškviečiami pagal paskutinės išvestinės klasės grandinėlę• Apibrėžiant klasę galima sumaišyti su ne virtualiomis bazinėmis klasėmis

10.12. Šablonai• Kas yra šablonas ?• Šablonai naudojami ir objektiniame programavime• Jie išplečia klasės ir funkcijos supratimą• Suteikia galimybes parametrizuoti funkcijas ir klases• Faktiškai įgalina apibrėžti funkcijas ir klases kaip “bet kurio tipo” elementus • Sąvotiškai leidžia atsisakyti tipų

10.13. Funkcijų šablonai

• Tai funkcijos kaip šablono specifikacijos paskelbimas. Šablono specifikaciją sudaro raktinis žodis template, paskui kurį seka parametrų, įtrauktų į < > skliaustelius, sąrašas• Turi tipo parametrus kurie žymimi raktiniu žodžiu class, po kurio seka identifikatorius. Identifikatorius naudojamas tipo pavadinimo pakeitimui• Automatiškai kompiliatorius išplečia iki pilno funkcijos aprašymo• Gali būti perkrautos kitomis funkcijomis – šablonais

10.14. Klasių šablonai

• Tai klasių apibrėžimai, naudojant specifikaciją template• Automatiškai juos kompiliatorius išplečia iki pilno klasių apibrėžimo, kaip reikalauja taisyklės• Negali būti įstatyti į kitas klases (skirtingai nuo įprastų klasių)• Gali keisti netipizuotus parametrus. Reikšmės, nurodytos šiems parametrams, privalo būti konstantos • Gali būti išvesti iš kaip iš ne šabloninių klasių, taip ir iš klasių šablonų• Iš jų gali būti išvestos kaip ne šabloninės klasės, taip ir klasės šablonai

• Kai kuriems tipams gali būti perdengti tam, kad atlikt (arba neatlikti) kokius nors veiksmus, kuriuos klasių šablonai neatlieka• Taip pat gali būti klasėmis-struktūromis arba klasėmis-apjungimaisclass Stack { char * *v; int size, top;public: Stack(int ezis); ~Stack(); void Push(const char * &); char * & Pop(); char * & Top() const; };10.15. Statiniai duomenys- nariai

• Yra bendri duomenys visiems tam tikros klasės-šablono egzemplioriaus klasės objektams.• Apibrėžiami failo matomumo srityje, kuomet prieš apibrėžimą naudojamas template

template class C { static int i; static T t; };

template int C ::i; // apibrėžiame matomumo srityje template int C ::t; C c;C f;

10.16. Funkcijų-narių šablonai

• Apibrėžiami už klasių, kurioms priklauso, apibrėžimų ribų naudojant specifikatorių template• Apibrėžtiems tipams gali būti perdengti, kad atlikti tam tikrus veiksmus, kuriuos metodų šablonai neatlieka

template void Stack ::Push(const T& element) { if(top==size-1) error(“stack oveflow”); else v[++top]=element;}

10.17. Draugiškos funkcijos

• Kiekvienam T tipui gali būt visų T tipo klasių draugais. Tai įprastos draugiškos klasės• T tipui gali būt T tipo klasės draugais• Prieš juos gali eiti specifikatorius template• Gali būti kitos klasės funkcijomis- nariais• Gali būti apibrėžti visai klasei• Gali būti ne šabloninių klasių draugais

10.18. Operacijų perkrovimas

• Gali išplėsti iki klasės tipo bet kurių operacijų reikšmes, įskaitant :: , sizeof, ? :, ., *• Atliekama deklaruojant funkciją, susidedančią iš raktinio žodžio operator, po kurios seka viena iš vidinių operacijų• Nedaro jokių prielaidų apie tokias operacijas. Pvz: jeigu i yra int tipo, tai ++i yra tas pats, kas i=+1 ir i=i+1. Perkrautiems operatoriams tokios prielaidos nebegalioja tol, kol pats programuotojas jų atitinkamai neapibrėžia• Negali naudoti argumentų pagal nutylėjimą

10.19. Unariniai operatoriai

• Gali būti apibrėžti kaip nestatinės funkcijos-nariai, neturintys argumentų. Tai yra @ x interpretuojama kaip x.operator@() bet kuriam operatoriui @ • Gali būti apibrėžti kaip funkcijos, nesančios kokios nors klasės nariais, ir turinčios vieną argumentą• Šis argumentas yra tos klasės kintamasis arba nuoroda į tokį kintamąjį• Šiuo atveju @x interpretuojama kaip operator@(x) bet kuriam operatoriui @

11. XI-OJI PASKAITA

Operatorių perkrovimas. Polimorfizmas.

11.1. Unariniai operatoriai

Class X { X operator-() const; // unarinis minusas X operator &() const; // adreso gavimas X operator ^() const; // klaida: ^ binarine operacija};

class Y { friend Y operator –(const Y&); // unarinis minusas friend Y operator &(const Y&); // adreso skaiciavimas friend Y operator^(const Y&); // klaida};

11.2. Binarinės operacijos

• Gali būti deklaruotos kaip nestatinės funkcijos, kurios turi vieną argumentą. Tai yra užrašas x@y interpretuojamas kaip x.operator@(y) bet kuriam operatoriui @.• Gali būti deklaruotos kaip funkcijos, nepriklausančios konkrečiai klasei ir turinčios vieną argumentą. • Šis argumentas turi būti arba duotos klasės kintamuoju, arba nuoroda į tokį kintamąjį. Ta yra bet kuriai operacijai @, Įskaitant ir operaciją =, x@y interpretuojama kaip operator@(x,y)

• Pvz: class X { X operator –(const X&) const; // binarinis minusas X operator &(const X&) const; // poskiltinis IR X operator! (const X&) const; // klaida: ! Unarine operacija};

class Y { friend Y operator –(const Y&, const Y&); friend Y operator &(const Y&, const Y&); friend Y operator! (const Y&, const Y&); // klaida};

11.3. Operatorių perkrovimas

11.4. Funkcijos iškvietimo operacija

• Turi būt paskelbta, kaip nestatinė klasės funkcija narys• Leidžia vartotojui nustatyti operandų kiekį

Class X { // …. public: X(int a, int b, int c); // …. void operator() (int i, int j, in k);};

X Xample(1,2,3); // iškviečiamas konstruktoriusXamople(4,5,6); // iškviečiama operacija ()

11.5. Priskyrimo operacija

• Naudojama vieno duotos klasės objekto reikšmės priskyrimui kitam objektui• Jeigu vartotojas jos neapibrėžė, tai atlieka vieno klasės objekto laukų priskyrimą kitam objektui• Turi būti apibrėžta, jeigu klasėje yra laukai, kurie yra rodikliai į dinamiškai išskirtas atminties sritis• Tai tik operacijos funkcija, kuri nėra paveldima• Turi būti apibrėžta, kaip nestatinė klasės funkcija – narys

11.6. Indeksavimo operacija

• Turi būti apibrėžta kaip nestatinė klasės funkcija- narys• Dažniausiai gražina nuorodą, todėl ją galima naudoti priskyrimo operacijoje iš abiejų operando pusių

class String* { char *s;//… public: String(char); String(const char *); char &operator[](int pos) { return s[pos]; }// …};String ball=mitten”; ball[0]=‘k’;

11.7. Priėjimo prie nario operacija

• X->m interpretuojama kaip (x.operator->())->m.• Pastebima, kad tai unarinė operacija ir kad x – tai klasės objektas, o ne rodiklis į jį.• Turi gražinti rodiklį į klasės objektą, arba patį klasės objektą, arba nuorodą į klasės objektą, kuriam ši operacija yra priskirta, kadangi originali operacijos -> prasmė nėra prarandama, o tik užlaikoma• Turi būti apibrėžta, kaip nestatinė klasės funkcija – narys

11.8. Polimorfizmas

• Polimorfizmas išvertus iš graikų kalbos reiškia daugiaformiškumas• Tai paskutinė bazinė objektinio programavimo koncepcija• Polimorfizmas objektiniame programavime suprantamas kaip objekto sugebėjimas sureaguoti į tam tikrą užklausą priklausomai nuo savo tipo, netgi ir tuo atveju, kuomet kompiliacijos metu objekto, kuriam nukreipta užklausa, tipas dar nėra žinomas.

• C++ kalboje polimorfizmo koncepcija realizuota naudojant virtualių funkcijų-narių mechanzmą

11.9. Virtualios funkcijos-nariai

• Jeigu kurioje nors klasėje yra funkcija, aprašyta kaip virtual, tai į tokią klasę kompiliatorius patalpina paslėptą narį – rodiklį į virtualių funkcijų lentelę.• Taip pat sugeneruojamas specialus kodas, leidžiantis parinkti virtualią funkciją, tinkančią duoto tipo objektui, programos vykdymo metu.• Šis procesas įgijo vėlyvo surišimo pavadinimą (angl. late binding).• Kita vertus virtualių funkcijų naudojimas lėtina programos veikimą ir didina klasės objektų dydį• Jeigu kokia nors funkcija bazinėje klasėje apibrėžta kaip virtuali, tai funkcija tokiu pačiu pavadinimu, su tuo pačiu argumentų sąrašu ir tokio paties tipo gražinama reikšme, apibrėžta bazinėje klasėje, automatiškai tampa virtualia• Negalima apibrėžti išvestinėje klasėje funkcijos, besiskiriančios tiktai gražinamos reikšmės tipu• Virtuali funkcija savaime suprantama turi būti kokios nors klasės metodu, tačiau ji negali būti statiniu kokios nors klasės metodu.• Išvestinėje klasėje galima apibrėžti funkciją su kitu besiskiriančiu argumentų sąrašu ir ji bus paprasta (nevirtuali) funkcijaclass Base { int dummy; public: void f() { cout<

//lango klases pavadinimaschar const szClassName[]=“MyWindowsAppClass”;//lango pavadinimaschar const szWindowsTitle[]=“MyWindowApplication”;

Int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow) { HWND hwnd; // lango identifikatoriusMSG msg; ATOM aWndClass; // grizimo kodo atomasWNDCLASS wc; // lango klases registravimo struktura// uzpildome lango klases registravimo strukturos laukus//lango stiliuswc.style=0;// rodikis i lango funkcija, apdorojancia visus sios klases langu pranesimus

wc.lpfnWndPoc=(WNDPROC)WndProc;wc.cbClsExtra=0; wc.cbWndExtra=0; // papildomos atminties dydis wc.hInstance=hInstance; wc.hIcon=LoadIcon(NULL,IDI_APPLICATION); //ikoneles identifikatorius wc.hCursor=LoadCursor(NULL, IDC_ARROW); wc.hbrBackground=(HBRUSH)(COLOR_WINDOW=1);

wc.lpszMenuName=(LPSTR)NULL; wc.lpszClassName=(LPSTR) szClassName; // uzregistruojame lango klase aWndClass=RegisterClass(&wc); // sukuriam langa hwnd=CreateWindow(szClassName, szWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, // lango dydis ir vieta0, // motininio lango identifikatorius0, // meniu identifikatorius hInstance, NULL); if(!hwnd) return FALSE; ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);

// paleidziam pranesimu apdorojimo ciklawhile(GetMessage(&msg,0,0,0)) {DispatchMessage(&msg); }

return msg.wParam; }

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

switch(msg) {

case WM_LBUTTONDOWN: {

MessageBox(NULL, “paspaustas kairysis peles klavisas”, “pranesimas”, MB_OK); return 0; }

case W_RBUTTONDOWN: {MessageBox(NULL, “paspaustas desinysis peles klavisas”, “pranesimas”, MB_OK); return 0; }

case WM_DESTROY: {PostQuitMessage(0); return(0); } }

return DefWindowProc(hwnd, msg, wParam, lParam);}

11.11. Darbas su Windows sistemos meniu

• Beveik kiekviena Windows aplinkai parašyta programa turi meniu. • Dažniausiai meniu kuriamas naudojant programos resursų failą ir resursų kompiliatorių• Resursų failas turi plėtinį .rc • Resursu faile gali buti ir kai kurie kiti programai reikalingi duomenys (pavyzdžiui akseleratoriai, ikonėlės ir t.t.)

MY_MENU nameID MENU BEGIN POPUP “&File” BEGIN MENUITEM “&New”, CM_NEW MENUITEM “&Open”, CM_OPEN MENUITEM “&Save”, CM_SAVE END POPUP “&Edit” BEGINMENUITEM “&Undo”, CM_UNDOMENUITEM “&Cut”, CM_CUTMENUITEM “&Paste”, CM_PASTEMENUITEM “&Copy”, CM_COPY END ENDMENUITEM SEPARATOR