500 likes | 633 Views
Podstawy informatyki 2013/2014. Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka. Mechanizm obsługi sytuacji wyjątkowych. Mechanizm obsługi sytuacji wyjątkowych
E N D
Podstawy informatyki2013/2014 Łukasz SztangretKatedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiałyDanuty Szeligi i Pawła Jerzego Matuszyka
Mechanizm obsługi sytuacji wyjątkowych Mechanizm obsługi sytuacji wyjątkowych wykorzystuje się, gdy wiemy, że program nie będzie w stanie wykonać poprawnych obliczeń. W takiej sytuacji „rzucamy” wyjątek, czyli przerywamy obliczenia i „przeskakujemy” do procedury obsługi wyjątku.
Mechanizm obsługi sytuacji wyjątkowych • Określenie, gdzie zaczyna się obszar, w którym może wystąpić sytuacja wyjątkowa. try – spróbuj • Gdy zaistnieje sytuacja wyjątkowa rzucenie wyjątku. throw – rzuć • Określenie reakcji na wystąpienie sytuacji. catch – złap
try { //tu coś może się nie udać throw 1; //coś się nie udało } catch(int) { //reakcja na sytuację wyjątkową }
Co może być sytuacją wyjątkową? O tym decyduje programista. Sytuacją wyjątkową może być wszystko, co my wewnątrz programu za taką uznamy.
Kiedy stosować mechanizm obsługi sytuacji wyjątkowych? Gdy dwa odmienne fragmenty kodu muszą ze sobą współpracować: • jeden potrafi wykryć sytuację wyjątkową, ale nie potrafi nic na nią poradzić, • drugi wie, co zrobić, ale nie potrafi jej wykryć.
double suma(string nazwa) { ifstream plik(nazwa.c_str()); if (plik.good()) { int s=0, li; while (!plik.eof()) { plik>>li; s+=li; } return s; } else { //return ?? } }
double suma(string nazwa) { ifstream plik(nazwa.c_str()); if (!plik.good()) throw 1; int s=0, li; while (!plik.eof()) { plik>>li; s+=li; } return s; } intmain() { stringnazwa="dane.txt"; double s; for(;;) { try { s=suma(nazwa); break; } catch (int) { cout<<"Podajnazwepliku\n"; cin>>nazwa; } } cout<<s<<endl; return 0; }
throwvsreturn Mechanizm obsługi sytuacji wyjątkowych umożliwia powrót z funkcji inny niż za pomocą instrukcji return. Różnica w obiektach zwracanych: • argumentem return musi być obiekt określonego typu, • argumentem throwmoże być obiekt dowolnego typu. Różnica w przeniesieniu sterowania: • instrukcja return powoduje powrót do miejsca wywołania funkcji, • instrukcja throw powoduje przejście do procedury obsługi sytuacji wyjątkowej – odpowiedni blok catch.
Po zakończeniu procedury obsługi wyjątku nie następuje żaden powrót do miejsca skąd rzucono wyjątek. Po zakończeniu wykonywania bloku catch zaczyna się wykonywanie instrukcji znajdujących się po wszystkich blokach catch.
Kolejność bloków catch ma znaczenie (analogicznie jak w przypadku elseif). try { throw 1; } catch(int){cout<<"int"<<endl;} catch(double){cout<<"double"<<endl;} catch(char){cout<<"char"<<endl;}
Który blok catch wybiera kompilator? Pierwszy pasujący, czyli: rzucamy oczekujemy T -> T T -> const T T -> T & T* -> void* obiekt obiekt klasy -> klasy podstawowej pochodnej
void f(int a){cout<<"int\n";} void f(...){cout<<"...\n";} intmain() { f(1.0); return 0; } intmain() { try { throw 1.0; } catch(int){cout<<"int\n";} catch(...){cout<<"...\n";} return 0; } int …
try { throw 1; } catch(...){cout<<"int\n";} catch(int){cout<<"...\n";} BŁĄD
Zagnieżdżanie bloków try try { try { throw 1; } catch (long){cout<<"long\n";} catch (int){cout<<"int\n";} } catch(int){cout<<"int\n";} catch(double){cout<<"double\n";} int
try { try { throw 1; } catch (long){cout<<"long\n";} catch (char){cout<<"char\n";} catch (...){cout<<"...\n";} } catch(int){cout<<"int\n";} catch(double){cout<<"double\n";} …
Re-throw try { try { throw 1; } catch (long){cout<<"long\n";} catch (char){cout<<"char\n";} catch (...){cout<<"...\n";throw;} } catch(int){cout<<"int\n";} catch(double){cout<<"double\n";} … int
Można sprawdzać jaką wartość ma rzucony obiekt. try { throw 1; } catch(int a){cout<<"int = "<<a<<endl;} int = 1
W przypadku bloków try i catch obowiązują normalne zakresy ważności. try { int a=2; throw a; } catch(int) { cout<<"int = "<<a<<endl; } BŁĄD
Funkcja exit Deklaracja: voidexit(int status); Jest to funkcja, która kończy działanie programu, ale wcześniej zamyka wszystkie pliki oraz opróżnia wszystkie bufory.
Funkcja abort Deklaracja: void abort(); Jest to funkcja, która kończy działanie programu (brutalnie).
Funkcja terminate Deklaracja: voidterminate(); Jest to funkcja wywoływana przez kompilator w chwili, gdy żaden z bloków catch nie złapie wyjątku. Funkcja ta wywołuje funkcję abort.
Funkcja set_terminate Deklaracja: (void (*wsk)()) set_terminate(void (*wsk)()); Jest to funkcja, która mówi kompilatorowi, jaką funkcję ma wywołać z funkcji terminate.
void nie_zlapano() { cout<<"Niezlapanowyjatku\n"; exit(0); } intmain() { set_terminate(nie_zlapano); try { throw 1; } catch(double) {cout<<"double\n";} } Nie zlapanowyjatku
int main() { set_terminate(nie_zlapano); try { throw 1; } catch(int) { cout<<"int\n"; try { throw 1.0; } catch (int){cout<<"int\n";} } catch(double){cout<<"double\n";} catch(char){cout<<"char\n";} } int Nie zlapanowyjatku
Deklarując funkcję możemy podać jakie wyjątki funkcja może rzucać, np.: voidfun(); funkcja rzuca dowolny wyjątek void fun() throw (int, double); funkcja rzuca int albo double voidfun() throw(); funkjca nie rzuca żadnych wyjątków
Funkcja unexpected Deklaracja: voidunexpected(); Jest to funkcja wywoływana przez kompilator w chwili, gdy z wnętrza funkcji zostanie rzucony nieoczekiwany wyjątek. Funkcja ta wywołuje funkcję terminate.
Funkcja set_unexpected Deklaracja: (void (*wsk)()) set_unexpected(void (*wsk)()); Jest to funkcja, która mówi kompilatorowi, jaką funkcję ma wywołać gdy rzucony zostanie wyjątek niespodziewany.
void fun() throw(int) { throw 1.0; } void niespodziewany() { cout<<"Wystapilniespodziewanywyjatek"; exit(0); } int main() { set_unexpected(niespodziewany); try { fun(); } catch(int) { cout<<"int\n"; } return 0; }
goto for(;;){ for(;;){ for(;;){ for(;;){ for(;;){ goto koniec; } } } } } koniec:
throw try{ for(;;){ for(;;){ for(;;){ for(;;){ for(;;){ throw 1; } } } } } } catch (int){}
Wyjątki standardowe można znaleźć w Thinkingin C++ tom II Bruce Eckel Dostępne http://helion.pl/online/thinking/index.html
Zmienne: • deklaracja (extern), • definicja, • inicjalizacja, • nazwy zmiennych. • Stałe: • będące liczbami całkowitymi (hex, oct, dec) • będące liczbami zmiennoprzecinkowymi, • znakowe (znaki specjalne), • tablice znakowe – C-stringi.
Instrukcje sterujące: • blok instrukcji • if • if…else • switch (ograniczenia) • while • do…while • for • break • continue • goto (inne sposoby wyjścia z zagnieżdżonej pętli)
Typy: • fundamentalne • złożone [] () * & • wbudowane • definiowane przez użytkownika • typ void • Czas życia obiektu, zakres ważności, zasłanianie nazw. • Specyfikatory: • const • register • volatile • static
Typ wyliczeniowy enum, instrukcja typedef • Operatory: • arytmetyczne jedno- i dwuargumentowe, • przypisania, • logiczne, • bitowe, • wyrażenie warunkowe, • operator przecinek, • Priorytety i łączność operatorów.
Funkcje: • deklaracja, definicja, wywołanie, • zwracanie wartości, • argumenty formalne i aktualne, • przesyłanie argumentów przez wartość i przez referencję, • argumenty domniemane, • funkcja inline, • zmienne lokalne statyczne.
Preprocesor: • define • undef • makrodefinicja • kompilacja warunkowa • include • ifndef • nazwy predefiniowane: • __FILE__ • __LINE__ • __DATA__ • __TIME__
Tablice: • definicja, inicjalizacja, • odwołania do elementów tablicy, • stałe tablice, • tablice znakowe, • tablice wielowymiarowe, • przekazywanie tablic do funkcji.
Wskaźniki: • wskaźniki do pojedynczych obiektów i tablic, • wskaźnik jako argument funkcji, • wskaźnik do funkcji, • wskaźnik do funkcji jako argument innej funkcji, • arytmetyka wskaźników, • stałe wskaźniki, wskaźniki do stałych, stałe wskaźniki do stałych, • dynamiczne tworzenie tablic, usuwanie tablic, • wskaźnik do tablicy wielowymiarowej, • funkcja zwracająca tablicę (wskaźnik) jedno- i wielowymiarową.
Operatory rzutowania. • Argumenty z linii poleceń (argumenty funkcji main). • Przeładowanie nazw funkcji: • lista argumentów przy przeładowaniu, czyli kiedy dwie funkcje o tej samej nazwie mogą współistnieć w tym samym zakresie ważności (błędy w momencie definiowania funkcji oraz błędy w momencie wywołania funkcji), • wskaźnik do funkcji przeładowanej,
konwersje przy dopasowaniu argumentów aktualnych do argumentów formalnych • dopasowanie dokładne (z trywialną konwersją), • dopasowanie z awansem, • dopasowanie za pomocą konwersji standardowych, • dopasowanie za pomocą konwersji zdefiniowanych przez użytkownika, • dopasowanie do funkcji z wielokropkiem.
Szablony funkcji: • definiowanie, • parametr szablonu, argument funkcji, • funkcja specjalizowana, • obiekty lokalne, typy pochodne, obiekty lokalne statyczne, • funkcje inline, • Run-Time TypeIdentyfication.
Struktury: • definicja i rozmiar struktury, • obiekty strukturalne, wskaźniki do nich, inicjalizacji obiektów strukturalnych, • odwoływanie się do składników struktury, • pola bitowe, unie – zastosowanie do „konwersji” danych, • metody składowe struktury, • wskaźnik this • struktury zagnieżdżone i lokalne, • statyczny składnik struktury, • wskaźnik do niestatycznego składnika struktury, • modyfikator mutable.
Klasa biblioteczna std::string: • definiowanie stringu, • dodawanie, • długość, pojemność, • rezerwacja pamięci, zmiana rozmiaru, • odwoływanie się do poszczególnych znaków w stringu oraz do fragmentów stringu, • wyszukiwanie, • usuwanie, wstawianie, zastępowanie, zamiana, • porównywanie, • getline, • iteratorystringu.
Operacje we/wy: • operacje we/wy bitowe i tekstowe, • posługiwanie się strumieniami, • przeładowane operatory przesunięcia bitowego, • domniemania, • flagi i maski, • zmiany formatowania: • funkcje zmieniające flagi, • funkcje nie zmieniające flag, ale towarzyszące im parametry, • manipulatory, • nieformatowane operacje we/wy: • funkcje wyjmujące ze strumienia, • funkcje wstawiające do strumienia, • funkcje dodatkowe, • Strumienie płynące do i z plików: • flagi stanu błędu strumienia, • wybór miejsca czytania i pisania, • Strumienie płynące do i z obiektów klasy string
Mechanizm obsługi sytuacji wyjątkowych: • bloki try i catch, instrukcja throw, • throwvs return, • blok try i innym bloku try, • blok try w bloku catch, • powtórne rzucenie tego samego wyjątku, • wartość rzuconego obiektu, • funkcje exit, abort, • funkcje terminete, set_terminate, • funkcje unexpected, set_unexpected.
Zapis liczb w komputerze: • jednostki informacji, • systemy addytywne i pozycyjne, • reprezentacja liczb całkowitych: • liczby nieujemne, • kod znak-moduł, • kod U1, • kod U2, • kod z nadmiarem, • dodawanie liczb całkowitych, • liczby stałoprzecinkowe, • liczby zmiennoprzecinkowe (standard IEEE 754), • przeliczanie pomiędzy systemami (2, 8, 10, 16), • błędy zaokrągleń.
Prezentacja udostępniona na licencji CreativeCommons: Uznanie autorstwa, Na tych samych warunkach 3.0. Pewne prawa zastrzeżone na rzecz autorów. Zezwala się na dowolne wykorzystywanie treści pod warunkiem wskazania autorów jako właścicieli praw do prezentacji oraz zachowania niniejszej informacji licencyjnej tak długo, jak tylko na utwory zależne będzie udzielana taka sama licencja. Tekst licencji dostępny jest na stronie: http://creativecommons.org/licenses/by-sa/3.0/deed.pl