Wejściówka na lab.10

Zaprojektuj klasę, która posłuży do tworzenia obiektów reprezentujących macierze przechowujące liczby rzeczywiste.

Klasa macierz posiada pola do zarządzania dwuwymiarową, dynamiczną tablicą reprezentującą komórki macierzy. Wszystkie pola są prywatne.

Posiada trzy konstruktory:

  1. domyślny, inicjalizujący wszystkie pola tak, aby powstała macierz o wymiarach 1 na 1; w tym przypadku nie powinny być alokowane żadne dodatkowe zmienne dynamiczne,
  2. konstruktor z argumentami opisującymi wymiary macierzy; wymiary mogą być dowolne większe od zera. Pamięć pod komórki macierzy powinna być alokowana dynamicznie. Przy okazji działania tego konstruktora przetestuj, jakie są górne granice dostępnej pamięci w twoim komputerze, tj. podając coraz większe wymiary macierzy doprowadź do sytuacji, kiedy alokacja pamięci w końcu nie powiedzie się. Zapisz uzyskane wartości graniczne, będą potrzebne na wejściówce,
  3. konstruktor kopiujący, który utworzy drugą macierz identyczną co do rozmiaru i zawartości.

oraz destruktor, który zwalnia dynamicznie zaalokowane zasoby.

Posiada też seter i geter do komórek macierzy. Obydwie metody powinny kontrolować poprawność argumentów wejściowych, tj. czy współrzędne żądanej komórki mieszczą się w dozwolonych granicach.

Dodatkowo posiada metodę, która realokuje rozmiar macierzy, tj. powiększa jej rozmiar lub pomniejsza. W przypadku pomniejszenia, część informacji zapisanej w komórkach macierzy jest tracona. W przypadku powiększenia nowo dodane komórki są zapełnianie wartością domyślną (dowolnie ustaloną).

Napisz prosty program testujący działanie wszystkich konstruktorów, destruktora i metod klasy macierz. Utwórz obiekt z wykorzystaniem konstruktora domyślnego. Utwórz drugi obiekt reprezentujący macierz o dowolnym rozmiarze i zainicjuj go wartościami losowymi z przedziału (-1,1) (użyj do tego setera). Utwórz trzeci i czwarty, obydwa będące kopiami odpowiednio pierwszego i drugiego obiektu. Porównaj zawartość komórek miedzy oryginałami i kopiami (użyj do tego getera).

Wejściówka na lab.9

Zaprojektuj klasę, reprezentującą figurę na płaszczyźnie: trapez.

Zaproponuj zestaw pól dla tej klasy, pozwalający na jednoznaczne określenie jej położenia na płaszczyźnie względem początku układu współrzędnych oraz jednoznacznie określający jej rozmiary (np. długości boków, podstawy, itd.). Dla uproszczenia przyjmij, że trapez jest zawsze rysowany w określonej pozycji, np. podstawą równolegle do osi X. Projektując zestaw pól postaraj się zminimalizować ich liczbę. Np. gdyby to dotyczyło kwadratu, to do określenia położenia wystarczą współrzędne jednego z wierzchołków, np. lewy-dolny, a do określenia rozmiarów – długość jednego boku. Za pomocą tych wartości jesteśmy już w stanie łatwo wyznaczyć w kwadracie współrzędne wszystkich pozostałych wierzchołków oraz długości pozostałych boków.

Zbiór pól reprezentujących położenie trapezu powinien być rozłączny ze zbiorem pól reprezentujących jego rozmiary, tak aby ewentualne operacje zmiany położenia nie obejmowały modyfikacji pól rozmiaru, a np. skalowanie nie modyfikowało pól położenia.

Wszystkie pola mają być niedostępne z zewnątrz (zadeklarowane jako private).

Do klasy dodaj trzy metody zadeklarowane jako publiczne:

  1. Pierwsza – ma ustalać położenie i rozmiary figury, tj. modyfikować wartości pól opisujących położenie i rozmiar. Nowe wartości dla pól powinny być podawane w argumentach wywołania metody. Metoda powinna kontrolować poprawność wartości podawanych w argumentach wywołania i jeżeli są nieprawidłowe (np. ujemne długości boków) powinna je zastępować bezpiecznymi wartościami domyślnymi.
  2. Druga – powinna wypisywać wartości wszystkich pól figury w oknie konsoli oraz dodatkowo wypisywać aktualne współrzędne wszystkich jej wierzchołków wyliczone na podstawie wartości pól.
  3. Trzecia – powinna wyrażać przekształcenie symetrii środkowej, tj. jako argument powinna przyjmować współrzędne punktu symetrii środkowej na płaszczyźnie, względem którego figura ma zostać przekształcona, a w swoim działaniu powinna przeliczyć wszystkie wartości tych pól, które są odpowiedzialne za położenie tak, aby w rezultacie tego działania przyjęły one wartości określające położenie figury po przekształceniu.

