Programozás C++ típusok, operátorok
Fodor Attila Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék
[email protected]
2010. március 4.
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
Deklaráció és definíció
Deklaráció Minden névről meg kell mondani mire szeretnénk használni, mert ennek a hiányában a fordító nem tud mit kezdeni az adott névvel A tulajdonságai a következők: típus, tárolási osztály, láthatóság Nem történik memória foglalás
Definíció Ha az a cél, hogy a deklarációnak megfelelő objektum is létrejöjjön a memóriában akkor DEFINÍCIÓT kell alkalmazni. A DEFINÍCIÓ olyan DEKLARÁCIÓ, amely helyfoglalással jár.
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
2 / 43
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
A C++ nyelv típusai Skalár (egyszerű típus) Aritmetikai típusok Egész jellegű típusok char int enum Lebegőpontos típusok float double
Mutató típusok Referencia típus void
Összetett típus Összeállított típusok Tömb típusok Structúra (struct) típusok
Unió (union) típusok Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
3 / 43
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
Alaptípusok, Típusmódosítók, Típusminősítők, Típuselőírás Alaptípusok char int float double enum struct union void (típusnév hiánya; üres típus)
Típusmódosítók short (a tárolási hosszat szabályozza) long (a tárolási hosszat szabályozza) signed (előjeles) unsigned (előjel nélküli)
Típusminősítők: const (olyan objektum definiálható, amely nem változatható meg (olvasható objektum)) Típuselőírás: (alaptípus, típusmódosítók, típusminősítők) Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
4 / 43
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
Változók mérete (sizeof operátor)
sizeof kifejezés sizeof(típus) sizeof(char) ⇒ 1 byte (8 bit) sizeof(short) ≥ 2 byte (16 bit) sizeof(long) ≥ 4 byte (32 bit) sizeof(short) ≤ sizeof(int) sizeof(int) ≤ sizeof(long) Az int mindig az adott arcitektúrán a gépi szó mérete
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
5 / 43
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
Az MS Visual Studio-ban használható típusok
(Nem csak ANSI C++ típusok) Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
6 / 43
C++ típusok
C++ nyelvben használható típusok, változók, aritmetika
Változók és aritmetika Aritmetikai műveletek: char, int, float, double, enum + // összeadás vagy előjel, egy- és kétoperandusú is lehet - // kivonás vagy előjel, egy- és kétoperandusú is lehet * // szorzás / // osztás % // maradékképzés
Összehasonlító műveletek: char, int, float, double, enum == // egyenlő != // nem egyenlő < // kisebb > // nagyobb <= // kisebb vagy egyenlő >= // nagyobb vagy egyenlő
Bitenkénti operátorok Logikai operátorok Léptető operátorok Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
7 / 43
C++ típusok
Referencia típus
Referencia (hívatkozás) típus Egy objektum "álneve" (alias) Függvények (és túlterhelt operátorok) paramétereinek és visszatérési értékeinek megadására használható hatékonyan A jelölés jelentése: "Hivatkozás A-ra" Példa: int i = 100; int& ref = i; int x = ref; ref = 200;
// r és i itt ugyanarra az int-re hivatkoznak // x = 100 // i = 200
A referencia célpontját létrehozáskor meg kell határozni!!! Példa: int& ref = i; int& ref2; extern int& ref3;
Fodor A. (Pannon Egyetem)
// // // //
OK Hibás referencia megadás nincsen kezdeti érték megadva OK (Később kap értéket)
Programozás
2010. március 4.
8 / 43
C++ típusok
Referencia típus
Referencia (hívatkozás) típus
A referencián nem hajtódik végre utasítás (nem változik az értéke) Az utasítás mindig azon hajtódik végre, amire mutat a referencia Példa: int i = 0; int& ref = i; ref++; int* p = &ref;
// i növelése // p az i-re mutat
void cplusplus(int& c) { c++; }
Egyes fordítók fizikailag referenciával valósítják meg a referencia típust
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
9 / 43
C++ típusok
Felhasználói típus
Felhasználói típus
Absztrakt típus (abstract data type, ADT) Felhasználói típus (user-defined type) A beépített típusokkal közel azonos viselkedés Megközelítés: "Döntsd el, mely típusokra van szükség és mindegyikhez biztosíts teljes műveletkészletet." Stroustrup Absztrakt típus (abstract data type, ADT) A felület elszigeteli a felhasználót a megvalósítás részleteitől
Konkrét típus A felület nem teljesen szigeteli el a felhasználót a megvalósítás részleteitől
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
10 / 43
C++ típusok
Felhasználói típus
Felhasználói típus - példa
Példa: Complex számok kezelése class CComplex { private: double Im, Re; public: CComplex(double x, double y, bool IsImRe=1); CComplex() {Im=0; Re=0;}; double GetIm() const {return Im;}; double GetRe() const {return Re;}; double GetR() const {return sqrt(Re*Re+Im*Im);} double GetPhi(); double SetIm(double x) {Im = x;}; double SetRe(double x) {Re = x;}; };
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
11 / 43
C++ típusok
Felhasználói típus
Felhasználói típus - operátor
Probléma: Milyen műveletek értelmezettek a típuson Összeadás, kivonás, összehasonlítás, stb.
I. megoldás Osztályfüggvények alkalmazása Minen művelethez meg kell írni Meg kell hívni egyesével a függvényeket az osztálypéldányon
I. megoldás Operátorok alklamazása (+ - * / == != stb.) Operátorokat el kell készíteni
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
12 / 43
C++ típusok
Felhasználói típus
Felhasználói típus operátora - példa Példa: Complex számok kezelése class CComplex { private: double Im, Re; public: CComplex(double x, double y, bool IsImRe=1); CComplex() {Im=0; Re=0;}; double GetIm() const {return Im;}; double GetRe() const {return Re;}; double GetR() const {return sqrt(Re*Re+Im*Im);} double GetPhi(); double SetIm(double x) {Im = x;}; double SetRe(double x) {Re = x;}; friend friend friend friend friend friend
CComplex operator+(CComplex a1, CComplex a2); CComplex operator-(CComplex a1, CComplex a2); CComplex operator/(CComplex a1, CComplex a2); CComplex operator*(CComplex a1, CComplex a2); bool operator==(CComplex a1, CComplex a2); bool operator!=(CComplex a1, CComplex a2);
}; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
13 / 43
C++ típusok
Felhasználói típus
Felhasználói típus operátora - példa Példa: Complex számok kezelése CComplex operator+(CComplex a1, CComplex a2) { return CComplex(a1.Re+a2.Re, a1.Im+a2.Im); } CComplex operator-(CComplex a1, CComplex a2) { return CComplex(a1.Re-a2.Re, a1.Im-a2.Im); } bool operator==(CComplex a1, CComplex a2) { return ((a1.Re==a2.Re)&&(a1.Im==a2.Im))?true:false; } bool operator!=(CComplex a1, CComplex a2) { return ((a1.Re==a2.Re)&&(a1.Im==a2.Im))?false:true; } Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
14 / 43
C++ típusok
Felhasználói típus
Felhasználói típus operátora - példa
Példa: Complex számok kezelése ComplexExample() { CComplex c1(1,0); CComplex c2(1,1); CComplex c3 = c1 + c2*CComplex(1, 2); // ... if (c1 != c2) c3 = (c1/c2) + c2; else c3 = (c1/c2); }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
15 / 43
C++ típusok
Mutatók, Tömbök
Mutatók Minden változó memóriában levő helye (címe) képezhető Minden függvény memóriában levő helye (címe) képezhető Ez a cím mutató típusban (pointerben) tárolható A pointer típus értékkészlete egy memória cím A pointer mindig egy meghatározott típusú objektumra mutat
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
16 / 43
C++ típusok
Mutatók, Tömbök
Mutatók használata Mutató típus definiálása: pointer_tipusa *pointer_neve Változó címének meghatározása: &valtozo_neve Mutató által mutatott változó értéke: *pointer_neve int i, *ip, v[10]; i = 123; ip = &i; *ip = 123; ip = &v[2]; double d, *dp double* dp2; void *p; int **ipp; int* *ipp2;
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
17 / 43
C++ típusok
Mutatók, Tömbök
Tömb alkalmazása Tömb mérete A fordítóprogram határozza meg az elemtípusok méretének a függvényében A méret mindig fordítási időben döl el! Méret meghatározása: sizeof(tömb_neve)/sizeof(elem_típusa); int v[50]; int n=sizeof(v)/sizeof(int);
Tömb bejárása Általában for ciklussal történik int i; register int i; //Nagy elemszám esetén for(i=0; i
Kezdeti érték adása tömböknek tipus tömb_neve[] = érték1, érték2...; A tömb méretét a fordító határozza meg a felsorolt konstansok alapján Példa: int adatok[] = 1, 2, 3, 4, 5; char szoveg[] = "alma"; char szoveg2[] = 65, 76, 77, 65, 0 ; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
18 / 43
C++ típusok
Mutatók, Tömbök
Többdimenziós tömbök Megadása: típus tömb_neve[méret_dim1][méret_dim2] típus tömb_neve[méret_dim1][méret_dim2][méret_dim3] típus tömb_neve[méret_dim1][méret_dim2]...[méret_dim_n]
int i,j; int tomb2d[100][50] for(i=0; i<100; i++) for(j=0; j<50; j++) tomb2d[i][j]=0; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
19 / 43
C++ típusok
Template osztály
Sablon/Tamplate osztály Ötlet: Az osztály általánosítása → sablon létrehozása
template
előtag T-t az utána következő deklaráció paraméterévé teszi. Példa: Verem kezelése template class CStack { T* v; int max_size; int top; public: class Underflow { }; // hibakezelés class Overflow { }; // hibakezelés CStack(int s); // konstruktor ~CStack(); // destruktor void Push(T); T Pop(); }; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
20 / 43
C++ típusok
Template osztály
Sablon/Template osztály
Példa: Verem kezelése (Függvények megadása) template void CStack::Push(T c) { if (top == max_size) throw Overflow(); v[top] = c; top = top + 1; } template T CStack::Pop() { if (top == 0) throw Underflow(); top = top - 1; return v[top]; }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
21 / 43
C++ típusok
Template osztály
Sablon/Template osztály Példa: Verem kezelése (Függvények megadása) CStack st_int(100); CStack st_cmplx(50); CStack< list > st_list(50);
// verem 100 int-nek // verem 50 komplex számnak // verem 50, int-ből álló lista számára
void StackExample() { st_int.push(100); if (st_int.pop() != 100) { //... //Hiba a veremkezelésben } st_cmplx.push(Ccomplex(0,0)); if (st_cmplx.pop() != CComplex(0,0)) { //... //Hiba a veremkezelésben } }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
22 / 43
C++ típusok
Template osztály
Sablon/Template osztály használata
Adatszerkezetek kezelése Lista Vektor Tömbök (map) stb.
Fordítási időben van jelentősége Nem növeli meg futási időt a "hagyományos kódoláshoz" képest Container Class (tároló, konténer) Osztály elnevezés Valamilyen típusú elemek gyűjteményét tartalmazza
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
23 / 43
Standard könyvtárak
iostream
iostream Adatfolyam-bemeneti és -kimeneti szolgáltatások Kimenetek és bemenetek kezelése A << kimeneti operátor második operandusát beírja az elsőbe A >> bemeneti operátor első operandusát beírja a másodikba
Karakterláncok (string) kezelése Listák, vektorok kezelése .. . Példa: #include #include<string> #include<list> CComplex c(1,0), c2(1,1); std::cout << "Im: " << c.GetIm() << "
Re: " << c.GetRe() << " \n\n";
std::string str = "Szoveg..."; int i; std::in >> i; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
24 / 43
Standard könyvtárak
iostream
Kimenet iostream könyvtár meghatároz egy kimenetet A << kimeneti operátor második operandusát beírja az elsőbe Példa: #include #include<string> #include<list> //... CComplex c(1,0), c2(1,1); printf("Im: %lf std::cout std::cout std::cout std::cout std::cout
<< << << << <<
\nRe : %lf \n\n", c.GetIm(), c.GetRe());
"Im: "; c.GetIm(); " Re: "; c.GetRe(); "\n\n";
std::cout << "Im: " << c.GetIm() << " std::string str = "Szoveg..."; Fodor A. (Pannon Egyetem)
Programozás
Re: " << c.GetRe() << " \n\n";
2010. március 4.
25 / 43
Standard könyvtárak
iostream
Névtér Standard könyvtár az std névtérhez tartozik std::cout helyett, ha cout nem működik #include #include<string> //... CComplex c(1,0), c2(1,1); cout cout cout cout cout
<< << << << <<
"Im: "; c.GetIm(); " Re: "; c.GetRe(); "\n\n";
string str = "Szoveg...";
Hiba: complex.cpp(130) : error C2065: ’cout’ : undeclared identifier
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
26 / 43
Standard könyvtárak
iostream
Névtér beállítása Névtér beállítása using namespace nevter_neve; #include #include<string> //... CComplex c(1,0), c2(1,1); std::cout std::cout std::cout std::cout std::cout
<< << << << <<
"Im: "; c.GetIm(); " Re: "; c.GetRe(); "\n\n";
//Itt nem hagyható el az std::
using namespace std; cout << "Im: " << c.GetIm() << " string str = "Szoveg...";
Re: " << c.GetRe() << " \n\n";
Hiba: (a névtér beállítása előtt hanyagoljuk el a beállítást) complex.cpp(130) : error C2065: ’cout’ : undeclared identifier
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
27 / 43
Standard könyvtárak
iostream
Bemenet
istreams szolgál bemenetek kezelésére A >> bemeneti operátor első operandusát beírja a másodikba Példa: #include \\... using namespace std; \\... int i; cin >> i; double d; cin >> d;
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
28 / 43
Standard könyvtárak
iostream
Bemenet
Egész sor beolvasása getline() függvény segítségével Példa: #include #include <string> \\... using namespace std; \\... string str; cout << "Írja be a nevét!\n"; getline(cin,str); cout << "Helló, " << str << "!\n";
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
29 / 43
Standard könyvtárak
iostream
Karakterlánc (string)
Karaktersorozatok eltárolására használható típus Karaktrlánc-műveletek Operátorok használata (pl.: + - == !=) #include #include<string> //... using namespace std; string str1 = "Programozás "; string str2 = "Előadás "; string TantargyNev = str1+str2;
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
30 / 43
Standard könyvtárak
iostream
Karakterlánc (string) Kimenetre, bemenetre átirányítható: string str1 = "Helyes?"; string str2; cout << str1; cin >> str2;
Összehasonlítás string str2; cout << "Helyes? (igen/nem); cin >> str2; if (str2 == "igen") { ... }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
31 / 43
Standard könyvtárak
iostream
Karakterlánc (string) Paraméterként átadható #include \\... using namespace std; \\... void AddNewLine(string& str1, string& str2) { str1 = str1 + ’\n’; str2 += ’\n’; } \\ ... string str1="123"; string str2="1234"; AddNewLine(str1, str2); cout << str1 << " " << str2 << "
Fodor A. (Pannon Egyetem)
Programozás
";
2010. március 4.
32 / 43
Standard könyvtárak
iostream
Stringeken értelmezhető műveletek/fogalmak Bejárók Az elemek (karakterek) elérése Konstruktor Hibák kezelése, detektálása Értékadás Átalakítás C stílusú karakterláncra Összehasonlítás Beszúrás Összefűzés Keresés Csere Részláncok Méret és kapacitás (memóriakezeléssel kapcsolatos) Ki- és bemeneti műveletek Felcserélés Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
33 / 43
Standard könyvtárak
iostream
C stílusú string
string típus átalakítható Kompatibilítás miatt szükséges/hasznos c_str() tagfüggvény végzi az átalakítást #include #include <string> \\... using namespace std; \\... void 2_C_String(string& str1) { printf("Szoveg: %s\n",str1.c_str()); }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
34 / 43
Tárolók
Tárolók
Szabványos tárolók Szabványos tárolók vector Változó hosszúságú vektor list Kétirányú láncolt lista Queue Sor Stack Verem Deque Kétvégű sor Priority_queue Érték szerint rendezett sor set Halmaz Multiset Halmaz, melyben egy érték többször is előfordulhat Map Asszociatív tömb Multimap Asszociatív tömb, melyben egy kulcs többször előfordulhat
std névtérhez tartoznak Header állományokat be kell rakni! , <list>, <map>, stb. Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
35 / 43
Tárolók
Vektor
Vektor Probléma: C nyelvben rögzített méret C nyelvben fordítási időben meg kell adni a méretet Nem hatékony a memóriakezelés
Példa: struct VarStar { public: string Name; double JD; double Magnitude; };
//C++
VarStar Observe[1000]; Observe[2].JD = 2455259.5; Observe[2].Name = "R CRB"; Observe[2].Magnitude = "6.2";
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
36 / 43
Tárolók
Vektor
Vektor Megoldás, hiányosságok pótlása: Futási időben megadható méret Futási időben változtatható méret Hibás indexelés detektálása
Példa: #include <string> #include using namespace std; class CVarStar { public: string Name; double JD; double Magnitude; }; vector Observe(1000); Observe[2].JD = 2455259.5; Observe[2].Name = "R CRB"; Observe[2].Magnitude = "6.2"; Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
37 / 43
Tárolók
Vektor
Vektor kezelése
Vektor bejárása Hasonlóan a C-s vektorbejáráshoz Példa: void PrintStar(int i) { cout << Observe[i].Name << ’ ’ << Observe[i].JD << ’ ’ << Observe[i].Magnitude << ’\n’; } void PrintObserve() { for(i=0; i
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
38 / 43
Tárolók
Vektor
Vektor mérete
Vektor méretének lekérdezése size() függvény segítségével Vektor méretének megváltoztatása Futási időben változtatható méret Növelhető, Csökkenthető A méret lekérdezhető Példa: void AddStars(int n) { Observe.resize(Observe.size()+n); }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
39 / 43
Tárolók
Vektor
Tartományellenőrzés
Alapértelmezés szerint nincsen benne tartományellenőrzés Akár túl is tudjuk indexelni Példa: VarStar Observe[1000]; Observe[1001].JD = 2455259.5; Observe[1002].Name = "R CRB"; Observe[1003].Magnitude = "6.2";
Gondoskodni kell az ellenőrzősről! Saját függvénnyel leszármaztatott osztályban Kivételkezeléssel
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
40 / 43
Tárolók
Lista
Lista A vektor adatszerkezetben az adatok törlése, hozzáfűzése csak nehézkesen oldható meg Megoldás Lista használata
Példa: #include <list> using namespace std;
list ObserveList; void AddStar(const CVarStar& obs, list::iterator i) { ObserveList.push_front(obs); // hozzáadás a lista elejéhez ObserveList.push_back(obs); // hozzáadás a lista végéhez ObserveList.insert(i, obs); // hozzáadás az i által mutatott el }
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
41 / 43
Tárolók
Asszociatív tömb
Asszociatív tömb
Listában a keresés csak nehezen lehetséges Listában a keresés rossz hatékonyságú Olyan adatszerkezet kellene, amely a következőket tudja: Támogatja a beszúrást Támogatja a törlést Támogatja az érték szerinti keresést
Megoldás Standard könyvtár map típusa A map egy értékpár-tároló
Léterehozása map asszociativ_tomb_neve;
Szokásos elnevezései: map / asszociatív tömb / szótár
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
42 / 43
Tárolók
Asszociatív tömb
Asszociatív tömb - példa Példa: #include <list> #include <string> using namespace std; map<string,double> ObserveMap; void PrintOneObserve(const string& starname) { if (double i = ObserveMap[starname]) cout << starname << ’ ’ << i << ’\n’; }
Illeszkedést keres Ha nem talál illeszkedést az a kulcsra (starname), a ObserveMap egy alapértével tér vissza
Fodor A. (Pannon Egyetem)
Programozás
2010. március 4.
43 / 43