Jerzy Kisielewicz Jakub Gładysz Karol Puchała Instrukcja nr 1 do Laboratorium z Programowania Obiektowego Zajęcia 1-5 Tydzień INEW002L Semestr 2 Kierunek: Informatyka (INF) Teleinformatyka (TIN) Studium Kształcenia Podstawowego (SKP) Wrocław 2009
Zajęcia Laboratoryjne składają się z 15 zajęć po 90 minut każde. Podczas pierwszych zajęć prowadzący winien przeprowadzić szkolenie BHP oraz zapoznać studentów z Regulaminem Pracowni. Warunkiem uczestnictwa w zajęciach jest odbycie w/w szkolenia i poświadczenie go czytelnym podpisem. Na każde zajęcia przygotowana będzie instrukcja laboratoryjna z zestawem zadań do zrobienia oraz wskazówkami. Zadania z bieżącego laboratorium powinny być oddane na następne zajęcia. Oddanie zadań po terminie skutkuje obniżeniem oceny za dane laboratorium. Oprócz tego na niektórych zajęciach będzie sprawdzana wiedza Studentów poprzez rozwiązanie zadań testowych w systemie Moodle (w czasie 6 laboratoriów). Tematyka zadań testowych na dane laboratorium znajduje się w Tabeli na następnej stronie. W przypadku oceny niedostatecznej z testu, student dopuszczony jest do laboratorium, przy czym na kolejnych zajęciach będzie zobowiązany do zaliczenia tego testu. Ocena za test będzie wówczas średnią punktów z pierwszego oraz drugiego podejścia. Oprócz list zadań każdy student otrzyma Projekt Indywidualny, który powinien zostać zrealizowany najpóźniej na przedostatnie zajęcia laboratoryjne. Propozycje tematów semestralnych znajdują się w instrukcji nr 4 i zaprezentowane zostaną podczas drugich zajęć laboratoryjnych. Zadania ostatecznie przydzielone powinny zostać do czwartych zajęć laboratoryjnych. Możliwa jest własna propozycja tematu semestralnego, przy czym zawartość Projektu musi pokrywać się z tematyką wykładu oraz laboratorium. Warunkiem koniecznym zaliczenia przedmiotu jest: 1) Uczęszczanie na zajęcia (możliwe jedynie 2 nieobecności nieusprawiedliwione), 2) Zrealizowanie WSZYSTKICH zadań przewidzianych do zrobienia w czasie laboratorium (w czasie zajęć mogą być zaproponowane dodatkowe zadania na ocenę celującą dla ochotników), 3) Zaliczenie zadań testowych z danej tematyki laboratorium, 4) Zrealizowanie indywidualnego Zadania Projektowego. Szczegółowe zasady zaliczeń i proporcje przedstawia prowadzący. Obowiązująca Platforma Programowa to Visual Studio C++ 2008. Zaliczenie laboratorium jest warunkiem koniecznym dopuszczenia do egzaminu z wykładu!
Program laboratorium przedstawia się następująco: Lab. Instrukcja Temat Laboratorium Test 1 1 Wstęp. Uruchomienie prostej aplikacji terminalowej 2 1 3 1 4 1 5 1 6 2 Prosta aplikacja terminalowa. Formatowanie obiektowego wejścia i wyjścia Propozycje programów semestralnych Definicja prostej klasy (punkt, prostokąt, zesp, itp). Obserwacja konstruktorów i destruktorów Aplikacja dialogowa budowa interfejsu użytkownika + przydział tematów semestralnych Rozbudowa aplikacji dialogowej programowanie obsługi wybranych kontrolek Klasa z alokacją pamięci definiowanie konstruktorów, destruktora i operatora przypisania Podstawy C, Wskaźniki i struktury Podstawy C++ Klasy i ich metody 7 2 Przeciążanie operatorów. Definiowanie klas pochodnych, dziedziczenie proste i wielobazowe 8 2 (kontynuacja ćwiczenia 7) Klasy pochodne, Diedziczenie, Polimorfizm 9 2 Funkcje wirtualne, klasy abstrakcyjne 10 3 Aplikacja dialogowa 11 3 Aplikacja SDI Windows (zdarzenia, aplikacje dialogowe i SDI) 12 3 Aplikacja SDI (cd.) 13 4 Program semestralny UML, Wyjątki 14 4 Program semestralny (c.d.) 15 4 Program semestralny (c.d.) i wpisy
Ćwiczenie 1. Wstęp. Uruchomienie prostej aplikacji terminalowej. Propozycja programów semestralnych. Celem ćwiczenia jest poznanie środowiska kompilatora Microsoft Visual Studio 2008 Professional C++, sposobu tworzenia aplikacji terminalowych. Zapoznać się z edytorem i kompilatorem. 1. Wybrać z menu File New Projects. Wybrać lokalizację, czyli katalog, w którym automatycznie powstanie podkatalog (przestrzeń robocza tworzonego programu -> ang location). W przestrzeni roboczej będą umieszczone pliki tworzonego programu. Wpisać nazwę projektu (będzie to nazwa podkatalogu i równocześnie programu) -> name. Z listy projektów wybrać: Visual C++ Win32 Win32 Console Application i nacisnąć OK. 2. nacisnąć klawisz Next, następnie wybrać typ aplikacji Console Application i nacisnąć klawisz Finish. 3. W funkcji _tmain wpisać cout << Własny tekst <<endl; 4. Skompilować i uruchomić wybraną aplikację. Wybrać z menu: Build Build..., a następnie po poprawnej kompilacji uruchomić program wybierając: Build Execute.... Wszystkie programy powinno się uruchamiać dopisując do takiego programu kolejne instrukcje i sprawdzając, co pewien czas, czy tworzony niekompletny program się kompiluje i czy prawidłowo się wykonuje. Podstawowa idea polega na tym, aby cały czas pracować z chodzącym programem
Ćwiczenie 2. Definicja prostej klasy. Obserwacja konstruktorów i destruktorów. Celem ćwiczenia jest poznanie zasad formatowania obiektowego wejścia i wyjścia. Zadania laboratoryjne (czas realizacji: 1 tydzień) 1.1. Napisz i uruchom program, który wczyta 1 kilka liczb rzeczywistych do tablicy TAB[Max] (Max=1000), następnie wyprowadzi te liczby w wyrównanej kolumnie. W programie kontroluj, aby zadany rozmiar tablicy nie przekroczył maksymalnego. 1.2. W programie z zadania 1.1 zredaguj precyzję wyprowadzanych liczb tak, aby była ona zależna od życzenia użytkownika. Jako dane wprowadzaj liczby o różnej liczbie cyfr po kropce dziesiętnej oraz liczby całkowite. 1.3. Sformatuj wyprowadzane liczby tak, aby miały one jednakową zadaną liczbę cyfr po kropce oraz aby kropki dziesiętne były pisane w jednej kolumnie. 1.4. Wyprowadzaj każdą liczbę dwukrotnie: w notacji zwykłej i naukowej Np. w postaci TAB[7]= 3.20 3.20E+00. 1.5. Zaproponuj konwersje wprowadzonych liczb do postaci ósemkowej oraz szesnastkowej. 1.6. Jakie pliki zawiera przestrzeń robocza programu i jaka jest zawartość pliku StdAfx.h? *Do wczytywania liczb należy używać obiektowych operatorów wejścia. Dodatkowo mile widziane będzie wczytywanie danych z pliku (strumienie plikowe). 1 Do wczytywania liczb należy używać obiektowych operatorów wejścia. Dodatkowo mile widziane będzie wczytywanie danych z pliku (strumienie plikowe).
Ćwiczenie 3. Definicja prostej klasy. Obserwacja konstruktorów i destruktorów. Zadania laboratoryjne (czas realizacji: 1 tydzień) Celem ćwiczenia jest poznanie zasad definiowania oraz obserwacja konstruktorów i destruktorów poprzez tworzenie prostych obiektów. 1. Napisz w języku obiektowym C++ następujący program: Stwórz klasę definiującą okręg. Każdy okręg składa się ze współrzędnych środka oraz promienia (współrzędne środka x,y powinny być zmiennymi całkowitymi, promień r liczbą rzeczywistą nieujemną). Dokonaj wczytania liczb ze sprawdzeniem poprawności (r>=0). W programie obiektowym użyj konstruktora z parametrami do przypisania wartości początkowych na standardowe współrzędne środka S(0,0) oraz promień r=1. Użyj konstruktora z tzw. listą inicjalizującą. Oprócz konstruktora z parametrami zdefiniuj oraz zbadaj przykład użycia konstruktora bezparametrowego oraz konstruktora z niepełną liczbą parametrów. Wyświetleniem komunikatu na ekran informuj użytkownika który konstruktor został wywołany. Napisz funkcje obliczające Pole oraz Obwód okręgu oraz wyprowadzające wynik z dokładnością do 0,001. Wprowadź dane dwóch okręgów oraz zbadaj czy wprowadzone okręgi mają punkty wspólne. Program powinien poinformować o tym użytkownika w postaci wyprowadzenia komunikatu o ilości punktów wspólnych (zero, jeden, dwa lub nieskończenie wiele). 2. Niech obiektem będzie klasa Student posiadająca następujące pola: Imie (typu String), Nazwisko (String), Nr_albumu (integer), Srednia (float), Przedmioty (dynamiczna tablica typu String). Na początku programu użytkownik podaje liczbę tworzonych obiektów K i zostaje przydzielona pamięć na tablicę K obiektów typu
Student. Następnie należy wczytać dane poszczególnego Obiektu z klawiatury. W czasie wczytywania każdego obiektu powinno znaleźć się zapytanie o ilość Przedmiotów N dla danego obiektu Student, a następnie dynamicznie przydzielona pamięć na N Przedmiotów oraz ich wczytanie. Należy stworzyć Menu umożliwiające: a) Dodanie i wprowadzenie danych nowego studenta (zwiększając pamięć o 1 obiekt klasy student), b) Wyświetlenie aktualnego stanu tablicy, c) Zapisanie zawartości bazy do pliku student.txt (średnia z dokładnością do 2 miejsc po przecinku, nr indeksu w notacji szesnastkowej), d) Skasowanie całej zawartości i zakończenie programu. Program powinien działać w pętli a zwiększanie tablicy obiektów klasy student powinno odbywać się dynamicznie z chwilą wprowadzania nowego studenta. Zaproponuj odpowiedni konstruktor, destruktor, do wypisywania danych użyj przeciążonego operatora <<. Czy w zadaniu można użyć destruktora domyślnego czy konieczne będzie użycie konstruktora jawnego?
Ćwiczenie 4. Aplikacja dialogowa budowa interfejsu użytkownika Przydział tematów semestralnych Zadania laboratoryjne (czas realizacji: 1 tydzień) Celem ćwiczenia jest poznanie sposobu tworzenia aplikacji windowsowych MFC oraz zasad umieszczania i programowania podstawowych kontrolek w oknie dialogowym. Uruchomić program, który w zależności od wyboru: doda, odejmie, pomnoży lub podzieli dwie liczby. W tym celu należy wykonać poniższe kroki. 1. Wybrać z menu File New Projects. a. Wybrać lokalizację, czyli katalog, w którym automatycznie powstanie podkatalog (przestrzeń robocza tworzonego programu -> ang location). W przestrzeni roboczej będą umieszczone pliki tworzonego programu. b. Wpisać nazwę projektu (będzie to nazwa podkatalogu i równocześnie programu) -> name. c. Z listy projektów wybrać: VisualC++ MFC MFC Application. i nacisnąć OK. 2. Step1 Nacisnąć Next. Wybrać typ aplikacji Dialog based i nacisnąć klawisz Finish. 3. Skompilować i uruchomić wybraną aplikację. Wybrać z menu: Build Build, a następnie po poprawnej kompilacji uruchomić program wybierając: Debug Start Without Debugging.... Powieli się okno z nazwą programu zakończyć program naciskając klawisz OK. lub Cancel. 4. Kliknąć napis TODO: Place dialog controls here. ( kontrolka Static Textt ) Przesunąć okienko z tym tekstem do górnej krawędzi okna programu. Kliknąć prawym klawiszem na ww. tekst i wybrać Properties. W okienku właściwości w linii edycyjnej Appearance Caption wpisać inny dowolny tekst. W zakładce Align Textt można zmienić zmienić położenie tekstu.
5. Z okienka Toolbox przeciągnąć myszką ikony Aa (Static Textt) oraz ab (Edit Box) na wybrane miejsca obok siebie w okienku programu. Jak w p. 4 wprowadzić do kontrolki Static Textt tekst z opisem pierwszej danej, która będzie wprowadzana do linii edycyjnej Edit Box. Powtórzyć (dwa razy) czynności z p. 5 dla drugiej danej i dla wyniku. Uruchomić program. 6. We właściwościach linii edycyjnej wyniku wybrać zakładkę Behavior i ustawić opcję Read-only na TRUE. 7. Zdefiniuj obsługę zdarzeń w pierwszej linii edycyjnej. Kliknij jej ikonę prawym klawiszem i wybierz Add Event Handler. W okienku Message type: podświetl EN_KILLFOCUS (zdarzenie wyjścia myszą z obszaru linii edycyjnej). Naciśnij klawisz Add and Edit i zaakceptuj nazwę funkcji. Pojawi się okno do edycji kodu źródłowego w C++. Wpisz następującą zawartość funkcji obsługi zdarzenia (jeśli IDC_EDIT1 identyfikuje tę linię edycyjną sprawdzisz to w jej właściwościach). CEdit* pedit=(cedit*)getdlgitem(idc_edit1); pedit->getwindowtextt(m_text); a=atof(m_text); m_text.format("%.*lf", prec, a); pedit->setwindowtextt(m_text); 8. Aby wrócić do edycji graficznej w lewym oknie (w zakładce Res.. ) rozwiń drzewo i gałąź Dialog oraz wybierz (dwuklik) okno dialogowe programu (IDE_Nazwa_Projektu_DIALOG). Powtórz to samo dla drugiej linii edycyjnej (z identyfikatorem IDC_EDIT2) używając zmiennej b w miejsce zmiennej a. Skompiluj program. Błędy kompilacji wykazują brak definicji zmiennych: m_text, a, prec, b. 9. Zdefiniuj ww. zmienne w klasie okna dialogowego. Kliknij prawym klawiszem nazwę klasy okna dialogowego w zakładce Clas.. i wybierz Add Member Variable. Dodobnie dodaj zmienną prec typu int oraz zmienne a, b typu double. 10. Dodaj zmienną zabezpieczoną (Protected) m_text typu CString do klasy dialogowej. W tym celu przejdź do zakładki Class View. Wykonaj dwuklik na klasę dialogową - przejdziesz do edycji tej funkcji. Po instrukcji double b; dopisz inicjacje zmiennej CString m_text;
11. Zmień system kodowania znaków. Przy otwartym projekcie wejdź w Project->Properties->Configuration Properties->General, znajdź pole Character Set i wybierz Use Multi-Byte Character Set. 12. Klikinij na klasę dialogowa. W poniżej ukażą się funkcje tej kasy. Wykonaj dwuklik na funkcji OnInitDialog() przejdziesz do edycji tej funkcji. Przed instrukcją return TRUE; dopisz inicjację zmiennej prec dopisz instrukcję prec=3;. Skompiluj i uruchom program. Spróbuj wpisywać dane. 13. W podobny sposób zainicjuj zmienne a i b oraz linie edycyjne wpisując do funkcji OnInitDialog instrukcje: a=b=1; m_text.format("%.*lf", prec, a); ((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowTextt(m_Text); ((CEdit*)GetDlgItem(IDC_EDIT2))->SetWindowTextt(m_Text); 14. Dodaj funkcję obsługi kliknięcia klawisza OK.. W edytorze graficznym kliknij ten klawisz prawym klawiszem myszki i wybierz Add Event Handler., a następnie klawisz Add and Edit i zaakceptuj nazwę funkcji. W edytorze tekstu źródłowego usuń instrukcję OnOK(); i na jej miejsce wpisz instrukcje: CEdit* pedit=(cedit*)getdlgitem(idc_edit3); double wynik=a+b; m_text.format("%.*lf", prec,wynik); pedit->setwindowtextt(m_text); 15. Przetestuj działanie programu. 16. Do okna programu (edycja graficzna) wstaw kontrolkę Group Box i zwiększ jej wymiary. W obszar kontrolki wstaw jeden pod drugim 4 przyciski Radio Button. Zaznacz te przyciski i kliknij prawym klawiszem myszki, a następnie wyrównaj położenie przycisków wybierając Align Left Edges. 17. Podobnie jak w p. 4 zaopatrz przyciski w teksty; Dodaj, Odejmij, Pomnóż i Podziel. W oknie właściwości pierwszego przycisku ( Dodaj ) zaznacz opcję Group -> TRUE Dla tego przycisku stwórz zmienną m_zadanie typu int klikając go prawym klawiszem i wybierając Add Variable. W Add Member Variable Wizard zmień Category na Value.
Następnie ustaw Variable Type na typ całkowity int. nadaj nazwę zmiennej w okienku Variable Name i naciśnij OK. 18. W konstruktorze klasy okna dialogowego sprawdź wartość początkową zmiennej m_zadanie. Jeżeli wartość będzie różna od 0, zmień ją na 0. Następnie sprawdź działanie programu. 19. Zmodyfikuj działanie funkcji obsługi naciśnięcia klawisza OK. tak, aby wynik zależał od wartości zmiennej m_zadanie (po wykonaniu funkcji UpdateData(), aktualizowane są wartości zmiennych stowarzyszonych z przyciskami i zmienna m_zadanie otrzymuje wartości: 0 dodawanie, 1 odejmowanie, 2 mnożenie i 3 dzielenie). 20. Umieść w oknie dialogowym tekst statyczny i linię edycyjną do wprowadzenia wymaganej liczby cyfr ułamkowych precyzji. Napisz funkcję obsługi tej kontrolki Edit Control, aby wprowadzoną liczbę całkowitą podstawiać do zmiennej prec zdefiniowanej w klasie okna dialogowego.
Ćwiczenie 5..Rozbudowa aplikacji dialogowej programowanie obsługi wybranych kontrolek Wielu kontrolkom ( np.: Edit Control, Button, Check Box, Radio Button, Combo Box, List Box, ) można przypisać zmienne zgodne z typem wprowadzanych danych. Np. linii edycyjnej "Edit Control" można przypisać zmienną tekstową typu CString, aby wprowadzać teksty, zmienną typu int, aby wprowadzać liczby całkowite, zmienną typu double itp. Zmiennym można ograniczać zakres akceptowanych danych. Np. można określić rozmiar zmiennej tekstowej ograniczając długość tekstu. Zmiennym liczbowym można określić minimalną i maksymalną wartość. Aby przekazać dane z kontrolek do przypisanych im zmiennych, należy wywołać funkcję UpdateData() z domyślnym argumentem TRUE. Aby przekazać dane ze zmiennych do przypisanych im kontrolek, należy wywołać funkcję UpdateData(FALSE). Zadania laboratoryjne (czas realizacji: 1 tydzień) Celem ćwiczenia jest doskonalenie umiejętności posługiwania się kontrolkami. Zadanie 1 1. W programie z ćwiczenia 4 dodać do linii edycyjnej do wprowadzania precyzji zmienną m_prec typu int i ograniczyć zakres wprowadzanych wartości do przedziału od 0 do 8. W tym celu klikając prawym klawiszem na kontrolkę wybieramy Add Variable. W powstałym oknie Add Member Variable Wizard zmieniamy Category na Value. Następnie ustaw Variable Type na typ całkowity int. nadaj nazwę zmiennej w okienku Variable Name. Następnie określamy minimalną i maksymalną wartość. i naciśnij OK. Na koniec zmieniamy zawartość funkcji obsługi kontrolki na: UpdateData(); prec=m_prec;
2. We właściwościach klawiszy OK. i Cancel zmień teksty na klawiszach na Oblicz i Koniec. Wstaw początkowy napis 3 do kontrolki wprowadzania precyzji w funkcji OnInitDialog w miejsce linii prec=3; wstaw linie m_prec=prec=3; UpdateData(FALSE); 3. We właściwościach klawisza Oblicz zmień tekst na nim na Dodaj. Do kontrolek Radio Button dodaj funkcje obsługi zdarzenia BN_CLICKED. W każdej funkcji zmieniaj tekst na klawiszu na zgodny z wybranym przyciskiem. Np. aby zmienić tekst na Podziel, należy w funkcji dodanej do przycisku Odejmij wpisać instrukcję ((CEdit*)GetDlgItem(IDOK))->SetWindowText("Podziel"); gdzie IDOK jest identyfikatorem klawisza. 4. Dopisz pokazanie okna klasy CAboutDlg zdefiniowanego automatycznie w Twoim programie. Do tego celu użyj dodatkowego klawisza, któremu nadaj właściwości Caption: O Programie oraz identyfikator IDC_ABOUT. Niech funkcja obsługi zdarzenia BN_CLICKED utworzy obiekt klasy CAboutDlg i wykona na nim funkcję DoModal(). Zadanie 2 1. Stwórz nową aplikację MFC i napisz funkcje realizujące następujące operacje Stwórz 2 pola umożliwiające wprowadzenie dwóch liczb naturalnych n i k z zakresu <0-100> oraz (n>=k) a następnie napisz 4 funkcje liczące: a) silnie podanej liczby n lub k* b) kombinacje (n po k) c) n-tą lub k-tą liczbę pierwszą* d) n k *) Należy użytkownikowi umożliwić wybór 2 Stwórz pole umożliwiające wprowadzenie tekstu (ścieżki do pliku tekstowego - np. dane.txt), w którym będzie zawarta w pierwszej linii ilość elementów tablicy A, a w drugiej i następnych liczby naturalne oddzielone znakiem spacji. Odczytaj ilość liczb, a następnie stwórz dynamiczną tablicę
integer wielkości A i wpisz do niej elementy z pliku dane.txt. Na danych z pliku dokonaj następujących operacji: a) znajdź element maksymalny oraz minimalny, b) rozpiętość danych, czyli różnice pomiędzy elementem max a min, c) policz wartość średnią elementów z dokładnością do 0.01. Następnie zapisz te wartości do pliku wyjściowego wyniki.txt każdą policzoną wartość w osobnej linii.