Napisz program, który w funkcji main deklaruje obiekt typu trapez, po czym:

  1. inicjalizuje go wartościami pobranymi od użytkownika, tak aby powstał prawidłowy trapez, korzystając z metody nr 1,
  2. wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli,
  3. prosi użytkownika o podanie współrzędnych punktu symetrii środkowej i wywołuje na rzecz tego obiektu metodę przekształcenia dla zadanego punktu,
  4. ponownie wywołuje na rzecz tego obiektu metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby zobaczyć nowe położenie figury,
  5. ponownie wywołuje na rzecz tego obiektu metodę symetrii środkowej z tym samym punktem symetrii co poprzednio,
  6. a na koniec jeszcze raz wywołuje metodę wypisującą wszystkie pola i współrzędne w oknie konsoli, aby sprawdzić, czy figura wróciła na swoje miejsce.

Wejściówka na lab.8

Napisz program, który pobiera nazwę pliku od użytkownika, otwiera plik tekstowy o podanej nazwie w trybie do odczytu, odczytuje z niego niewielką liczbę dodatnią całkowitą, po czym zamyka go. Sprawdź za pomocą asercji, czy liczba w pliku rzeczywiście jest dodatnia i czy nie jest większa od 100 (przyjmij, że inny napis niż liczba całkowita nie może w nim wystąpić). Następnie zaczyna sprawdzać zręczność użytkownika: wyświetla na ekranie dowolny napis testowy, po czym oczekuje na wprowadzenie tego napisu przez użytkownika za pomocą klawiatury mierząc czas, jaki jest potrzebny użytkownikowi na wprowadzenie tego napisu. Do pomiaru czasu użyj funkcji time i difftime. Ta czynność pomiaru powtarzana jest tyle razy, ile wynosi liczba odczytana z pierwszego pliku. Rezultat każdego pomiaru czasu zapisywany jest do listy dynamicznej. Dla skończonej serii pomiarów zapisanych w liście obliczana jest mediana. Po zakończeniu testu zręczności program pobiera od użytkownika jeszcze jedną nazwę pliku, otwiera go w trybie do zapisu i zapisuje tam całą zawartość listy dynamicznej oraz – w ostatnim wierszu – mediana. Na koniec plik jest zamykany a lista usuwana.

Uwagi:
Zaproponuj własny sposób sprawdzenia, czy plik o podanej nazwie istnieje. Następnie napisz funkcję, która jako argument wywołania przyjmuje nazwę pliku, a zwraca wartość zero, jeżeli pliku nie ma, oraz 1 – jeżeli istnieje. Użyj tej funkcji w swoim programie do sprawdzenia, czy pierwszy plik istnieje, a jeżeli nie (np. kiedy użytkownik zrobi błąd, źle podając nazwę tego pliku), poproś o ponowne podanie nazwy pliku. Użyj tej funkcji do sprawdzenia również, czy drugi plik – do zapisu – istnieje, a jeżeli istnieje, poproś użytkownika o ponowne podanie nazwy pliku do zapisu (chcemy chronić już istniejące pliki przed ich nadpisaniem nowymi danymi).

Do sprawdzania błędów związanych z dostępem do pliku wykorzystaj stałą errno a do generowania komunikatów funkcje strerror i perror. Wszelkie komunikaty o sytuacjach błędnych, jakie wystąpiły w trakcie pracy programu związane np. z dostępem do plików, wysyłaj do standardowego strumienia dla komunikatów o błędach stderr.

Wejściówka na lab.7

Napisz program wczytujący z pliku listę rekordów (rekord to kolekcja kilku dowolnych wartości, każda ściśle określonego typu, występujących w ustalonej, zawsze tej samej kolejności). Wczytywane rekordy składają się z trzech pól i są zapisane w wierszach pliku tekstowego; każdy wiersz zawiera kolejno: nr indeksu studenta, nazwisko i ocenę, które rozdzielone są znakiem spacji. Typ danych do przechowywania jednego rekordu ma następującą strukturę:

