JPzPO wykład 5
Transkrypt
JPzPO wykład 5
www.imio.polsl.pl JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 5 1 www.imio.polsl.pl SPECYFIKATOR const Specyfikator (przydomek) const: Umieszczenie przed nazwą zmiennej specyfikatora const w jej definicji informuje kompilator, że zawartość tej zmiennej nie może być modyfikowana. Zmienna taka (traktowana odtąd jako obiekt stały) musi być zainicjalizowana w momencie definicji. Inicjalizacja – nadanie obiektowi (np. zmiennej) wartości w momencie jego tworzenia. Przypisanie – podstawienie do obiektu wartości w dowolnym innym momencie. #include <iostream> using namespace std; int main() { //const int MojaStala; //Błąd! Brak inicjalizacji const float MojaStala=5.123; cout<<MojaStala; //MojaStala=6.456; //Błąd! Tego obiektu nie można zmieniać const int ROZMIAR=10; //pisanie obiektów stałych wielkimi literami int tablica[ROZMIAR]; //może zwiększać czytelność programu // (o tablicach później...) return 0; } 2 TABLICE STATYCZNE www.imio.polsl.pl Tablica jest to ciąg obiektów tego samego typu, które zajmują ciągły obszar w pamięci, np.: int t[5]; // statyczna tablica 5 obiektów typu całkowitego Numeracja elementów tablicy zaczyna się od zera!!! Np. piąty element tablicy ma indeks 4… Zatem mamy elementy: t[0], t[1], t[2], t[3], t[4] Wpisanie czegoś do elementu tablicy, który nie istnieje, np. t[5] nie jest sygnalizowane jako błąd! Może to powodować nadpisanie innych zmiennych! Rozmiar tak zdefiniowanej tablicy (tablica statyczna) musi być znany w momencie kompilacji. O tablicach dynamicznych – w późniejszym czasie.... 3 TABLICE STATYCZNE www.imio.polsl.pl Tablice można tworzyć z: o typów fundamentalnych (z wyjątkiem void); o typów wyliczeniowych (enum); o innych tablic (tablice dwu- i wielowymiarowe); o wskaźników; a także: o obiektów typów zdefiniowanych przez użytkownika (obiektów klas); o wskaźników do pokazywania na składniki klasy. Zwykle korzysta się z pętli: int T[10]; //definiujemy tablicę for(int i=0; i<10; ++i) T[i]=i+3; //zauważ: i<10, czyli i=0..9 //wypełniamy tablicę wartościami for(int i=0; i<=9; ++i) //też prawidłowo, //ale mniej wygodnie... 4 TABLICE STATYCZNE www.imio.polsl.pl Przykłady definicji tablic: int tablica1[20]; //tablica 20 liczb typu int int tablica2[3][4]; //tablica 12 liczb typu int int tablica3[2][3][4]; //tablica 24 liczb typu int char zdanie[80]; //tablica 80 znaków typu char float numery[20]; //tablica 20 liczb typu float double liczby[5]; //tablica 5 liczb typu double int *tabl_wsk[12]; //tablica 12 wskaźników do int Samochod tabl_ob[6]; //tablica 6 obiektów klasy Samochod o Indeks elementu tablicy musi być liczbą całkowitą lub wyrażeniem całkowitym. o Elementy tablic wielowymiarowych umieszczane są kolejno w pamięci komputera tak, że najszybciej zmienia się najbardziej skrajny prawy indeks. 5 TABLICE STATYCZNE www.imio.polsl.pl Przykład – tablica jednowymiarowa: #include <iostream> using namespace std; int main() { const int ROZMIAR=10; //stała okreslająca rozmiar - zwiększa czytelność int T[ROZMIAR]; for(int i=0; i<ROZMIAR; ++i) //"i" jest znane tylko wewnątrz pętli for... { T[i]=2*(i+1); cout<<T[i]<<" "; } // cout<<endl <<i; //błąd kompilacji (patrz: poprzedni komentarz... return 0; } 6 TABLICE STATYCZNE www.imio.polsl.pl Przykład – tablica dwuwymiarowa : #include <iostream> using namespace std; int main() { const int W=2, K=3; //liczba Wierszy i Kolumn int Tabl[W][K]; cout<<"Podawaj po kolei elementy tablicy: \n"; for(int i=0; i<W; ++i) //wpisywanie do tablicy 2-wymiarowej for(int j=0; j<K; ++j) { cout<<"Podaj element ["<<i<<"]["<<j<<"]: "; cin>>Tabl[i][j]; } cout<<endl<<"Tablica zawiera elementy:\n"; //wypisywanie na ekran for(int i=0; i<W; ++i) { for(int j=0; j<K; ++j) cout<<Tabl[i][j]<<"\t"; // wypisanie i wstawienie tabulatora cout<<endl; //wstawienie znaku nowej linii na końcu wiersza } return 0; } 7 www.imio.polsl.pl TABLICE STATYCZNE Nadawanie wartości elementom tablic: o w pętli (jak w przykładach): #include <iostream> using namespace std; int main() { int Tablica[5]; for(int i=0; i<5; ++i) { Tablica[i]=5*i; cout<<Tablica[i]<<" } return 0; "; } o przypisanie każdego elementu z osobna, np.: int tab[3]; //tablica 3 liczb typu int tab[0]=1; tab[1]=4; tab[2]=-3 //jawne przypisanie 8 www.imio.polsl.pl TABLICE STATYCZNE Nadawanie wartości elementom tablic: o inicjalizacja (zatem w momencie definicji tablicy), np.: int T1[5]={0}; //wszystkie elementy zerowe int T2[5][3]={0}; int T3[6]={1}; //wszystkie elementy zerowe //pierwszy element równy 1, pozostałe zerowe int T4[5]={2,5,6}; //elementy 4 i 5 zerowe (o indeksach 3 i 4) int T5[4]={1,2,3,4}; //jawna inicjalizacja elementów int T6[2][2]={{1,2},{3,4}}; int T7[2][2]={{1},{3,4}}; int T8[2][2]={1,2,3,4}; int T9[ ]={1,2,3}; //jawna inicjalizacja elementów //element T7[0][1] zerowy //jawna inicjalizacja elementów //liczba elementów tablicy równa 3 int T10[3]={5,7,2,3}; //błąd składni, za dużo elementów! 9 TABLICE STATYCZNE www.imio.polsl.pl Nadawanie wartości elementom tablic: Brak zainicjalizowania elementów tablicy, która tego wymaga (np. zdefiniowanej w zakresie lokalnym) może powodować błąd logiczny (błąd wykonania), np.: #include <iostream> using namespace std; int main() { const int ROZ=3; int tab[ROZ]; // definicja tablicy bez jej inicjalizacji // zapominamy o nadaniu wartości elementom... for (int i=0; i<ROZ; ++i) { tab[i]+=i; //dodajemy coś do każdego elementu tablicy cout<<tab[i]<<" "; //i dostajemy niezamierzony rezultat... } return 0; } 10 www.imio.polsl.pl TABLICE STATYCZNE Tablice znakowe: - to specjalne tablice, w których przechowywane są znaki (np. litery). Stringi (napisy) to ciągi znaków zakończone znakiem NULL (znak o kodzie 0) – tego oczekują wszelkie funkcje biblioteczne operujące „na stringach”... char tekst1[30]; //tablica znakowa char char tekst2[30]={”wyraz”}; //znak NULL automatycznie dopisany char tekst3[ ]={”wyraz”}; //string poprawnie zakończony, jest NULL char tekst4[30]={’w’,’y’,’r’,’a’,’z’}; //reszta inicjalizowana //zerami, zatem jest znak NULL. char tekst5[]={’w’,’y’,’r’,’a’,’z’}; //nie ma znaku NULL! //nie jest to błąd, jeśli elementy tablicy nie mają być //traktowane jako string lecz osobne litery Niezapewnienie wystarczająco dużego rozmiaru tablicy znakowej do przechowania napisu może powodować utratę danych i poważne błędy wykonania! 11 www.imio.polsl.pl FUNKCJE Funkcja: podprogram realizujący jakieś zadanie, który najczęściej jako rezultat zwraca jakąś wartość, np.: double pole_kwadratu(double a) //funkcja przyjmuje jako argument { //dlugosc boku (typu double) return a*a; //i zwraca wartosc typu double } Funkcję wywołuje się poprzez podanie jej nazwy i umieszczonych w nawiasie argumentów, np.: cout<<pole_kwadratu(3.5); o Każda funkcja przed użyciem musi być zadeklarowana. o Nie można definiować funkcji wewnątrz innej funkcji (również main). o Funkcja może wywoływać inną funkcję. double pole_kwadratu(double a); //sama deklaracja funkcji //(zauważ średnik na końcu) 12 FUNKCJE www.imio.polsl.pl Przykład: #include <iostream> #include <cmath> using namespace std; //------------------------------------------------------------------------double biegunowy(double d); // (tylko) deklaracja funkcji „biegunowy” // double biegunowy(double) //tak naprawdę tu wystarczy sam typ argumentu… //------------------------------------------------------------------------int main() //funkcja główna { double srednica=10.2; cout << biegunowy(srednica) << endl; return 0; } //------------------------------------------------------------------------double biegunowy(double d) //a tu definicja funkcji „biegunowy” { double wynik=M_PI*pow(d,4)/32; return wynik; } Argumenty (parametry) formalne – argumenty występujące w definicji funkcji (tu: d). Argumenty (parametry) aktualne – argumenty użyte w wywołaniu funkcji (tu: srednica). 13 www.imio.polsl.pl FUNKCJE Przykład: #include <iostream> #include <cmath> using namespace std; //------------------------------------------------------------------------double biegunowy(double d) //Albo tak: { //deklaracja i definicja funkcji „biegunowy” double wynik=M_PI*pow(d,4)/32; return wynik; } //------------------------------------------------------------------------int main() //funkcja główna { double srednica=10.2; cout << biegunowy(srednica) << endl; return 0; } Definicja funkcji jest deklaracją, w której przedstawiona jest treść tej funkcji Wywołanie funkcji zwracającej rezultat samo w sobie ma wartość, jaką ma rezultat zwracany przez tą funkcję, można je więc użyć w dowolnym wyrażeniu, np.: y=3.27+m+dodaj(2,3)+dodaj(n,5); 14 www.imio.polsl.pl FUNKCJE Przykłady deklaracji funkcji: Deklaracja funkcji double dodaj(double a, double b); Opis funkcja wywoływana z 2 argumentami typu double i zwracająca wartość typu double double dodaj(double, double); void wypisz(string napis); int fun11(void); int fun11(); j.w. funkcja wywoływana z 1 argumentem typu string i nie zwracająca żadnej wartości funkcja wywoływana bez argumentów i zwracająca wartość typu całkowitego j.w. (inaczej, niż w C…) Jeśli funkcja nie zwraca żadnej wartości, to po słowie kluczowym return nie może stać żadna wartość (można też to słowo pominąć): void komunikat(int ile) { cout<<"Nalezy "<<ile<<" razy nacisnac Enter"; } 15 FUNKCJE www.imio.polsl.pl Funkcja main Specyficzne cechy: • musi wystąpić w każdym programie; • nie jest deklarowana; • nie można jej wywołać z innej funkcji; • tylko w niej można opuścić instrukcję return (kompilator sam doda return 0;) • rezultatem działania może być wyłącznie liczba całkowita; • tradycyjnie zwrócenie zera oznacza poprawne zakończenia działania (informacja dla systemu operacyjnego). 16 FUNKCJE www.imio.polsl.pl Funkcje inline Krótkie funkcje można definiować jako inline („w linii”). o Sugestia (która może być zignorowana) dla kompilatora, by w miejscu wywołania wstawić treść tej funkcji. o Skutek – skrócenie czasu wykonania. o Definicja (nie tylko deklaracja) – przed pierwszym wywołaniem tej funkcji (zwykle na początku programu lub w pliku nagłówkowym). 17 FUNKCJE www.imio.polsl.pl Przykład: #include <iostream> using namespace std; //------------------------------------------------------------------------inline void wypisz() //definicja funkcji inline { cout<<"______________________________________"<<endl; } //------------------------------------------------------------------------bool sprawdz(double a,double b) //”zwykła” funkcja { wypisz(); //tu funkcja wywołuje inną funkcję… if ((a*b)>0) return 1; else return 0; // zauważ przy okazji: return może występować więcej niż 1 raz } //------------------------------------------------------------------------int main() // funkcja główna { double x,y; cout<<"Podaj 2 liczby rozne od zera a powiem Ci, czy maja ten sam znak"; cout<<"\nLiczba 1: "; cin>>x; cout<<"\nLiczba 2: "; cin>>y; if (sprawdz(x,y)) cout<<"\nMaja ten sam znak"<<endl;//jesli wartość f. różna od 0 else cout<<"\nMaja rozne znaki"<<endl; //a jeśli równa zero... wypisz(); //wywołujemy funkcję wypisz() wewnątrz funkcji głównej return 0; } 18 FUNKCJE www.imio.polsl.pl Argumenty domyślne funkcji Programista może określić, że dany argument funkcji jest argumentem domyślnym i przypisać mu wartość domyślną. o Argumenty domyślne muszą być położone najdalej z prawej strony na liście argumentów funkcji. o Argumenty domyślne muszą być określone wraz z pierwszym wystąpieniem nazwy funkcji – zazwyczaj w jej deklaracji (w późniejszej definicji już nie!). 19 FUNKCJE www.imio.polsl.pl Przykład: #include <iostream> using namespace std; //------------------------------------------------------------------------float odleglosc(int mm, int m=0, int km=0); // domyślne na końcu listy //------------------------------------------------------------------------int main() { cout.precision(10); cout<<odleglosc(10)<<" [mm]"<<endl; // wynik: 10 cout<<odleglosc(21,1)<<" [mm]"<<endl; // wynik: 1021 cout<<odleglosc(37,56,2)<<" [mm]"<<endl; // wynik: 2056037 //cout<<odleglosc()<<" [mm]"<<endl; //Błąd - pierwszy argument // nie jest domyślny! return 0; } //------------------------------------------------------------------------float odleglosc(int mm, int m, int km) //funkcja wylicza odleglosc w [mm] { return mm+1000*m+1000*1000*km; } 20 FUNKCJE www.imio.polsl.pl Przekazywanie danych do funkcji przez wartość Przekazywanie argumentów do funkcji przez wartość powoduje, że funkcja pracuje na kopii przekazywanej zmiennej, więc nie ma możliwości jej modyfikowania. #include <iostream> using namespace std; //------------------------------------------------------------------------int funkcja(int x) { x=x*60; //albo: x*=60; return x; } //------------------------------------------------------------------------int main() { int a=4, b; cout<<"a="<<a<<", b="<<b<<endl; // a=4, b=? //brak inicjalizacji zmiennej! b=funkcja(a); cout<<"a="<<a<<", b="<<b<<endl; // a=4, b=240 //a nadal równe 4… return 0; } O innych sposobach przekazywania danych do funkcji (przez referencję i przez wskaźniki) – na innym wykładzie… 21 FUNKCJE www.imio.polsl.pl Przeładowanie (przeciążanie) nazwy funkcji: o Sytuacja, gdy w tym samym zakresie ważności jest więcej niż jedna funkcja o takiej samej nazwie. o Funkcje te muszą się różnić typem i/lub liczbą argumentów wywołania. o Zatem mogą współistnieć w danym zakresie ważności np. funkcje: float oblicz(float x); int oblicz(int x); float oblicz(int x, float y); int oblicz(int x, int y); int oblicz(int zmienna); //Błąd! Już jest taka funkcja! 22 FUNKCJE Przykład: www.imio.polsl.pl #include <iostream> using namespace std; //------------------------------------------------------------------void sprawdz(int x) // pierwsza funkcja sprawdz() { if (!x) cout<<"Sprawdzana liczba to zero\n"; else cout<<"Sprawdzana liczba to nie jest zero\n"; } //------------------------------------------------------------------void sprawdz(float x, float y) // druga funkcja sprawdz() { if (x>y) cout<<"Pierwsza liczba jest wieksza niz druga\n"; else cout<<"Pierwsza liczba nie jest wieksza niz druga\n"; } //------------------------------------------------------------------bool sprawdz(char aa) // trzecia funkcja sprawdz() { if (aa=='x') { cout<<"To jest 'x'"<<endl; return 1; } else { cout<<"To nie jest 'x'"<<endl; return 0; } } //------------------------------------------------------------------int main() // funkcja główna { int calkowita=5; float a=5.1, b=4.2; char znak='y'; sprawdz(calkowita); sprawdz(a,b); sprawdz(znak); return 0; } 23 WYRAŻENIE WARUNKOWE www.imio.polsl.pl Wyrażenie warunkowe ma postać: warunek ? wartość1 : wartość2 np.: (wiek>=18)?1:0; Jeśli warunek jest spełniony to wartość wyrażenia wynosi wartość1. W przeciwnym przypadku wartość wyrażenia wynosi wartość2 . Wyrażenie warunkowe może być składnikiem innych wyrażeń: cout<<"Ten produkt "; (wiek>=18)?cout<<"moze ":cout<<"nie moze "; cout<<"byc Ci sprzedany"<<endl; 24 WYRAŻENIE WARUNKOWE www.imio.polsl.pl #include <iostream> using namespace std; int main() { float a; cout<<"\n Podaj dowolna liczbe a powiem Ci, czy jest wieksza niz 5.1"<<endl<<" "; cin>>a; cout<<" Podana przez Ciebie liczba "; (a>5.1)?cout<<"jest ":cout<<"nie jest "; //wyr. warunkowe cout<<"wieksza niz 5.1"<<endl; return 0; } 25