www.imi.plsl.pl JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 8 1
TABLICE DYNAMICZNE Duż ciekawsze jest: Twrzenie dynamicznych tablic peratrem new[]: peratr new[] jest drębnym peratrem; d pary: delete[]; rzmiar takich tablic nie musi być znany w mmencie kmpilacji! www.imi.plsl.pl Dynamiczne tablice jednwymiarwe: Np.: stwrzenie dynamicznej tablicy: alb: duble *w_t; w_t=new duble[100]; duble *w_t=new duble[100]; i jej usunięcie: delete[] w_t; 2
TABLICE DYNAMICZNE www.imi.plsl.pl Nie da się elementm tak twrznej tablicy nadać wartści pczątkwych (nie jest mżliwa inicjalizacja, jak w przypadku tablic statycznych). Należy zadbać wypełnienie tablicy senswnymi wartściami P zwlnieniu pamięci peratrem delete[] wart ustawić wskaźnik na 0. np.: delete[] w_t; w_t=0; //lub: w_t=null 3
TABLICE DYNAMICZNE Przykład: www.imi.plsl.pl 4
TABLICE DYNAMICZNE Dynamiczne tablice n-wymiarwe: www.imi.plsl.pl Dla przypmnienia: W C++ tablica wielwymiarwa t tablica składająca się z innych tablic świadczy tym zapis, np.: tablica[5][3] Dynamiczna tablica n-wymiarwa składa się ze wskaźników d tablic (n-1)-wymiarwych. Niezbędna jest knstrukcja prgramistyczna w pstaci wskaźnik na wskaźnik, np.: int **Tablica2D; duble ***Tablica3D; Alkacja pamięci dbywa się n-etapw (przykład na następnym slajdzie ) 5
TABLICE DYNAMICZNE www.imi.plsl.pl Przykład: 6
TABLICE DYNAMICZNE www.imi.plsl.pl Dynamiczne jednwymiarwe tablice (n-wymiarwych) tablic statycznych. Czasami takie pdejście jest wystarczające. Tylk wymiar znajdujący się najbardziej z lewej strny mże być kreślny w spsób dynamiczny pzstałe muszą być znane w mmencie kmpilacji, np.: int (*t)[w][3] Uwaga na nawiasy! Zapisy: 1. new int(*t)[w][3] raz: 2. new int *t[w][3] nie są równważne! Prirytet peratrów [] jest wyższy, niż peratra *. 1. t jest wskaźnikiem pkazującym na tablicę elementów typu int (tak chcemy) 2. t jest tablicą wskaźników d biektów typu int (a nie t nam chdził ) 7
TABLICE DYNAMICZNE Przykład: www.imi.plsl.pl 8
DYNAMICZNY PRZYDZIAŁ PAMIĘCI www.imi.plsl.pl Jak sprawdzić, czy alkacja pamięci się pwidła: 1. Obecnie: peratr new generuje tzw. wyjątek (następuje rzucenie wyjątkiem ). Wyjątek należy złapać i cś z nim zrbić. Obsługa: try spróbuj, czy się uda, a jeśli nie t: catch(std::bad_allc) złap wyjątek w pstaci niepwdzenie alkacji : try { wsk=new int[205000000]; //... // jeśli się udał, t używamy stwrzneg biektu... } catch(std::bad_allc) // a jeżeli nie: {cut<<"nie udal się stwrzyc tablicy!\n"; //... // inne działania... } // dalsza część prgramu, wspólna dla bu wariantów... 9
DYNAMICZNY PRZYDZIAŁ PAMIĘCI Przykład: www.imi.plsl.pl 10
DYNAMICZNY PRZYDZIAŁ PAMIĘCI Jak sprawdzić, czy alkacja pamięci się pwidła: www.imi.plsl.pl 2. Dawniej: w przypadku niepwdzenia peratr new zwracał wartść 0. W dalszym ciągu jest mżliwść trzymywania infrmacji w ten spsób, jednakże nie jest t spsób dmyślny. Należy użyć std::nthrw w nawiasie zaraz za new: int *wsk; wsk=new(std::nthrw) int[205000000]; if(!a) // jeśli się nie udał {cut<<"nie udal się stwrzyc tablicy!\n"; //... // inne działania... } else { //... // jeśli się udał, t używamy stwrzny biekt... } // dalsza część prgramu, wspólna dla bu wariantów... 11
DYNAMICZNY PRZYDZIAŁ PAMIĘCI Jak sprawdzić, czy alkacja pamięci się pwidła: www.imi.plsl.pl 3. Inna mżliwść (rzadziej stswana): wywłanie stwrznej przez nas funkcji. 12
PREPROCESOR Preprcesr: jest t specjalny mechanizm języka, który przetwarza tekst prgramu przed jeg kmpilacją. www.imi.plsl.pl O tym, c ma n zrbić decydują tzw. dyrektywy preprcesra, np. znane Ci: #include <istream> t dyrektywa preprcesra włączająca plik nagłówkwy bibliteki istream d prgramu Czyli dyrektywy t żądania wyknania przez preprcesr jakiejś akcji... Każda dyrektywa rzpczyna się znakiem # (hash), przed którym mgą się znajdwać wyłącznie białe znaki; Dyrektywy preprcesra kńczą się przejściem d następneg wiersza. Nie należy kńczyć dyrektyw preprcesra średnikiem (nie są t instrukcje języka) mże (ale nie musi) pwdwać t błędy. Wybrane dyrektywy na następnych slajdach. 13
PREPROCESOR - dyrektywy Dyrektywa #define www.imi.plsl.pl Pstać: #define wyraz ciąg znaków zastępujących Pwduje, że w kmpilwanym pliku każde wystąpienie słwa wyraz będzie zastąpine przez t, c następuje p tym słwie. Preprcesr nie dknuje zastępwania nazw makr wewnątrz napisów. W słwie wyraz mgą występwać wyłącznie znaki dzwlne przez C++ (litery, cyfry, pdkreślenia) nie mgą występwać białe znaki. Treść (ciąg znaków zastępujących) mże zawierać białe znaki. prsty przykład: #define LICZBA 17 (każde wystąpienie w tekście prgramu wyrazu LICZBA skutkuje zamianą teg wyrazu na 17). W języku C dyrektywy #define używał się d definiwania stałych. W C++ lepiej użyć cnst jest t zrzumiałe dla kmpilatra i daje mniejsze szanse na pmyłki. 14
PREPROCESOR - dyrektywy Dyrektywa #define twrzenie makrdefinicji www.imi.plsl.pl Ciekawszy przykład: #define szlaczek {fr(int i=0; i<20; i++) cut<<"-*-";cut<<endl;} Każde wystąpienie w tekście prgramu wyrazu szlaczek skutkuje zamianą... Uwaga! Treść makr pwinna być w nawiasach ich brak mże spwdwać trzymanie nie teg, czeg się spdziewaliśmy, np.: 15
PREPROCESOR - dyrektywy Dyrektywa #define twrzenie makrdefinicji www.imi.plsl.pl Przykład z parametrem: #define pmnz(a,b) ((a)*(b)) Każde wystąpienie w tekście prgramu wyrazu pmnz(a,b)skutkuje zamianą na ((a)*(b)) Jeśli parametr jest pprzedzny znakiem # t wynikiem jest string któreg zawartść jest tym, c jest aktualnie parametrem, np.: 16
PREPROCESOR - dyrektywy Dyrektywa #undef kaswanie makrdefinicji www.imi.plsl.pl Pstać: #undef wyraz Użycie pwduje, że d teg mmentu zastępwanie, spwdwane wcześniejszym użyciem dyrektywy #define wyraz..., nie będzie miał miejsca. Typwe użycie: gdy włączamy plik z #define d inneg pliku dyrektywą #include i nie chcemy, by wyraz znany w ramach pierwszeg pliku był znany również w drugim. 17
PREPROCESOR - dyrektywy Dyrektywa #if kmpilacja warunkwa www.imi.plsl.pl Pstaci: a) b) c) #if warunek #if warunek #if warunek1 instrukcje instrukcje 1 instrukcje 1 #endif #else #elif warunek2 #endif instrukcje 2 instrukcje 2 #else instrukcje 3 #endif W zależnści d spełnienia warunku pewne linie są kmpilwane bądź nie. Np. na etapie testwania prgramu chcemy, by wyświetlane były ddatkwe infrmacje, zbędne w kńcwej wersji prgramu, a nie chcemy danych linii usuwać. Pewnym rzwiązaniem są czywiście kmentarze typu /*...*/. Prblem nie mżna ich zagnieżdżać 18
PREPROCESOR - dyrektywy Dyrektywa #if kmpilacja warunkwa www.imi.plsl.pl W przypadku kmpilacji warunkwej zagnieżdżanie jest dpuszczalne: #if(wariant==1) // sprawdzamy warunek zewnętrzny #if(ladunek==1) // sprawdzamy warunek wewnętrzny //instrukcje 1 #else //instrukcje 2 #endif // LADUNEK #else #if(ladunek==1) //instrukcje 3 #else //instrukcje 4 #endif // LADUNEK #endif // WARIANT //dbrze jest ddawać taką infrmację... 19
PREPROCESOR - dyrektywy Przykład: www.imi.plsl.pl 20
PREPROCESOR - dyrektywy Dyrektywy #ifdef, #ifndef kmpilacja warunkwa www.imi.plsl.pl Pstaci: a) b) #ifdef nazwa1 #ifndef nazwa2 instrukcje #endif #endif instrukcje W bydwu przypadkach jest sprawdzane, czy dana nazwa zstała zdefiniwana pleceniem #define. W przypadku a) instrukcje będą skmpilwane, jeśli nazwa1 jest zdefiniwana (i nie zstała dwłana przez #undef). W przypadku b) instrukcje nie będą skmpilwane, jeśli nazwa2 jest zdefiniwana (i nie zstała dwłana przez #undef). 21
PREPROCESOR - dyrektywy Dyrektywa #errr przerwanie kmpilacji www.imi.plsl.pl Pstać: #errr tekst P naptkaniu tej dyrektywy kmpilacja jest przerywana i wyświetlana jest przez kmpilatr infrmacja diagnstyczna zawarta w tekst, np.: 22
PREPROCESOR - dyrektywy www.imi.plsl.pl Nazwy predefiniwane preprcesra ( znacza 2 znaki pdkreślenia ) LINE numer linii pliku która jest kmpilwana / w której znajduje się nazwa FILE DATE TIME nazwa kmpilwaneg pliku ciąg znaków dpwiadający dacie w mmencie kmpilacji w pstaci: Nv 19 2013 ciąg znaków dpwiadający czaswi kmpilacji w pstaci: 12:54:54 23
PROGRAM W WIELU PLIKACH www.imi.plsl.pl Mżliwe (i częst wskazane) jest twrzenie prjektów bejmujących więcej, niż jeden plik: nie jest kmpilwany cały prjekt a tylk zmdyfikwany plik (ważne przy dużych prgramach); łatwiej jest panwać nad dużym prjektem. Uwagi: Prgram mżna pdzielić na pliki jedynie między definicjami funkcji. Należy zadbać t, by funkcje z jednych plików miały dstęp d zmiennych glbalnych z innych plików - umieszczamy stswne deklaracje (nie definicje!); Zapewnia t w przypadku zmiennych deklaracja z użyciem słwa extern, np.: extern int x; infrmuje, że zmienna x jest typu int i zstanie zdefiniwana w innym miejscu (np. w innym pliku). Częst twrzy się sbny plik nagłówkwy ze stswnymi deklaracjami. Taki plik nagłówkwy włącza się d innych plików dyrektywą #include "nazwa.h" 24
PROGRAM W WIELU PLIKACH Przykład: www.imi.plsl.pl 25
FUNKCJE REKURENCYJNE www.imi.plsl.pl Funkcja rekurencyjna t funkcja, która wywłuje samą siebie (rekurencja bezpśrednia). Nie jest t cecha języka, lecz zagadnienie związane z algrytmami. W zasadzie każda funkcja mże wywływać sama siebie. Należy zapewnić dpwiedni warunek (warunek zatrzymujący rekurencję), by uniknąć nieskńczneg wywływania funkcji. Rekurencja pśrednia: funkcja 1 wywłuje funkcję 2, która z klei wywłuje funkcję 1. Przykład ( klasyczny ) funkcji rekurencyjnej: lng int silnia (int n) { if (n==0) return 1; // z definicji silni... //przy kazji warunek zatrzymujący rekurencję return n*silnia(n-1); //wywłanie rekurencyjne } 26
PROBLEMATYCZNE SPACJE www.imi.plsl.pl Uwaga na teksty wpisywane za pmcą strumienia cin: Strumień wczytuje dane d zmiennej d naptkania białeg znaku (spacji, tabulatra, znaku kńca linii) np.: string imie_nazwisk; cut<<"pdaj imie i nazwisk"<<endl; cin>>imie_nazwisk; //Pdajemy np: Adam Nwak cut<<imie_nazwisk<<endl; //Adam // nie tak t miał wygladać.. Rzwiązanie: getline(cin,imie_nazwisk); //zamiast cin>>imie_nazwisk; 27