Programozás II. 2. Dr. Iványi Péter
1
C++ • Bjarne Stroustrup, Bell Laboratórium – Első implementáció, 1983
• Kezdetben csak „precompiler” volt – C++ konstrukciót C-re fordította – A kiterjesztés alapján ismerte fel: .cpp .cc .C
• Ma már önálló nyelv, de felülről kompatibilis
2
C++ • Ötletek: – – – –
Simula67: osztályok, származtatott osztályok Algol68: operátor kiterjesztés Ada: template-k Egyéb
• Minden C program lefordítható C++ -ban, de nem biztos hogy ugyanaz a tárgykód lesz.
3
C++ • Előnyök – – – – –
Támogatja a kód újrahasznosítást Új adattípus létrehozása könnyebb Memória kezelés könnyebb Erősebb szintaktikai ellenőrzés „Adat elrejtés” jobb
• Persze lehet és kell is kritikával fogadni az előnyöket! 4
Megjegyzések • Ugyanaz mint C-ben /* valami */
• Egy soros megjegyzés // valami
5
Változók deklarálása • bárhol definiálhatóak { double b; b = 2.14; double c; c = b + 4.5; } 6
Függvények • A fordító pontosan ellenőrzi, hogy egyezik-e a definícióval. • int func(); – C -ben: Egy függvény aminek a visszatérési értéke egész, argumentuma bármi – C++ -ban: Nincs argumentuma!!!
7
include file-ok • C-ben #include <stdio.h>
• C++ -ban #include
– Más név – Kiterjesztés nélkül
8
iostream • printf, scanf helyett az input-output függvények itt vannak deklarálva • Kimeneti „csatorna”: cout • Például: cout << “Hello”;
9
iostream #include int main() { std::cout << "Hello World! I am "; std::cout << 8; std::cout << " Today!" << std::endl; return 0; } Azt is meg kell adni, hogy mely “csomagból” vesszük a csatornát! Az adat típusa „bármi” lehet! 10
iostream #include using namespace std; int main() { cout << "Hello World! I am " << 8; cout << " Today!" << endl; return 0; } A teljes csomagot használjuk, minden elemét, függvényét, stb. 11
iostream #include using namespace std; int main() { cout << "egy decimalis szam: " << dec << 15 << endl; cout << "egy oktalis szam: " << oct << 15 << endl; cout << "egy hexadecimalis szam: " << hex << 15 << endl; return 0; }
Kulcsszót is „betölthetünk” ami kontrollálja a kiírást. 12
Érvényességi kör operátor :: (hatókör operátor) • A program tetszőleges pontjából hivatkozhatunk globális változóra, melynek ugyanaz a neve mint a lokális változónak • Használni fogjuk még: – Osztályoknál (lásd később) – Névtartományoknál (lásd később)
13
Érvényességi kör operátor #include using namespace std; double a = 1.5; int main() { double a = 2.3; cout << ”Lokalis: ” << a << endl; cout << ”Globalis: ” << ::a << endl;
// 2.3 // 1.5
return 0; }
14
Beolvasás #include using namespace std; int main () { int number; cout << "Adj meg egy decimalis szamot: "; cin >> number; cout << "a szam hexadecimalis erteke = 0x"; cout << hex << number << endl; return 0; } 15
szövegek • C -ben – Karakter tömb – Nehézkes kezelés
• C++ -ban – Új adattípus: string #include <string>
16
szövegek #include <string> #include using namespace std; int main() { string s1, s2; // string s3 = "Hello World."; // string s4("I am"); // s2 = "Today"; // s1 = s3 + " " + s4; // s1 += " 8 "; // cout << s1 + s2 + "!" << endl;
ures szovegek szoveg kezdeti ertekkel van kezdeti ertek Ertekadas Szovegek osszefuzese
return 0; } 17
szövegek #include #include using namespace std; char name[30]; int main( ) { strcpy(name, "Sam"); cout << "The name is " << name << '\n'; return (0); } 18
File-ok kezelése • include file • File-ok olvasására az ifstream és írására az ofstream „csatornák” használhatók • Egy sor beolvasásához a getline függvényt lehet használni
19
File-ok kezelése #include <string> #include using namespace std; int main() { ifstream in("test.dat"); // Megnyitas olvasasra ofstream out("testout.dat"); // Megnyitas irasra string s; while(getline(in, s)) out << s << "\n"; return 0;
// Olvassunk be egy sort // irjuk ki a masik fileba
} 20
Igaz és hamis • C -ben – Adattípusok: char, int, float, double – hamis: nulla – igaz: nem nulla
• C++ -ban – bool típus, értéke: true, false
21
Igaz és hamis #include using namespace std; int main() { bool felt; int a; felt = false; if(felt) // ez hamis lesz a = 1; else a = 2; // ez a rész hajtódik végre cout << a << endl; return 0; } 22
Érték szerinti paraméterátadás #include using namespace std; void f(int a) { cout << "a = " << a << endl; a = 5; cout << "a = " << a << endl; } int main() { int x = 47; cout << "x = " << x << endl; f(x); cout << "x = " << x << endl; return 0; }
47 5
47 47 23
Mutatók #include using namespace std; void f(int *a) { cout << "a = " << *a << endl; *a = 5; cout << "a = " << *a << endl; } int main() { int x = 47; cout << "x = " << x << endl; f(&x); cout << "x = " << x << endl; return 0; }
47 5
47 5 24
Referenciák #include using namespace std; void f(int &a) { cout << "a = " << a << endl; 47 // itt közvetlenül a változóba írunk, nem a címére !!! a = 5; 5 cout << "a = " << a << endl; } int main() { int x = 47; cout << "x = " << x << endl; f(x); cout << "x = " << x << endl; return 0; }
47 5
Nehezebb megmondani, hogy változik-e a paraméter
25
C-ben írt függvények extern "C" void *xmalloc(unsigned size); Több deklaráció esetén: extern "C" { #include int *fvg(int a); }
26
C include file C++ -ban #ifdef __cplusplus extern "C" { #endif // a függvények és változók ide jönnek, // például: void *xmalloc(unsigned size); #ifdef __cplusplus } #endif 27
Többértelműség 2. int main() { int a; unsigned char b; cout << "Adj meg egy 0 es 255 kozotti szamot"; cin >> a; b = a; PrintBinary(b); cout << endl; return 0; }
28
Többértelműség 1. #include using namespace std; void PrintBinary(const unsigned char val) { for(int i = 7; i >= 0; i--) { if(val & (1 << i)) cout << "1"; else cout << "0"; } }
29
Függvények még egyszer • Emberi kommunikáció: egy szó több mindent jelenthet • Programban: egy tevékenység egy név – De mi van ha csak a típusa különböző – print_char, print_int, print_double
30
Function overloading • Az overloading általánosan azt jelenti, hogy az adatokon valamilyen operáció végrehajtását végző szimbólumhoz (például függvényazonosítóhoz, operátorhoz) több, különböző típusra vonatkozó különböző jelentést rendelünk. • Valamilyen adaton mely műveletet hajtjuk végre függ az adat szignatúrájától (típusától)
31
Function overloading #include <stdio.h> void show(int val) { printf("Integer: %d\n", val); } void show(double val) { printf("Double: %lf\n", val); } void show(char *val) { printf("String: %s\n", val); } int main() { show(12); show(3.1415); show("Hello World\n!"); } 32
Function overloading • A forrás kódban azonos a nevük a fordítás után nem • „Name mangling” – void show(int) – void show(char *)
@@showI @@showCP
• Különböző „mangling”-et használnak a fordítók
33
Function overloading • Ne használjuk, ha a két függvény teljesen mást csinál • A függvényeknél nem elég ha csak a visszatérési értékben különböznek (mivel azt nem kötelező figyelembe venni) show(“hello”);
• A függvény overloading néha meglephet bennünket. – Melyik függvényt hívjuk meg? show(0); Egész számként nyomtatja. 34
Alap argumentum • Még egy „kényelmi” lehetőség • Ha nem adunk meg értéket akkor a programozó által megadott értéket veszi fel egy függvény argumentuma
35
Alap argumentum #include <stdio.h> void showstring(char *str = "Hello World!\n"); int main() { showstring("Ez egy explicit argumentum.\n"); showstring();
// valójában ez: // showstring("Hello World!\n");
}
36
Alap argumentum void two_ints(int a = 1, int b = 4); int main() { two_ints(); two_ints(20); two_ints(20, 5);
// argumentumok: 1, 4 // argumentumok: 20, 4 // argumentumok: 20, 5
}
Több módon használhatjuk, de ez hibás two_ints(,6) 37