410 likes | 564 Views
Základy systémov reálneho času. Doc. RNDr. Jaroslav Fogel, CSc Katedra informatiky a výpočtovej techniky E-mail: Jaroslav.Fogel@stuba.sk http://hercules.kar.elf.stuba.sk/~zsrc/. Podmienky pre absolvovanie skúšky: Cvičenia: Získanie zápočtu a tým aj umožnenie prístupu ku skúške je
E N D
Základy systémov reálneho času Doc.RNDr. Jaroslav Fogel, CSc Katedra informatiky a výpočtovej techniky E-mail: Jaroslav.Fogel@stuba.sk http://hercules.kar.elf.stuba.sk/~zsrc/
Podmienky pre absolvovanie skúšky: Cvičenia: Získanie zápočtu a tým aj umožnenie prístupu ku skúške je podmienené vypracovaním, odovzdaním a obhájením zadania programu. Vypracované zadanie je hodnotené maximálne 40 bodmi a minimálny počet bodov pre získanie zápočtu je 20. Skúška: Maximálny počet bodov za písomnú časť skúšky je 60 bodov. Podiel skúšky na hodnotení predmetu je 60%.
Odporučená literatúra: 1. Ľ. Šešera, A. Mičovský: Objektovo - orientovaná tvorba systémov a jazyk C++, Vyd. Perfekt, Bratislava 1994. 2. R. Ege: Object - Oriented Programming with C++, Academic Press, 1994. 3. Visual C++ Language Reference Manual 4. Borland C++ Programmer’s Guide. 5. http://www.cplusplus.com/doc/tutorial 6. http://bruceeckel.com
Úvod • OO programovanie a návrh • Modul • Základná stavebná jednotka programu, ktorá môže byť navrhnutá, kódovaná, preložená a testovaná nezávisle od ostatných modulov a neskôr vložená do väčšieho programu • Základné kritéria modulárnosti: • Modulárna dekompozícia – dekompozícia problému na podproblémy • Modulárna kompozícia – znovupoužitelnosť kódu • Modulárna zrozumitelnosť – minimum interfejsov • Modulárna spojitosť – flexibilnosť modulov • Modulárna ochrana – šírenie chýb
Procedurálne programovanie • Modul = funkcia • Stavba programu je zhora nadol – úloha sa dekomponuje do podúloh • Nevýhody: zlá údržba programov (testovanie, ladenie, rozšíritelnosť) • Objektovo-orientované programovanie • Modul = trieda • Stavba programu je obojsmerná:- zdola nahor (zovšeobecnenie) • - zhora nadol (špecializácia, agregácia) • Výhody: - abstraktné datové typy • - ukrytie informácií • - ľahšia znovupoužitelnosť kódu • - ľahšia rozšíritelnosť programu
Modul Moduly v procedurálnych jazykoch ako C sú C funkcie int find_max( int n1, int n2 ) { if ( n1 > n2 ) return n1; else return n2; }
Modul Moduly v objektovo-orientovaných jazykoch ako C++, Java tvoria triedy, ktoré obsahujú premenné a funkcie Príklad Trieda String obsahuje premennú na uloženie charakterov reťazca spolu s funkciami pre tvorbu reťazca, určenie jeho dĺžky, zistenia či reťazec obsahuje daný charakter, atď.
Procedurálne programovanie Technika, ktorá sa používa pri návrhu procedurálneho programu je funkcionálna dekompozícia zhora nadol. Pri takomto návrhu je problém dekomponovaný do podproblémov a týmto sú priradené funkcie na ich riešenie. Príklad Úlohu konštrukcie auta môžeme dekomponovať do podúloh - konštrukcia karosérie - konšrukcia motora - konštrukcia riadenia, atď Celý problém konštrukcie auta v simulačnom programe môže byť priradený hlevnej funkcii, v ktorej budú volané jednotlivé funkcie podúloh ako build_chasis(), build _engine(), atď.
Procedurálne programovanie Nedostatky návrhu zhora nadol Zmena v dekomponovaní problému vyvoláva reťazec zmien v celej dekomozičnej hierarchii až na úroveň funkcionálnej dekompozícii. Príklad Funkcia main v prípade zmeny argumentov niektorej jej funkcie musí byť zmenená v celej dekompozičnej hierarchickej štruktúre. main(){ build_chassis(a); // … return 0; } void build_chassis(arg){ f(arg); … }
OO Programovanie • OO programovanie odstraňuje nevýhody procedurálneho programovania • Triedy sa chovajú ako moduly, ktoré môžu interakovať s inými • modulmi takým spôsobom, že zmena v jednom module nevyžaduje • zmenu v inom.
Významy triedy Trieda je súbor objektov, ktoré majú spoločné vlastnosti Napríklad trieda Ľudia je charakterizovaná vlastnosťami: - sú teplokrvný (na rozdiel od rýb) - vedia sa smiať (na rozdiel od zvierat) Môžu vykonávať činnosti: - poľovať - riadiť auto - tancovať Trieda je abstraktný datový typ, ktorý má svoje inštancie alebo objekty.
Trieda- zapúzdrenie (encapsulation) • - Premenných, ktoré vyjadrujú črty alebo vlastnosti, ktoré • objekty triedy zdieľajú • funkcií, ktoré sa používajú na tvorbu objektov (konštruktory) • funkcií, ktoré reprezentujú operácie alebo chovanie sa triedy • (metódy)
Prečo C++?? • podporuje procedurálne (jazyk C) aj OO programovanie • podporuje užívateľom definované typy (abstraktné typy) • podporuje modularitu (súborov, funkcií a tried) • podporuje generické programovanie (template) • kompilátor optimalizuje kód z hľadiska úspory pamäti a rýchlosti • výkonu programu • poskytuje run-time knižnice podporujúce: • - prácu z reťazcami • - vstupno- výstupné operácie • - matematické výpočty • - spracovanie údajov a času • - sortovacie a vyhľadávacie operácie, atď.
Abstrakcia dát • kľúčový pojem v O-O programovaní • Je to spôsob ako kombinovať premenné s funkciami, ktoré s nimi manipulujú do modulov (v OO nazývaných triedy). • Modul (trieda ) tvorí abstraktný dátový typ, ktorý sa v programe deklaruje ako ostatné základné typy jazyka. • Abstrakcia dát umožňuje tzv. ukrytie informácií t.j. poskytuje používateľovi len tie informácie, ktoré sú nevyhnutné pre prácu s daným abstraktným typom, detaily, ktoré sú nepodstatné sú pred používateľom skryté. • Abstrakcia dát umožňuje jednoduchý spôsob znovupoužitelnosti kódu (dedičnosť). To núti programátorov písať kód takým spôsobom, aby sa nové programy tvorili ľahšie rozšírením kódu ako písaním nového kódu. • Abstrakcia dát umožňuje ľahkú modifikovatelnosť existujúcich programov bez skutočnej zmeny kódu (dedičnosť, polymorfizmus).
Rozšírenia procedurálnych • čŕt jazyka C • Komentár ukončovaný koncom riadka. Nový spôsob začína // a končí koncom riadka. Pôvodné označenie komentára v C ostáva aj v C++. • Prísnejšia kontróla typu. V C++pre každú funkciu musí byť daný prototyp a volanie funkcie musí tomuto typu odpovedať. • int main() { • printf("Hello World\n"); • return (0); } • je kompilátorom C jazyka skompilovaný hoci aj s varovným hlásením že printf( ) je neznáma funkcia, pritom mnoho kompilátorov C++ tento kód nepreloží.
3. Prototypizácia funkcie. C++ umožňuje deklarovať typ argumentu funkcie vo vnútri okrúhlych zátvoriek.Príklad: C++ float suma(float a, int b){…} C float suma( a, b)float a; int b; { … …}
4. Smerník na void a funkcia vracajúca void . Funkcia, ktorá nevracia hodnotu sa deklaruje ako void. Možno deklarovať smerník ukazujúci na void a možno mu priradiť smerník na ľubovolný typ. Príklady: void main(){ void* ptr; int* iptr; int i; i=1; iptr = &i; ptr = iptr; // void smerník možno presmerovať na ľubovolný typ } void fnc(){ printf(“\n funkcia fnc je typu void”); }
5. Názov enumerácia je názvom typu. V C++ je enumerácia názvom typu automaticky. V C treba použiť konštrukciu typedef.Príklad: v C++enum svetla_semafora{červená, zelená, žltá};typedef struct{ svetla_semafora svetla; //… }krizovatka v Ctypedef enum svetla_semafora{červená, zelená, žltá}typedef struct{ svetla_semafora svetla; //… }krizovatka
6. Názov struct je názov typu. V C je treba pre struct použiť typedef. Podobne ako pri enum. Pr. v C++enum svetla_semafora{červená, zelená, žltá};struct krizovatka{ svetla_semafora svetla; //… } krizovatka mestska_siet [20];
v Ctypedef enum svetla_semafora{červená, zelená, žltá}typedef struct{ svetla_semafora svetla; //… }krizovatka krizovatka mestska_siet [20]; 7. Deklarácia pri mieste použitia. V C++ sa deklarácia považuje za typ príkazu a možno ju umiestniť kdekoľvek. Pr. #include<stdio.h> void main(){ int i; i=1; if( i>0) { i=2; int j; j=3; } }
8. Operátor rozsahu platnosti ::. Používa sa na riešenie konfliktov pri použití rovnakých mien. V C++ má aj ďalšie možnosti použitia. Pr. #include<stdio.h> char c=‘A’; void fnc() { char c; c = ‘B’; printf(“\n lokalna hodnota c = %c”, c); printf(“\n globalna hodnota c = %c”, ::c); } void main() { fnc(); } Vystup: lokalna hodnota c = B globalna hodnota c = A
9. Definícia konštanty. V C++ ju dovoľuje rezervované slovo const aj pre členské funkcie triedy a argumenty funkcie. Pr.: const size= 100; // size v programe nemožno zmeniť const char* text = “konst. je hodnota, na ktorú ukazuje smerník”; //text[0]=‘K’; je nedovolene text = “novy text”; // je dovolene char* consttext =“ konst. je smerník nie jeho hodnota”; text[0]=‘K’; // je dovolene //text = “novy text”; je nedovolene 10. Anonymný union. C++ dovoľuje aby union ostal nepomenovaný. v C++ v C union{ union{ int plat; int plat; float pocet_hodin; float pocet_hodin; }; }praca;
V C typedef struct { char title[50]; char author[50]; union { float dollars; int yens; } price; } book; void main( ){ book history; history.price.dollars = 100; } V C++ struct book{ char title[50]; char author[50]; union { float dollars; int yens; }; }; void main( ){ book history; history.dollars = 100; }
12. Špecifikácie funkcie typu inline. Kompilátor nahrádza každé volaniefunkcie jej telom nie makrom ako to v C robí predprocesor. Pr. #include<stdio.h> inline float square(float arg) { return(arg*arg); } void main() { float a =3.14; float result; result = square(a); // telo sa skopiruje printf(“\n square =%d”, result); }
13. Prázdny zoznam argumentov. V C jazyku sa uvádza vo funkcii bez argumentov rezervované slovo void v C++ sa nemusí uvádzať. Pr. V C int fnc(void); v C++ int fnc(); 14. Použitie štandardných C funkcií. Štandardné C funkcie knižníc sa môžu používať v C++ programoch, avšak musia byť deklarované ako C funkcie.Ako príklad uveďme funkciu xmalloc( ), ktorá je Cfunkciou: extern "C" void *xmalloc(unsigned size); 15. Hlavičkové súbory pre C a C++. Kombinácia preddefinovaného symbolu _cplusplus s možnosťou definovať extern "C" funkcie umožňuje vytvárať hlavičkové súbory pre C aj C++.Takéto hlavičkové súbory môžu deklarovať skupiny funkcií, ktoré sa môžu používať v C aj v C++ programoch.
#ifdef __cplusplus extern "C" { #endif . . //(tu je declarácia C-funkcií napr.) externvoid *xmalloc(unsigned size); . #ifdef __cplusplus } #endif Niekedy je potrebné sa vyhnúť viacnásobnej deklarácie hlav. súboru. #ifndef _MYHEADER_H_ #define _MYHEADER_H_ . . (tu nasleduje deklarácia hlav. súboru) #endif
16. Preťažovanie funkcií. V C++ je možno definovať niekoľko funkcií s tým istým menom pre rôzne činnosti. Funkcie sa musia líšiť v zozname svojích argumentov. Pr. # include<stdio.h> void fnc(int arg){ … } void fnc(char* arg){ … } void fnc(float arg1, int arg2){ … } void main(){ fnc(5); fnc(“Hello”); fnc(3.14, 2);}
17. Kľúčové slovo typedef. Kľúčové slovo typedef je v C++ povolené ale je nie potrebné na rozdiel od C. Pretože struct, uniona enum sú názvami typu. 18. Funkcia ako člen struct. V C++ je možno definovať funkciu ako člena štruktúry. struct point // definition of a screen { int x,y; // coordinates x,y void draw(void); // drawing function }; 19. Operátory new a delete. Operátor new slúži na dynamickú alokáciu pamäti. Operátor delete slúži na uvolnenie alokovanej pamäti pomocou operátora new. new vracia adresu alokovanej pamäti. new má v C ekvivalent knižničnú funkciu malloc na rozdiel od nej umožňuje však rezervovať pamäť pre premenné ľubovolného abstraktného typu typu.
Pr. #include<stdio.h> void write_name( ) { int num_chars; printf(“\n Kolko znakov ma tvoje meno:”); scanf(“%d”,&num_chars); char* name= new char[num_chars+1]; printf(“\n Zadaj svoje meno:”); scanf(“%s, name); printf(“\n Tvoje meno je %s, name); delete name; } void main( ){ write_name( ); }
20. Funkcia s nešpecifikovaným počtom argumentov. C++ dovoľuje deklaráciu funkcie s nešpecifikovaným počtom argumentov. Na označenie zvyšných argumentov sa používa ... . Sú neznámeho typu a preto sa nevykoná ich typová kontróla. Pr. #include <stdio.h> void fnc(char* arg, …) { printf(“funkcia fnc: arg=%s”, arg); } void main(){ fnc(“hello”, “Bye”); } 21. Špecifikácia referencie. C++ obsahuje ďalší typ premennej (podobný smerníku), ktorý sa volá referencia. Referencia musí byť inicializovaná (s výnimkou argumentu funkcie): int num = 50; int& ref = num;
Referencia ref slúži ďalej ako synonymum (alias) premenej num. Najčastejšie sa využíva v deklarácii argumentu funkcie. Pri volaní funkcie sa potom vlastne odovzdáva volanej funkcie adresa premennej. Funkcia takto môže zmeniť hodnotu premennej. Pr. #include <iostream.h> void increment(int& value) { value++ } void main() { int j=1; increment(j); cout << j << endl; } výstup: 2
To iste v C jazyku: #include <iostream.h> void increment(int* value) { (*value)++ } void main() { int j=1; increment(&j); cout << j << endl; } výstup“: 2
Referencia ako návratová hodnota funkcie Návratová hodnota funkcie sa nekopíruje do dočasnej pamäte ako pri návrate z funkcie danej hodnotou ale je priamo dostupná volajúcej funkcii. int i=8; int val( ) { // návrat hodnotou … // int i; return i; // tu OK aj v prípade keď je i deklarované vo funkcii } j = val( ); j dočasná pamäť i 8 8 8
int& val( ){ // návrat referenciou … return i; // i musí byť deklarované mimo funkciu inak // ERROR: i goes out of existence } j = val(); j i 8 8
Pravidlá pri použití referencií: • Keď je referencia vytvorená musí byť vždy inicializovaná. • (smerník môže byť inicializovaný kedykoľvek). • Ak je referencia inicializovaná nejakým objektom nemôže byť • neskôr zmenená ako referencia na iný objekt. • ( smerník môže ukazovať na akýkoľvek objekt danej triedy) • Referencia nemôže byť NULL.
22. Preťažovanie operátorov C++ umožňuje takmer všetky operátory jazyka C ( unárne, binárne), ktorých operandy sú štandardného typu predefinovať funkciami tak, že ich operandy môžu byť ľubovolného abstraktného typu. Prototyp funkcie je: returntype operator name (paramtype,...) kde name je prekrytý operátor (+, -, <<,…) Príklad Ak chcete sčítať dve komplexné čísla c1 a c2 v C programe musíte vytvoriť funkciu napr. s názvom „add“ a potom c3 = add(c1,c2), kde c1, c2, c3 sú typu komplex. V C++ možno prekryť operátor + funkciou complex operator + (complex, complex) a potom môžno jednoducho písať c3 = c1+ c2
Cvičenie 1. Kde je chyba v nasledujúcej deklarácii: void f(int v, float s=3.14, int d); 2. Kde je chyba v nasledujúcejdefinícii: f(int n){ ... } 3. Aké sú rozsahy deklarovaných premenných: const int s=4; int f(int k); int main( ){ int j; for (j =0; j< s; j++){ int l =3*f(j); } return 0; } int f(int k){ return k*k; }
4. Aké sú výstupy programu: void swap( int a, int b){ int t; t = a; a =b; b = t; } void main( ){ int c = 8, d =5; swap(c, d); printf(“\n c: %d d:%d”, c, d); } 5. Nájdite chybu int& g(int i){ int j = 2*i; return j; }
6. Čo je výstupom int x = 9; int* p = &x; int** pp = &p; **pp= *p +10; printf(“%d”, x) 7. Vysvetlite chybu char c = ‘A’; double* p = &c; 8. Obsahuje nasledovný kód chybu? char c = ‘A’; char* p = &c; char* q; q = p; 9. Kde je chyba? int p; p = new int[100];