Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2003
1/38
2003
Fejleszti krnyezetek: GNU C++ MS Visual C++ Watcom C++ Turbo C Borland C++
Bevezet:
a C++ a C nyelvbl szrmazik 70-es vek Bell laboratrium, Unix opercis rendszer fejlesztse: az opercis rendszer jrarshoz j, magas szint nyelvre van szksg. A rendelkezsre ll magas szint nyelvek (COBOL, FORTRAN, PL1,) nem eredmnyeztek hatkony kdot (binris kdot) j nyelv s fordt Dennis M. Ritchie nevhez fzdik : C nyelv (Dennis M. Ritchie, Brian W. Kennighan: A C programozsi nyelv) 80-as vek kzepn kezd terjedni az objektum orientlt programozs (OOP); Bjourn Stronstup (AT&T) felismerte az objektum orientlt programozsnak, mint mdszernek a jelentsgt. Ettl kezdve a C nyelvet ilyen irnyban fejlesztik tovbb. A nyelv mai formjt ANSI ajnlsok hatrozzk meg. A C++ kicsi, strukturlt nyelv (kevesebb, mint 50 kulcsszt tartalmaz), de ezzel szemben a programnyelvek kzl a legtbb opertort tartalmazza.
2003
#include <iostream.h>
bool Prime(const int n){ int i; if (n<2) return false; for (i=2;i*i<=n;i++) if (n%i==0) return false; return true; } int main (){ int n; cout<<Enter an integer:; cin>>n; if (Prime(n)) cout<<Prime.\n; else cout<<Non prime.\n; return 0; } Azonos nev fggvnyek tbbfle paramterrel vagy argumentummal #include <iostream.h> int Abs(const int i){ return i<0?-i:i; } double Abs(const double d){ return d<0.0?-d:d; } int main(){ int n; double f; cout<<Enter an integer number:; cin>>n; cout<<Enter a real number:; cin>>f; cout<<The absolute value of the integer: <<Abs(n)<<\n; cout<<The absolute value of the real number: <<Abs(f)<<\n; return 0; } Az azonos nev fggvnyek kzl hogyan vlaszt a fordt: az argumentumok szma: hvhat-e a fggvny adott szm paramterrel? 3/38 //const mert i rtkt nem akarjuk megvltoztatni
2003
az argumentumok tpusa: kevesebb tpuskonverzira van-e szksg, mint ms, azonos nev fggvny hvsa esetn
Az elz plda alapjn: 1. felttel alapjn nem lehet eldnteni, mert ugyan annyi az argumentum 2. felttel alapjn hajtdik vgre a program
Alaprtelmezett argumentumrtk
C++-ban egy fggvny argumentumban szerepl vltozknak adhatunk alaprtelmezett (default) rtket, Fggvny deklarcijban inicializlt argumentum (default rtkkel rendelkez) paramter utn csak inicializlt paramter kvetkezhet (pl.: (int b, int c, int a=1,...) Ha egy fggvnynek n db argumentuma van, s ebbl m db-nak alaprtelmezett (default) rtke, akkor a fggvny meghvhat n-m db, n-m+1,...,n szm paramterrel. Teht legalbb a nem inicializltakat meg kell adni! Pl.: #include <iostrem.h> void test (int a, int b=2, int c=3){ cout<<a<<b<<c; } int main( ){ test(1); // 1 2 3 fog kirdni test(2,1) // 2 1 3 fog kirdni test(3,2,1) // 3 2 1 fog kirdni return 0; } A new s delete opertorok, 0 mutat new = memriafoglals Szintaxisa: mutat_neve = new tpus Pl.: int *p; p=new int[10] //10 egszet tartalmaz tmb cmnek lefoglalsa
0 mutat = a pointerhez nem tartozik memriacm: sehova sem mutat mutat. Ha egy mutat rtke 0, akkor nem trterletre mutat, hanem azt jelzi, hogy nem foglaltunk hozz memrit. delete : memria felszabadtsa szintaxisa: delete mutat_neve; Pl.: delete p; Cm szerinti paramtertads
2003
Pldaprogram: #include <iostream.h> void GetInt(int &n,const int lb=0,const int ub=100) //adott intervallumba es szm bekrse { bool ok; do{ cin>>n; if (n<lb) cout<<"The required integer value must be greater or equal to "<<lb<<"."; if (n>ub) cout<<"The required integer value must be less or equal to "<<ub<<"."; ok = (n>=lb && n<=ub); if (!ok) cout <<"\nRe-enter the value please: "; }while (!ok); } void GetNumbers(int* &t,int &num) //egy egsz tpus tmb bekrse { int i; cout<<"Enter the number of the values: "; GetInt(num,1,10); if (t) delete t; //ha t=0, vagyis hamis, akkor trlje t=new double[num]; for (i=0;i<num;i++){ cout<<"Enter the "<<i+1<<". value: "; cin>>t[i]; } } void PutNumbers(const int* t,const int num) //A const hasznlata (Paramter) Vltozk : o const int i; : i tartalma nem vltoztathat o const int *a; : az a mutat ltal mutatott trterlet pl.: tmb nem vltoztathat o int *const a; : az a mutat nem vltoztathat meg o const int *const b; : sem a b mutat, sem az ltala mutatott trterlet nem vltoztathat meg { int i; for (i=0;i<num;i++)
5/38
BevIT: Programozs II. cout<<"The "<<i+1<<". value: "<<t[i]<<"\n"; } double Min(const int* t,const int num) //tmb minimlis elemnek kivlasztsa { int i; int min=t[0]; //inicializls az 1. elemmel for(i=1;i<num;i++) if (t[i]<min) min=t[i]; return min; } double Avg(const int* t,const int num) //a tmb tlagnak meghatrozsa { int i; double sum=t[0]; for(i=1;i<num;i++) sum += t[i]; return sum/double(num); }
2003
int main( ){ int *a=0; int n; GetNumbers(a,n); PutNumbers(a,n); cout<<The smallest number is: <<min(a,n)<<\n; cout<<The average of the array is: <<Avg(a,n)<<\n; if(a) delete a; return 0; }
Paramtervltozk a memriban:
rtk szerint tadott paramtervltoz: az tadott vltoz tartalma lemsoldik egy msik trterletre void test1(int b){ b=3; } //2.2. int main(){ int a=1; test1(a); return 0; } //2.1.
6/38
BevIT: Programozs II. 1. | 2.1. 2.2. 3. a ___________________ | 0 | 0 0 0 0 0 0 2 Cm: E0000001 //2.1. //2.2. //1. //2. //3. 0 0 0 0 0 0 0 2 Cm: E0000001 0 0 0 0 0 0 0 2 Cm: E0000001 a __________________ 0 | 0 0 0 0 0 0 2 Cm: E0000001 b ___________________
2003
| | 0 0 0 0 0 0 0 2 b ___________________ | | 0 0 0 0 0 0 0 3
Vltoz rtk szerint tadott cme: void test2(int *p){ *p=3; } int main(){ int a=1; test2(&a); return 0; } 1. a ___________________ | | 0 0 0 0 0 0 0 1 Cm: E0000001 *p ___________________ | 0 0 0 0 0 0 0 1 Cm: E0000001 |
p ___________________ | | E 0 0 0 0 0 0 1
2.1.
7/38
2003
| | E 0 0 0 0 0 0 1
3. a ___________________ | 0 | 0 0 0 0 0 0 3 E0000001
Cm-szerinti paramtertads vagy referencia tpus paramter esetn egy j nvvel, az eredeti trterletre hivatkozunk void test3(int &b){ b=3; } int main(){ int a=1; test3(a); return 0; } 1. a ___________________ 2.1. b ___________________ 2.2. b ___________________ 3. a ___________________ | 0 | 0 0 0 0 0 0 3 Cm: E0000001 | 0 | 0 0 0 0 0 0 3 Cm: E0000001 | 0 | 0 0 0 0 0 0 1 Cm: E0000001 | 0 | 0 0 0 0 0 0 1 Cm: E0000001 //2.1. //2.2. //1. //2. //3.
8/38
2003
Futtathat llomnyok (Executable) Dinamikus knyvtrak (Dynamic link libraries) *.exe, *.dll (Op. rendszer fgg)
1.h 1.cpp ->1.obj 2.h 2.cpp -> 2. obj 3.h 3.cpp -> 3.obj
9/38
2003
llapotvltozk + viselkedsek. A viselkedsek olyan mveletek, amelyek hozzfrnek az llapotokhoz, vagy megvltoztathatjk azokat. Egysgbezrs (encapsulation) Az OOP tmogatja az egysgbezrst. Az egyetlen md egy objektum llapotnak megvltoztatsra sajt mveletein keresztl. Egy objektum belseje (llapotok) a klvilg szmra rejtett. Nincs olyan OOP nyelv, mely az egysgbezrst ne tmogatn. Az egysgbezrs hogyan vltoztatja meg a szoftverfejlesztst? - a kapcsold felletek tervezsvel kell tbb idt tlteni prbljuk a felletet minl pontosabban meghatrozni a fellet megvltoztatsa fjdalmas - a szoftver letciklusa talakul a korbbi programozsi feladatokhoz kpest A szoftverfejleszts egyes fzisaira fordtott id szzalkban hagyomnyos s OO programozsi mdszerrel. Hagyomnyos 30-40% 35-45% 15-20% OOP 70% 20% 10%
Az egysgbezrs elnyei: Knny karbantarthatsg: nincsenek bels sszefggsek a kdrszek kztt Plug & Play: azonos viselkeds objektumok egymssal helyettesthetk (klnbz implementci) Knnyebb rthetsg: csak a felletet kell rteni Gyors fejleszts: egyszer megvalsts ksbb kifinomultabbra cserlhet; csak az objektum belsejben kell vltoztatni Modulris ptkezs: minden objektum egy modul, ami a tbbitl fggetlenl fejleszthet/tesztelhet Megjegyzs: az OOP hrom legfontosabb jellemzje: - egysgbezrs - rkls/szrmaztats - tbbalaksg / poliformizmus Ezen lehetsgeket a ksbbiekben ebben a sorrendben trgyaljuk. Osztlyok s objektumok Analgia: tpus -> vltoz osztly -> objektum osztly : sszetett adatszerkezet a hozz kapcsold mveletekkel egytt objektum : egy konkrt pldny az adott tpuson bell Osztly deklarcija Szintaxis: class osztlynv{ Adattagok; 10/38
BevIT: Programozs II. Mveletek (fggvnyek formjban); }; Objektum deklarcija Szintaxis: osztlynv objektumnv; Dinamikusan: osztlynv *objektummutat; Objektummutat = new osztlynv; Objektum trlse = delete objektummutat; Pl.: class class1{ }; int main(){ class1 obj,*pobj; pobj=new class1; delete pobj; return 0; }
2003
Osztly metdus: class store{ int s; public: int GetStire() const(); Ha egy metdus konstans tpus akkor az osztlyban trolt adattagokat nem vltoztatja meg. Konstans objektumoknak csak konstans tpus metdusai hvhatak. //
Egysgbezrs: Hozzfrsi jogosultsgok mdostsval adatok s eljrsok/fggvnyek (metdusok) egy rsze a klvilg szmra nem hozzfrhet (private) ms rsze nyilvnos (public). Alaprtelmezs szerint minden private. Pl.: class cl1{ private: int state; public: void SetState(const int i); int GetState(); }; Pl.: void cl1::SetState(const int i){ state=i; } int cl1::GetState(){ 11/38
2003
return state; } int main(){ cl1 o; int j; o.SetState(10); //o.state=10;<-srti a jogosultsgot j=o.GetState(); return 0; } Konstruktor s destruktor: 1. Konstruktor 1.1. Olyan tagfggvny, melynek neve megegyezik az osztlyval 1.2. Nem rendelkezik visszatrsi rtkkel 1.3. Akkor indul el az eljrs, amikor az osztlyba tartoz objektum ltrejn 1.4. Feladata az llapotvltozk inicializlsa ( !dinamikus vltozk, adatszerkezetek) 2. Destruktor 2.1. Olyan tagfggvny melynek neve: ~osztlynv 2.2. Nincs visszatrsi rtke 2.3. Akkor indul el, amikor egy, az osztlyba tartoz objektum megsznik 2.4. Feladata az osztlyban trolt dinamikus adatszerkezetek trlse. Pl.: class cl2{ public: cl2(); ~cl2(); }; cl2::cl2(){}; cl2::~cl2(){}; int main(){ cl2 o,*po; po=new cl2; delete po; return 0; } //o.cl2() lefut //po->cl2() //po->~cl2() //o.~cl2() lefut
Szintaxis: <osztlynv> <objektumnv> (konstr. paramterei) vagy Objektummutat = new osztly_nv (konstr. Paramterei) 12/38
2003
Ha egy objektum ltrehozsakor nem adunk meg paramtereket a konstruktor szmra, akkor a default konstruktor indul el.
Tipikus plda: objektumtmb ltrehozsa Szintaxis: <osztlynv> <osztlytmb>[objektumok_szma] Ekkor a tmb minden elemre a default konstruktor hvdik meg. Pl.: #include <iostrem.h> class cl2{ private: int state; public: cl2(){state=0;}; cl2(const int pstate) {state = pstate ;}; //e kt sor helyett rhat a kv.: (const int pstate=0){state=pstate;};// int GetState(){return state;}; }; int main(){ cl2 a,*b,*c; //a.cl2() a.state = 0 cl2 d(2); //d.cl2(2) d.state = 2 b=new cl2; //b->cl2() b->state = 0 c=new cl2(3); //c->cl2(3) c->state = 3 cout<<a.GetState()<<b->GetState()<<c->GetState() <<d.GetState; // 0 0 3 2 r ki delete b; delete c; return 0; }
13/38
BevIT: Programozs II. // be fogja msolni a hvs helyre: b=Abs(b); esetn i=b; b=(i<0?-i:i); elnye: nincs fggvnyhvshoz kapcsold adminisztrci, teht gyorsabb htrnya: sokszor hvjuk meg -> sok helyre msoldik -> n a kd mrete Makr hasznlata: #define Abs(x)(x<0?-x:x) y=Abs(y); z=Abs(z++); //y=(y<0?-y:y); //z=(z++<0?-z++:z++);
2003
Itt a z rtke nem 1-gyel vltozik! elnye: gyors htrnya: nem vrt eredmnnyel szolglhat
a=8 pop a
b=6 pop b
a=2 pop a
5 2
6 2
8 6 2
6 2
268
befel
->
8 6 2 kifel
A verem megfordtja a benne trolt adatok sorrendjt. Verem megvalstsa dinamikus tmbben trolva. //stack1.h #ifndef _STACK_H #define _STACK_H const int DEFAULT_STACK_SIZE=5; class stack{ private: int maxelemnum,elemnum,*store; 14/38
BevIT: Programozs II. bool Full(); public: stack(int pmaxelemnum=DEFAULT_STACK_SIZE); bool Empty(); bool Push(const int n); bool Pop(int &n); ~stack(); }; #endif // _STACK_H //stack1.cpp #include stack1.h #include <iostream.h> stack::stack(int pmaxelemnum){ maxelemnum=pmaxelemnum; store=new int[maxelemnum]; elemnum=0; } bool stack::Full(){ return elemnum==maxelemnum; } bool stack::Empty(){ return elemnum==0; } bool stack::Push(const int n){ if (Full()) return false; store[elemnum++]=n; return true; } bool stack::Pop(int &n){ if (Empty()) return false; n=store[--elemnum]; return true; } stack::~stack(){ delete store; } int main() { //a fprogram stack *s=new stack; char c; int n; do{ cout<<(P)ush\n(P)op\n(E)xit\n;
2003
15/38
BevIT: Programozs II. cout<<Enter your selection : ; cin>>c; if(c==p){ cout<<Enter a number:; cin>>n; if(s->Push(n)) cout<<OK!\n); } if(c==o){ if(s->Pop(n)) cout<<n<<\n;} else cout<<Empty stack.\n; }while (c!=e); delete s; return 0; } Verem megvalstsa dinamikusan lncolt listval 2 5 8 X
2003
Stack_elem*
int
stack_elem*
NULL pointer
//stack2.h #ifndef _STACK2_H #define _STACK2_H struct stack_elem{ int n; stack_elem *next; }; class stack{ protected: stack_elem *top; public: stack(); bool Empty(); bool Push(const int n); bool Pop(int &n); ~stack(); }; #endif _STACK_H //stack2.cpp #include stack2.h stack::stack(){ top=0; } bool stack::Empty(){ return top==0; } 16/38
BevIT: Programozs II. bool stack::Push(const int n){ stack_elem *new_elem=new stack_elem; if (new_elem==0) return false; new_elem->n=n; new_elem->next=top; top=new_elem; return true; } 5 top Push(3) //1 new_elem //2 3 new_elem //3
3
2003
ltrejn
beleteszi a hrmat
new_elem
top 5
//4 3 5 2 X
top
bool stack::Pop(int &n){ stack_elem * to_delete; if (Empty()) return false; to_delete=top; n=to_delete->n; top=to_delete->next; delete to_delete; return true; }
17/38
2003
18/38
2003
5 to_delete top
//4 to_delete X
top
2 //destruktor
Szrmaztats s rkls
OOP tulajdonsgai: - egysgbezrs - szrmaztats, rkls - poliformizmus fogalma: a szrmaztats az az eljrs, melynek eredmnyeknt egy osztlybl egy msik osztlyt kapunk, mikzben annak (az snek) nhny tulajdonsgt megtartjuk (rktjk) a leszrmaztatott (gyermek) osztlyba, msokat megvltoztatunk s kiegsztnk. sosztly > szrmaztats -> szrmaztatott (gyermek) osztly A gyermek az s tulajdonsgait rkli, de ezek nhetnek, cskkenhetnek s vltozhatnak is. 19/38
2003
csak az osztlyon bell hozzfrhetek (legszigorbb) az osztlyban s szrmaztatott osztlyaiban (gyermekeiben) hozzfrhetek tetszlegesen hozzfrhet
Private
Protected
private NEM private protected Hozzprotected public frhet protected A szrmaztats csak szigorthatja a hozzfrs szabjait! Pl.: //stack3.h #ifndef _STACK3_H #define _STACK3_H #include stack2.h class adv_stack:public stack{ public: bool Top(int &n); }; #endif //stack3.cpp bool adv_stack::Top(int &n){ if (Empty()) return false; n=top->n; return true; } Osztlydiagram adv_stack
top Push Pop Empty Top Szrmaztats: public
stack
top Push Pop Empty
Polimorfizmus (tbbalaksg/tbbarcsg):
Metdus tdefinils (method overloading): Ha a szrmaztatott osztlyban definilunk s megvalstottunk azonos nev s argumentum metdust, mint amilyen nev s paramter az sben volt, akkor:
20/38
2003
a) A szrmaztatott osztlyban s annak leszrmaztatott osztlyaiban, metdusaiban az tdefinilt metdus nevvel a szrmaztatott osztlybeli metdushoz frnk hozz. b) Az sosztly metdusaiban vltozatlanul az s osztlybeli metdushoz frnk hozz. Pl.: #include <iostream.h> class clA{ private: void fv1(){cout<<clA::fv1\n;}; public void fv2(){cout<<clA::fv2\n;}; void fv3(){cout<<clA::fv3\n;}; }; class clB:public clA{ public: void fv1(){cout<<clB::fv1\n;}; void fv2(){cout<<clB::fv2\n;}; }; int main(){ clA a,*pa; clB b,*pb; a.fv2(); a.fv3(); pa=&a pa->fv2(); pa->fv3(); b.fv1(); b.fv2(); b.fv3(); pb=&b; pb->fv1(); pb->fv2(); pb->fv3(); pa=&b pa->fv1(); pa->fv2(); pa->fv3(); clB a Fv1 Fv2 Fv3
//a.fv1 nem frhet hozz //clA::fv2 mert private //clA::fv3 //pa->fv1(); nem hajthat vgre mert private //clA::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 //nem hajthat vgre //clA::fv2 //clA::fv3 clA Fv1 Fv2 Fv3
Szrm.: public
b 21/38
2003
clB pb=&b
pa=&b b
Megjegyzs: sosztlyra mutat pointer megkaphatja egy szrmaztatott osztlybeli objektum cmt, de csak azokhoz a metdusokhoz frnk hozz e pointeren keresztl, melyek az s osztlyban definiltak.
Virtulis metdusok:
Ha a szrmaztatott osztlyban definilunk s megvalstunk azonos nev s argumentum virtulis metdust, mint amilyen nev s argumentum az sben ltezett, akkor : - a szrmaztatott osztly metdusaiban, - annak leszrmazottaiban s az sosztlytl rklt metdusokban is az tdefinilt metdus nevvel a szrmaztatottbeli vltozatot rjk el. Pl.: #include <iostream.h> class clA{ private: void fv1(){cout<<clA::fv1\n;}; public: virtual void fv2(){cout<<clA::fv2\n;}; void fv3(){cout<<clA::fv3\n;fv2();}; }; class clB:public clA{ public: void fv1(){cout<<clB::fv1\n;}; virtual void fv2(){cout<<clB::fv2\n;}; }; int main(){ clA a,*pa; clB b,*pb; a.fv2(); a.fv3(); pa=&a; pa->fv2(); pa->fv3(); b.fv1(); b.fv2(); b.fv3(); pb=&b; pb->fv1(); pb->fv2(); pb->fv3();
//a.fv1() nem rhet el(private) //clA::fv2 //clA::fv3 //pa->fv1()nem rhet el(private) //clA::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 clB::fv2 // clB::fv1 // clB::fv2 // clA::fv3
clB::fv2 22/38
BevIT: Programozs II. pa=&b; pa->fv2(); pa->fv3(); return 0; } clA v. clB v. pb b Ktfle szmol eljrs kzs ssel s mdostott (tdefinilt) metdussal: // calc.cpp #include <iostream.h> class calc{ protected: double a,b; double Get(); virtual double Result(); public: void GetInput(); void PutResult(); }; double calc::Get(){ double d; cout<<"Enter a number: "; cin>>d; return d; } void calc::GetInput(){ a=Get(); b=Get(); } void calc::PutResult(){ cout<<"The result is: "<<Result()<<'\n'; } double calc::Result(){ return 0.0; fv1 fv2 fv3 virtualits miatt fv1 fv2 fv3
clA v. pa=&b
23/38
BevIT: Programozs II. } class add_calc:public calc{ virtual double Result(); }; double add_calc::Result(){ return a+b; } class sub_calc:public calc{ virtual double Result(); }; double sub_calc::Result(){ return a-b; } int main(){ calc *c0; char c; do{ cout<<"(s)um\n(d)ifference\nEnter your selection: "; cin>>c; }while (c!='s' && c!='d'); if (c=='s') c0=new add_calc; else c0=new sub_calc; c0->GetInput(); c0->PutResult(); delete c0; return 0; } add_calc Get GetInput PutResult Result Szrm: public Virtulis metdusok calc (s) Get GetInput PutResult v. Result
2003
meghvs
v.
Binris keresfa
Binris fa: krmentes, irnytott (erd), sszefgg grf fa. A cscsok Kifoka (kiindul lek szma) legfeljebb kett, ezrt binris.
24/38
BevIT: Programozs II. Plda: gykr gykrhez tartoz bal oldali rszgrf
2003
levelek
Amelyik cscs befoka nulla, azt gykrnek, amelyik cscs kifoka nulla, azt levlnek nevezzk. Binris fban egy cscsbl kiindul kt let bal s jobb gnak nevezzk. Egy cscshoz a bal (jobb) gn kapcsold sszefgg rszgrfot bal (jobb) oldali rszgrfnak nevezzk. Fa bejrsi algoritmusok: PreOrder : kzp(cscs), bal(g), jobb(g) InOrder : bal(g), kzp(cscs), jobb(g) PostOrder: bal(g), Jobb(g), kzp(cscs) 1 2 4 5 3 6 7 Bejrsa: PreOrder: InOrder: PostOrder: 1-2-4-3-5-6-7 4-2-1-5-3-6-7 4-2-5-7-6-3-1
Binris keresfa: dinamikus adatszerkezet a trolt adatokon rendezst feltteleznk egy cscshoz tartoz bal oldali rszgrfban a rendezs szerint csak nla kisebb vagy egyenl cscsok vannak egy cscshoz tartoz jobb oldali rszgrfban csak nla nagyobb elemek vannak (a rendezs szerint)
25/38
BevIT: Programozs II. Plda.: binris keresfa felptse a 4,9,7,6,2,8,10,10 szmok trolsra
4 2 7 6 8 10 9 10
2003
InOrder bejrssal kiolvasva :2,4,6,7,8,9,10,10 Binris keresfa felptse: elemek egyenknti beszrsval: Eljrs Beszr (fa, elem); Ha a fa nem ltezik, akkor a fa=elemet tartalmaz egyetlen cscs; Klnben Ha fa.gykr >= elem, akkor beszr (fa.balg, elem); Klnben Beszr (fa.jobbg, elem); Eljrs vge; Fa lebontsa PostOrder eljrssal ( a cscsot tntetjk el utoljra). Eljrs lebont (fa); Ha ltezik fa.balg, akkor lebont (fa.balg); Ha ltezik fa.jobbg, akkor lebont (fa.jobbg); Trl fa; Eljrs vge; Mirt hatkony adatszerkezet? Egy cscs megtallsa legfeljebb pr lpsben trtnik, ahol a m a binris magassg. A binris keresfban egy elem megtallshoz szksges lpsszm = l 0<= l <=m A binris fa magassga: log2 n <= m <= n-1 ahol n az elemek szma (cscsok szma) legjobb eset: 0<= l <= log2 n legrosszabb eset: 0<= l <= n-1 vrhat rtkben: l log2n Rendezs binris keresfval: Bemenet : elemek sorozata Kimenet : elemek rendezett sorozata Lps : a) elemek beraksa binris keresfba b) elemek kiolvassa InOrder eljrssal
26/38
BevIT: Programozs II. Rendezs binris keresfval: (C++ megvalstsa) //Binary Tree Sort #include <iostream.h> class tree{ private: int key; tree *less,*greater; public: tree(const int i); void Insert(const int i); void GetContent(int* t,int &c); ~tree(); }; tree::tree(const int i){ key=i; less=0; greater=0; } void TreeInsert(tree* &t,const int i){ if (t) t->Insert(i); //ha ltezik a fa beszrja i-t else t=new tree(i); //klnben ltrehozza } tree::~tree(){ if (less) delete less; if (greater) delete greater; } void tree::Insert(const int i){ if (i<=key) TreeInsert(less,i); else TreeInsert(greater,i); } void tree::GetContent(int* t,int &c){ if (less) less->GetContent(t,c); t[c++]=key; if (greater) greater->GetContent(t,c); } int main(){ int i,*out,c=0; char ch; tree* t=0; do{ cout<<"Enter the number: "; cin>>i;
2003
27/38
2003
c++; TreeInsert(t,i); do{ cout<<"Is there any other number ? (y/n): "; cin>>ch; }while (ch!='y' && ch!='n'); }while (ch!='n'); out=new int[c]; c=0; t->GetContent(out,c); cout<<"Numbers in decreasing order:\n"; while (c) cout<<out[--c]<<' '; delete t; return 0; } Lpsek: (plda) 0) t=0 1) az 5 szm beszrsa tree* key=5 less=0 2) a 2 szm beszrsa: greater=0
out[0]=2; c=1
3) szmok kiolvassa: b) lps t-> GetContent: meghvja a: a) t->less->GetContent, out[0]=2, c=1 out[1]=5, c=2 4) szmok kirsa: out[1]->5 out[0]->2 Msol konstruktor (copy constructor): A msol konstruktor pontosan egy argumentummal rendelkezik, amely argumentum tpusa az adott osztlyba tartoz objektumra hivatkoz referencia tpus, ltalban konstans.
28/38
2003
Feladata: a paramterknt kapott objektummal azonos tartalm pldnyt (objektumot) hozzon ltre. Pl.: sx sx1(), sx2(sx1),*sx3; sx3=new sx(sx1); Mikor van szksg msol konstruktorra: rtk szerinti paramter tads sorn vltoz/objektum msolatt a fordt a msol konstruktor segtsgvel kszti el. Pl.: void StrLen(const string s) fggvny hvsakor a string::string(const string&); konstruktor hvdik meg. rtk szerinti visszatrsi rtk esetn: Pl.: string UpperCase(const string &s){ string s1; : return s1;} //e sor hatsra is a string::string(const string&) msol konstruktor hvdik meg.
Cm szerinti (hivatkozs tpus) visszatrsi rtk A referencin keresztl kzvetlenl azt a vltozt adja vissza, mely a return utn szerepel. FONTOS! Ez a vltoz nem lehet az eljrs loklis vltozja. Pl.: class store{ private: int s; public: int &GetState(){return s;}; Ekkor a msol konstruktor nem hajtdik vgre. Alaprtelmezett msol konstruktor(cc): He egy osztlyban a msol konstruktor nem definilt, akkor a fordt alaprtelmezett msol konstruktort generl, mely az osztlyban trolt minden statikus adattagot lemsol. Kvetkezmny: dinamikus adatszerkezeteket tartalmaz objektumok msolsra az alaprtelmezett (default) msol konstruktor nem alkalmas, teht a dinamikus adatszerkezeteket tartalmaz osztly msol konstruktort mindig definilni kell.
29/38
BevIT: Programozs II. Pl.: class store{ int state : }; : store s1(2),s2(s1) s1 state=2 store Pl.: def. konstr. s2 state=2 store
2003
class stack{ top* stack_elem; : }; stack st1; st1.valami; stack st2(st1); st1 Top E0120001 stack X st2 Top E0120001 stack
Itt hiba van! Ha az osztly dinamikus adatszerkezetet tartalmaz, akkor az alaprtelmezett msol konstruktor csak a mutatkat msolja le, melyek gy azonos trterletre mutatnak, teht ha az egyik adatszerkezet megvltozik vagy megsznik, akkor a msik is. Fontos!: ha egy osztly dinamikus adatszerkezeteket tartalmaz, akkor meg kell rni a msol konstruktort, ami azt tmsolja. Pl.: ltrehozza a verem elemeit tartalmaz lncolt lista egy jabb megvalsulst, ami a lemsolttal azonos adatokat tartalmaz.
Opertorok
Pl.: a+b ltalban van visszatrsi rtke mindig van legalbb egy argumentuma hvsa s deklarcija a fggvnyektl szintaktikjban klnbzik. // + opertor kt argumentuma van: a kt sszeadand szm van visszatrsi rtk: a kt szm sszege a + opertor jellemzen nem vltoztatja meg az argumentumait, vagyis argumentumai konstans paramterek.
30/38
BevIT: Programozs II. Pl.: a=b Pl.: //rtkads opertor kt argumentuma van, jellemzen a jobb oldali (msodik) nem vltozik (konstans), a bal oldali (els) vltozik (referencia tpus) visszatrsi rtke is jellemzen a msodik argumentum rtke
2003
a= =b //logikai egyenlsg opertor - jellemzen kett konstans argumentuma van - jellemzen logikai visszatrsi rtk
Opertorok definilsa fggvnyknt: Szintaxis: <vissz.rt. tpusa> operator <op.jele> (argumentumok) Pl.: cl operator=(cl &a,cl b); cl operator+(const cl &a, const cl &b); bool operator==(const cl &a, const cl &b); Megjegyzs: az opertorok argumentumainak tpusait tetszlegesen vlaszthatjuk, de az argumentumok szma nem trhet el a nyelvre szoksostl. Pl.: = op.: 2 argumentum + op.: 2 argumentum ! op.: 1 argumentum ? op.: 3 argumentum j fle opertort nem lehet ltrehozni, csak tdefinilni a mr meglvket. Opertor definilsa osztly metdusaknt: Ekkor az opertort az els argumentumnak tagfggvnyeknt rtelmezzk. Pl.: class clx{ public: clx operator=(const clx &b); clx operator+(const clx &b) const; bool operator==(const clx &b) const; }; clx a,b,c; a=b; c=a+b; //a.operator = (b); hvdik //c.operator = (a.operator+(b)); hvdik
BevIT: Programozs II. int len; void Init(); void New(const int plen); void Delete(); public: string(); ~string(); string& operator=(const char c); string& operator=(const char* pstore); string& operator=(const string& s); string(const char c); string(const char *pstore); string(const string &s); string operator+(const string& s)const; int Len()const{return len;}; void CopyCharsTo(char* const s, const int maxlen)const; }; int StrLen(const char *pstore); inline int StrLen(const string &s); ostream& operator<<(ostream &o,const string &s); #endif // _STR_H //str2.cpp #include <memory.h> #include "str2.h" int StrLen(const char *pstore){ int len=0; while (pstore[len]) len++; return len; } inline int StrLen(const string &s){ return s.Len(); } void string::Init(){ len=0; store=0; } void string::New(const int plen){ Delete(); len=plen; store=new char[len]; } void string::Delete(){ if (store) delete store;
2003
32/38
BevIT: Programozs II. } string::string(){ Init(); } string::~string(){ Delete(); } string& string::operator=(const char c){ New(1); store[0]=c; return *this; } string& string::operator=(const char* pstore){ New(StrLen(pstore)); memcpy(store,pstore,len); return *this; } string& string::operator=(const string& s){ New(StrLen(s)); memcpy(store,s.store,len); return *this; } string::string(const char c){ Init(); *this=c; } string::string(const char *pstore){ Init(); *this=pstore; } string::string(const string& s){ Init(); *this=s; } string string::operator+(const string& s)const{ string s2; s2.New(len+s.len); if (len) memcpy(s2.store,store,len); if (s.len) memcpy(s2.store+len,s.store,s.len); return s2; } void string::CopyCharsTo(char* const s,const int maxlen)const{ int s.len= len<maxlen ? len : maxlen; if (s.len) memcpy(s,store,s.len);
2003
33/38
BevIT: Programozs II. s[len]=0; } ostream& operator<<(ostream &o,const string &s){ int len=s.Len(); char* ps=new char[len+1]; s.CopyCharsTo(ps,len); o<<ps; delete ps; return o; }
2003
2003
Tpuskonverzi
C++-ban a tpuskonverzi mindig konstruktorokon keresztl valsul meg. Egy B tpus (osztlyba tartoz) vltoz (objektum) akkor konvertlhat A tpusv (osztlyba tartozv), ha az A osztlyban szerepel B argumentum konstruktor. (B->A tpuskonverzi) Pl.: class A{ public: A (const &B) }; Gyakorlati plda: char char* string sstring
a nyilak konvertlst jeleznek Explicit konverzi: a forrskdban kdrszlet hvja az A osztly B argumentum konstruktort a B>A tpuskonverzi megvalstsra clja olyan fggvny vagy operator hasznlatnak lehetv ttele, amely B argumentummal nem, de A argumentummal rtelmezett. void test(A){}; { test (A (B) ); } //konstruktor
Pl.:
- a tpuskonverzi eredmnyeknt egy A tpus tmeneti vltoz (objektum) jn ltre Implicit tpuskonverzi: A fordt tpuskonverzit vgez, ha egy fggvnyt vagy operatort, mely: a) B argumentummal nem, de A argumentummal rtelmezett b) adott nev fggvnyt vagy operatort B argumentummal hvjuk c) ltezik A-nak B argumentum konstruktora
Pl.: test(B) //B-vel hvjuk Gyakorlati plda: void test(const sstring &s){}; int main(){ string s; sstring ss; test(ss); test(sstring(s)); //explicit: string->sstring konv. test(s); //gy is j; impicit: string->sstring konv. test(sstring(string(abc))); //explicit: char*->sting //explicit: string->sstring konv. test(string(abc)); //explicit: char*->sting 35/38
BevIT: Programozs II. //implicit: string->sstring konv. test(ssting(abc)); //implicit: char*->sting //explicit: string->sstring konv. Megjegyzs: csak egy mlysgig lehet implicit tpuskonverzit vgrehajtani! Pl.: test(abc); //2 mlysg implicit konverzira a fordt nem kpes! Ha lenne a string-nek char* tpus konstruktora, akkor ez is mkdne. Megjegyzs: explicit konverzi tetszleges mlysgben trtnhet.
2003
//Universal Binary-Tree Sort Feltevsek typ-re: typ-nek van default konstruktora (typ :: typ( );) #include <iostream.h> template <class typ> class tree{ private: typ key; tree *less,*greater; public: tree(const typ i); void Insert(const typ i); void GetContent(typ *t , int &c); ~tree(); }; van copy konstruktora (rtk szerint tadhat)
36/38
BevIT: Programozs II. template <class typ> tree <typ>::tree(const typ i){ key=i; less=0; greater=0; }; van = opertora ( typ = typ) template <class typ> void TreeInsert(tree<typ>*&t,const typ i){ if (t) t->Insert(i); else t=new tree <typ> (i); } template <class typ> void tree<typ>::Insert(const typ i){ if (i<Key) TreeInsert(less,i); else TreeInsert (greater,i); } van < opertora (typ < typ) template <class typ> void tree<typ>::GetContent(typ *t,int &c){ if (less) less->GetContent(t,c); t[c++]=key; if (greater) less->GetContent(t,c); } template <class typ> tree <typ>::~tree(){ if (less) delete less; if (greater) delete greater; }
2003
int main(){ double i,*out; int c=0; char ch; tree <double> *t=0; do{ cout<<Enter a real value:; cin>>i; c++; TreeInsert(t,i); do{ cout<<Is there other value?(y/n); cin>>ch; }while (ch!=y && ch!=n); }while (ch!=n); 37/38
BevIT: Programozs II. out=new double[c]; c=0; t->GetContent(out,c); c=0; cout<<Values in decreasing order:\n; while (c) cout<<out[--c]<< ; delete t; delete out; return 0; }
2003
38/38
2003
Ajnlott irodalom: Stanley B. Lippmann: C++ elszr /Novotrade kiad/ Benk Tiborn, Popper Andrs, Benk Lszl: Bevezets a Borland C++ programozsba Dr. Kondorosi Kroly, Dr Szirmai-Kalos Lszl, Dr. Lszl Zoltn: Objektum orientlt szoftverfejlszts /Computer Book kiad/ A jegyzetet feldolgozta: Borbly Viktor, Bertk Botond eladsai nyomn. Kszlt: 2003
39/38