Pénzügyi algoritmusok A C++ programozás alapjai Tömbök (3. rész) Konstansok Kivételkezelés
Tömbök 3. Többdimenziós tömbök
Többdimenziós tömbök int a;
Többdimenziós tömbök int a[5];
Többdimenziós tömbök int a[5][4];
Többdimenziós tömbök int a[5][4][3];
Többdimenziós tömbök int a[5][4][3]; 41. 42. 43. 44. 45. 21. 22. 23. 24. 25. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Folytonos memóriaterületen tárolva!
Inicializálás int a[5][4] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 } };
Címzés a[2][3]; int a[4][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
Alternatívák A tömbök kényelmes és biztonságos C++ alternatíváját lásd később Tömbök tömbje helyett pointerek tömbje A pointerek tömbökre mutatnak Előny: Dinamikusan (heap-en) is létrehozható Elméletileg különböző méretű sorok is lehetnek (jagged array) Hátrány: Nem folytonos memóriaterületen tárolt Felszabadítás és inicializálás bonyolultabb Kilapított, egydimenziós tömb Méret: a[x][y] helyett a[x*y] Címzés: a[i][j] helyett a[i + j*x] Bővebben a különböző tömbökről és függvényekben történő használatukról: http://stackoverflow.com/questions/8767166/passing-a-2d-array-to-a-c-function
Pointerek tömbje inicializálás int a1[5] = { 1, 2, 3, 4, 5 }; int a2[5] = { 6, 7, 8, 9, 10 }; int a3[5] = { 11, 12, 13, 14, 15 }; int a4[5] = { 16, 17, 18, 19, 20 }; int *a[4] = { a1, a2, a3, a4 };
Pointerek tömbje vs. pointer tömbre int *a[4]; int (*a)[4];
Pointerek tömbje vs. pointer tömbre int *a[4]; int (*a)[4]; int **a[4]; int *(*a)[4];? int (*a[3])[4]; int *(*a[3])[4]; C++ deklarációk értelmezéséhez: http://cdecl.org/
Kitekintés: typedef Bármilyen típusnak adható alternatív név Jobban látszik a jelentés A tényleges típus egy helyen definiált typedef double currency; currency income = 200000.0; Összetett típusokat egyszerűsíti typedef int coordinate[3]; typedef coordinate * line[2]; coordinate c1 = { 1, 2, 3 }; coordinate c2 = { 2, 3, 4 }; line l = { &c1, &c2 }; int (*(*a)[2])[3] = &l;
Konstansok Változók, tagváltozók, paraméterek, függvények
Konstans módosító Konstans módosító (constant modifier): Szinte bármilyen deklarációhoz társítható Ökölszabály: arra vonatkozik, ami után a const kulcsszó következik (Tag)változóknál: inicializálás után nem módosítható Paramétereknél: függvényen belül nem módosítható Metódusoknál: a függvény nem módosítja a tagváltozókat Pointereknél összetett szabályok
Konstansok const int a = 5; int const b = 10; void Person::print(const bool full) const { this->name = ""; // HIBA! }
Konstansok const int a = 5; int const b = 10; void Person::print(const bool full) const { this->name = ""; // HIBA! } const int *a[4]; int const *a[4]; const int (*a)[4];? int * const a[4]; int const * const a[4]; int (* const a)[4]; int const * const * const a[4]; C++ deklarációk értelmezéséhez: http://cdecl.org/
Kivételkezelés Hibakezelés C++ módra
Hibajelzési stratégiák Speciális visszatérési érték Könnyen ellenőrizhető Nem mindig lehetséges Globális változó beállítása Könnyen implementálható Globális A hiba könnyen láthatatlan maradhat Tagváltozó beállítása Könnyen implementálható A hiba könnyen láthatatlan maradhat Adjunk vissza -1 értéket! Unsigned int visszatérési típussal?
Hibajelzési stratégiák Speciális visszatérési érték Könnyen ellenőrizhető Nem mindig lehetséges Adjunk vissza -1 értéket! Unsigned int visszatérési típussal? Globális változó beállítása Könnyen implementálható Globális A hiba könnyen láthatatlan maradhat Tagváltozó beállítása Közös problémák: Könnyen Nem implementálható kényszeríthető ki a hibakezelés A hiba Nehezen könnyen láthatatlan delegálható maradhat a hibakezelés
Kivételkezelés Kivétel (exception): A program futása során észlelt kivételes helyzet (hiba) Pl. érvénytelen bemenet, művelet, adathiba, stb. Kivétel keletkezése esetén hibakezelő kód futtatása try { A try blokkban keletkezett kivételeket kezeljük throw 20; } catch (int e) { cout << "Exception Nr. " << e << endl; }
Kivételkezelés Kivétel (exception): A program futása során észlelt kivételes helyzet (hiba) Pl. érvénytelen bemenet, művelet, adathiba, stb. Kivétel keletkezése esetén hibakezelő kód futtatása try { Hiba esetén a catch blokk fut le. Ha nem történik hiba, a catch blokk nem fut le. throw 20; } catch (int e) { cout << "Exception Nr. " << e << endl; }
Kivételkezelés Kivétel (exception): A program futása során észlelt kivételes helyzet (hiba) Pl. érvénytelen bemenet, művelet, adathiba, stb. Kivétel keletkezése esetén hibakezelő kód futtatása try { throw 20; } catch (int e) { } Hiba jelzése a throw utasítással lehetséges. A hibához egy érték is kapcsolható. cout << "Exception Nr. " << e << endl;
Kivételkezelés Kivétel (exception): A program futása során észlelt kivételes helyzet (hiba) Pl. érvénytelen bemenet, művelet, adathiba, stb. Kivétel keletkezése esetén hibakezelő kód futtatása try { A kapcsolt érték típusának megfelelő catch blokk fut le. Az érték a kezelőben használható. throw 20; } catch (int e) { cout << "Exception Nr. " << e << endl; }
A kivételek működése 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } int hs? 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int n 1 - PC 13 int ret? int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int n 1 - PC 13 int ret? int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int 1 int n 1 - PC 13 int ret? int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése int 1 int n 1 - PC 13 int ret? int n 2 - PC 5 int ret? int hs? 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
A kivételek működése 1. int main() 2. { 3. try 4. { 5. int hs = CalcRec(2); 6. } 7. catch(int ec){...} 8. } int ec 1 9. int CalcRec(int n) 10. { 11. if (n == 1) 12. throw 1; 13. return CalcRec(n - 1); 14. }
Különböző típusú hibák kezelése Egy try blokk után több catch blokk is lehet Választás: A throw utasításnak átadott érték típusa szerint Fentről lefelé try { // code here } catch (int param) { cout << "int exception"; } catch (char param) { cout << "char exception"; } catch (...) { cout << "default exception"; }
Különböző típusú hibák kezelése Egy try blokk után több catch blokk is lehet Választás: A throw utasításnak átadott érték típusa szerint Fentről lefelé try { // code here } catch (int param) { cout << "int exception"; } Bármilyen típust elfogad catch (char param) { cout << "char exception"; } catch (...) {(de cout nem << lehet "default hivatkozni exception"; az értékre) }
Kivételek továbbítása A kezeletlen kivételek tovább terjednek a stacken Ez kézzel is megtehető egy catch blokkban try { try { // code here } catch (int n) { throw; } } catch (...) { cout << "Exception occurred"; }
A standard kivételek A standard könyvtár definiál egy kivétel típust std::exception az <exception> könyvtárban Testreszabható, több fajtája is van (<stdexcept>) try { throw exception(); } catch (exception& e) { cout << e.what() << endl; } Referencia szerint fogadható A hiba leírása kiolvasható
Gyakori kivételfajták bad_alloc: a new parancs dobja, ha nincs elég memória logic_error: a program belső logikájához kapcsolódó hibák Indexelés (out_of_range) Hibás paraméter (invalud_argument) runtime_error: futásidőben észlelt hibák Túlcsordulás (overflow_error) http://www.cplusplus.com/doc/tutorial/exceptions/
Gyakori kivételfajták bad_alloc: a new parancs dobja, ha nincs elég memória logic_error: a program belső logikájához kapcsolódó hibák try { throw logic_error( Whoopsie!"); } catch (exception& e) { cout << e.what() << endl; }
Köszönöm a figyelmet!