Instrukcja do laboratorium
Transkrypt
Instrukcja do laboratorium
Programowanie Obiektowe Szczegółowy harmonogram laboratorium Poniższy harmonogram precyzuje terminy oddania programów wymienionych w programie laboratorium na stronie domowej przedmiotu: Program nad którym pracujemy Zajęcia Program do oddania Kolokwium 1 Hello world, Konkatenacja - - 2 Wyznacznik Konkatenacja - 3 Wyznacznik - - 4 Stos C Wyznacznik - 5 Stos C++ - Kolokwium 1 (15 min) 6 Complex Stos C, Stos C++ - 7 Complex - Kolokwium 2 (10 min) 8 Macierz Complex - 9 Macierz - - 10 Tablica asocjacyjna Macierz - 11 Tablica asocjacyjna - - 12 Wzorzec tablicy asocjacyjnej Tablica asocjacyjna - 13 - - Kolokwium 3 (60 min) 14 Wzorzec tablicy asocjacyjnej Wzorzec tablicy asocjacyjnej - Szczegółowe zasady wystawiania oceny końcowej Student ma prawo do jednej nieusprawiedliwionej nieobecności w semestrze. Każdy program ma ustalony termin oddania i jest oceniany w skali 0 - 100% jak poniżej: 100% - poprawny program oddany w terminie 60% - poprawny program oddany po terminie 0% - plagiat (niedopuszczalna jest sytuacja gdzie student prezentuje program i nie potrafi wyjaśnić każdej pojedynczej linii kodu) Ocenianie programów przez prowadzącego rozpoczyna się na początku zajęć wypadających w dniu terminu oddania. Programy nie są oceniane na godzinach konsultacji za wyjątkiem ostatniego tygodnia zajęć. Programy nie są oceniane w sesji egzaminacyjnej. Oceny ze wszystkich programów maja jednakowe wagi dające w sumie wagę 65%. Kolokwia maja wagi zróżnicowane jak na stronie domowej przedmiotu dające w sumie wagę 35%. Końcowa ocena procentowa przeliczana jest na ocenę w skali 2 - 5 zgodnie z przelicznikiem podanym na stronie przedmiotu. Szczegółowe zasady kolokwiów Kolokwium 1 Zgodnie z informacjami na stronie domowej przedmiot u zadaniem jest: • Zdefiniowanie funkcji standardowej z nagłówka <string.h> lub <ctype.h>. • Napisanie deklaracji określonego wskaźnika do funkcji. Lista funkcji których NIE będzie na kolokwium: string.h: • memmove • memcmp • strcoll • strxfrm • memchr • strcspn • strpbrk • strspn • strstr • strtok • strerror ctype.h: • iscntrl • isgraph • isprint • ispunct • isxdigit Na kolokwium studenci nie korzystają z żadnych własnych materiałów. Jeżeli zadanie będzie tego wymagało to studenci otrzymują wydruk tabeli kodu ASCII. Kolokwium 2 Studenci otrzymują fragmenty kodu, zawierającego błędy. Należy je wskazać oraz uzasadnić odpowiedź. Kolokwium 3 Studenci otrzymują fragment programu wykorzystującego pewną klasę oraz mają za zadanie napisanie tej klasy tak, aby podany fragment kompilował się i działał poprawnie. Ogólne zasady pisania programów Program ma być napisany przejrzyście i czytelnie. Program ma być wyraźnie podzielony na funkcje odpowiadające za poszczególne zadania. Unikaj długich funkcji. Staraj się pisać funkcje zawierające kilka, maksymalnie kilkanaście linii kodu. Unikaj duplikacji kodu. Nazwy funkcji mają być dobrane tak aby wyjaśniały co dana funkcja wykonuje. Nazwy zmiennych mają być dobrane tak aby wyjaśniały co dana zmienna reprezentuje. Nie ma nic złego w stosowaniu dłuższych nazw funkcji i zmiennych zbudowanych z kilku słów. Zastanów się jaką konwencję nazewnictwa chcesz stosować i stosuj ją konsekwentnie w swoich programach. Staraj się nie pisać komentarzy na rzecz lepszego nazewnictwa typów, funkcji i zmiennych. Nie używaj w programie "liczb magicznych". Poprawnie stosuj wcięcia w programie (aby uporządkować wcięcia: zaznacz blok kodu w edytorze tekstowym, wciśnij Tab lub Shift+Tab). Wskazówki do wybranych zadań Konkatenacja Wskazówka: implementując funkcję konkatenacji możesz skorzystać z funkcji dostępnych w bibliotece standardowej. Wymaganie: za pomocą programu valgrind sprawdź czy poprawnie zarządzasz pamięcią. Wyznacznik Wymaganie: za pomocą programu valgrind sprawdź czy poprawnie zarządzasz pamięcią. Stos C Zaimplementuj w języku C stos liczb całkowitych. Zapewnij następującą funkcjonalność: void init(struct Stack* s) void destroy(struct Stack* s) void push(struct Stack* s, int element) int pop(struct Stack* s) void clear(struct Stack* s) bool isempty(struct Stack* s) - upewnij się ze załączasz plik nagłówkowy stdbool.h konieczne aby używać typu bool w języku C Użyj dynamicznie alokowanej tablicy do przechowywania elementów na stosie. Gdy tablica się zapełni zwiększaj jej rozmiar dwukrotnie. W razie wystąpienia błędu (np. wywołanie funkcji pop gdy stos jest pusty) wywołuj funkcje assert lub abort aby zakończyć działanie programu. Wskazówka 1: w wykonaniu zadania pomogą ci przykładowe implementacje stosu prezentowane na wykładzie. Wskazówka 2: możesz zdefiniować strukturę z użyciem słowa kluczowego typedef aby nie trzeba było później w programie wszędzie stosować słowa kluczowego struct. Wymaganie 1: podziel program na następujące pliki: Stack.h, Stack.c, main.c. Nie jest wymagane przygotowanie pliku makefile. Wymaganie 2: za pomocą programu valgrind sprawdź czy poprawnie zarządzasz pamięcią. Stos C++ Napisz w jeżyku C++ klasę Stack o funkcjonalności analogicznej jak w poprzednim zadaniu. Wymaganie 1: podziel program na następujące pliki: Stack.h, Stack.cpp, main.cpp. Nie jest wymagane przygotowanie pliku makefile. Wymaganie 2: za pomocą programu valgrind sprawdź czy poprawnie zarządzasz pamięcią. Complex Zaimplementuj klasę Complex reprezentująca liczby zespolone. Zapewnij następująca funkcjonalność: podstawowe operatory arytmetyczne +, -, *, /, +=, -=, *=, /= operator porównujący == operator << funkcje zwracające cześć rzeczywista i urojona funkcje zwracające amplitudę i fazę Starannie przetestuj cala zaimplementowana funkcjonalność. Przetestuj przypadki szczególne jak: a += b += c a * 10 10 * a Wskazówka: implementuj większość funkcjonalności jako funkcje składowe klasy. Pisz funkcje nie składowe tylko gdy jest to uzasadnione. Wymaganie: podziel program na następujące pliki: Complex.h, Complex.cpp, main.cpp. Matrix Zaimplementuj klasę Matrix reprezentująca macierz liczb rzeczywistych typu double. Zapewnij następująca funkcjonalność: podstawowe operacje arytmetyczne +, -, *, +=, -=, *= konstruktor kopiujący oraz operator przypisania = operator porównania == operator wyświetlania << możliwość wczytywania macierzy z plikowego strumienia wejściowego dostęp do pojedynczego elementu - możesz przeciążyć operator(), tak aby m(2, 3) oznaczało element umieszczony w rzędzie 2, kolumnie 3 obiektu macierzy m. Należy rozróżniać pomiędzy operacja zapisu a odczytu. Jeżeli zaprezentujesz program który traktuje każdy dostęp do elementu jako operacje zapisu możesz uzyskać maksymalnie 60%. Zastosuj w implementacji zliczanie odwołana (ang. reference counting). Obsługa błędów: W razie wystąpienia błędu wyrzucaj wyjątek Rozróżniaj różne rodzaje błędów poprzez wyrzucanie wyjątków różnego typu Zapewnij własne klasy do reprezentacji błędów (jedna klasa na każdy jeden typ błędu) Starannie przetestuj cala zaimplementowana funkcjonalność. Tablica asocjacyjna Zaimplementuj tablice asocjacyjna liczb całkowitych indeksowana łańcuchem tekstowym. Unikając duplikacji kodu zaimplementuj dwie wersje tej tablicy: z rozróżnianiem małych i wielkich liter bez rozróżniania małych i wielkich liter Wymaganie 1: nie wolno używać gotowych kontenerów z biblioteki standardowej. Wymaganie 2: nie wolno duplikować kodu. Rozwiązania z duplikacja kodu nie będą akceptowane. Wskazówka: zamiast duplikować kod należy zaproponować odpowiednia hierarchię klas z wykorzystaniem polimorfizmu. Wzorzec tablicy asocjacyjnej Zaimplementuj wzorzec tablicy asocjacyjnej "Map" oraz klasę "Employee" reprezentująca dane personalne pracownika. Przykładowe użycie wzorca "Map" i klasy "Employee" ilustruje kod: #include <iostream> #include "Employee.h" #include "Map.h" //Defines class Employee //Defines template Map<Key,Value> using namespace std; int main(void) { typedef unsigned int ID; Map<ID,Employee> database; //Identification number of Employee //Database of employees database.Add(761028073,Employee("Jan Kowalski","salesman",28)); employee: name: Jan Kowalski, position: salseman, age: 28, //Add first database.Add(510212881,Employee("Adam Nowak","storekeeper",54)); employee: name: Adam Nowak, position: storekeeper, age: 54 database.Add(730505129,Employee("Anna Zaradna","secretary",32)); employee: name: Anna Zaradna, position: secretary, age: 32 }; //Add second //Add third cout << database << endl; //Print database Map<ID,Employee> newDatabase = database; //Make a copy of database Employee* pE; pE = newDatabase.Find(510212881); pE->Position = "salesman"; pE = newDatabase.Find(761028073); pE->Age = 29; //Find employee using its ID //Modify the position of employee //Find employee using its ID //Modify the age of employee database = newDatabase; //Update original database cout << database << endl; //Print original database