struct student {
        int nr_indeksu;
        char nazwisko[30];
        float ocena;
        struct student *nast;
        struct student *poprz;
};

W funkcji main pobierz od użytkownika nazwę pliku z danymi, otwórz ten plik w trybie do odczytu, a następnie wczytaj zawartość pliku do listy dynamicznej dwukierunkowej. Po wczytaniu każdego kolejnego wiersza dodawaj nowy element w takim miejscu listy, aby pozostawała uporządkowana rosnąco względem nr indeksu studenta. W trakcie wczytywania program powinien wypisywać na ekranie aktualnie odczytywane wartości. Przyjmij, że dane w pliku są zawsze poprawne, tj. wiersz zawsze zawiera trójkę prawidłowych napisów w prawidłowej kolejności.

Po zakończeniu czytania zamknij plik i wypisz na ekranie zawartość listy (rekordy powinny być już wtedy posortowane).

Następnie usuń z niej elementy reprezentujące studentów, którzy mają ocenę niższą niż 4.

Na koniec pobierz od użytkownika nazwę pliku do zapisu, otwórz plik o podanej nazwie w trybie do zapisu i zapisz do niego zawartość listy dynamicznej (stan już po usunięciu elementów) w takim samym formacie, jak w pliku wejściowym, tj. każdy wiersz zawiera nr indeksu studenta, nazwisko i ocenę, które rozdzielone są znakiem spacji. Po zakończeniu zapisywania zamknij plik i zakończ działanie programu.

Przygotuj odpowiedni plik tekstowy z prawidłowymi danymi wejściowymi i umieść go we właściwym katalogu. Przygotuj dane w pliku tak, aby:

  1. rekordy reprezentujące studentów z oceną poniżej 4 były przemieszane z rekordami studentów z oceną 4 i wyższą niż 4 i aby znalazły się na początku, w środku i na końcu pliku,
  2. numery studentów w kolejnych wierszach nie były uporządkowane rosnąco.

Wejściówka na lab.6

Napisz program wczytujący z pliku listę rekordów (rekord to kolekcja kilku dowolnych wartości, każda ściśle określonego typu, występujących w ustalonej, zawsze tej samej kolejności). Wczytywane rekordy składają się z trzech wartości. Wartości te są zapisane w jednym wierszu pliku tekstowego; każdy wiersz zawiera kolejno: nr indeksu studenta, nazwisko i ocenę, które rozdzielone są znakiem spacji. Typ danych do przechowywania jednego rekordu ma następującą budowę:

struct student {
	int nr_indeksu;
	char nazwisko[30];
	float ocena;
	struct student *nast;
};

W funkcji main pobierz od użytkownika nazwę pliku z danymi, otwórz ten plik w trybie do odczytu, a następnie wczytaj zawartość pliku do listy dynamicznej jednokierunkowej. W trakcie wczytywania program powinien wypisywać na ekranie aktualnie odczytywane wartości. Po zakończeniu czytania zamknij plik. Przyjmij, że dane w pliku są zawsze poprawne, tj. wiersz zawsze zawiera trójkę prawidłowych napisów w tej samej kolejności.
Po odczytaniu wypisz w oknie konsoli elementy reprezentujące studentów, którzy mają ocenę niższą niż 4.
Następnie pobierz od użytkownika nazwę pliku do zapisu, otwórz plik o podanej nazwie w trybie do zapisu i zapisz do niego zawartość listy. Po zakończeniu zapisywania zamknij plik i zakończ działanie programu.
Przygotuj odpowiedni plik tekstowy z prawidłowymi danymi wejściowymi i umieść go we właściwym katalogu. Przygotuj dane w pliku tak, aby rekordy reprezentujące studentów z oceną poniżej 4 były przemieszane z rekordami studentów z oceną 4 i wyższą niż 4 i aby znalazły się na początku, w środku i na końcu pliku.
Do obsługi plików wykorzystaj funkcje fopen, fclose, fprintf, fscanf i feof. Wszystkie z biblioteki: stdio.h.

Zwracam uwagę na obowiązek zatwierdzenia oddawanej wejściówki poprzez kliknięcie na przycisk „do oceny”, o którym pisałem w moim poprzednim wpisie dostępnym tutaj.