Gdańsk, 8.10.1996
JĘZYKI OBIEKTOWE - ZADANIA
Napisz program zawierający funkcję, która oblicza iloczyn skalarny dwóch n-elementowych wektorów v1 i v2. Funkcja powinna mieć następujący prototyp:
float ilska(float v1[], float v2[], int n);
Napisz program, który oblicza n-tą liczbę ciągu Fibonacci, zadanego formułami:
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2) dla n > 1
Napisz program `echo', który jedynie drukuje swoje argumenty, podane w wierszu rozkazowym. Np. `echo hello cruel > world' zapisze frazę „hello cruel” do pliku `world'.
Napisz program interakcyjny, który czyta z klawiatury rok i podaje, czy dany rok jest przestępny. Wskazówka: Lata po roku 1582 podzielne przez 4 są latami przestępnymi, za wyjątkiem tych, które są podzielne przez 100; jednak te, które są podzielne przez 400, są również latami przestępnymi.
Napisz program interakcyjny, który żąda od użytkownika wprowadzenia łańcucha znaków, a następnie wyświetla jego długość.
Funkcja biblioteczna char* strchr(const char* s, int c) szuka w łańcuchu s pierwszego wystąpienia znaku c. Jeśli przeszukiwanie zakończy się sukcesem, funkcja zwraca wskaźnik do znalezionego znaku; w przeciwnym przypadku funkcja zwraca wskaźnik zerowy. Napisz własną definicję takiej funkcji.
Jeden łańcuch jest podłańcuchem drugiego łańcucha, jeśli jest dopasowany do sekwencji kolejnych znaków drugiego łańcucha. Terminalne znaki zerowe łańcuchów nie są włączane do badania dopasowania. Funkcja biblioteczna char* strstr(const char* s1, const char* s2) szuka pierwszego wystąpienia łańcucha s2 jako podłańcucha s1. Jeśli przeszukiwanie zakończy się sukcesem, funkcja zwraca wskaźnik do pierwszego znaku dopasowanej sekwencji; w przeciwnym przypadku funkcja zwraca wskaźnik zerowy. Tak więc np. wywołanie strstr(*concatenate*, *ate*) zwraca wskaźnik do pierwszego znaku `a' (nie do drugiego) sekwencji *concatenate*, zaś wywołanie strstr(*concatenate*, *eat*) zwraca wskaźnik zerowy. Napisz własną definicję takiej funkcji.
Napisz program zawierający dwuargumentową funkcję reverse(). Pierwszy argument, str, wskazuje na odwracany łańcuch; drugi, count, zawiera liczbę odwracanych znaków. Nadaj parametrowi count wartość domyślną, która mówi funkcji reverse(), że ma odwrócić cały łańcuch.
*Funkcja strcat() z biblioteki ANSI C dołącza łańcuch wskazywany przez jej drugi argument na końcu łańcucha, wskazywanego przez jej pierwszy argument. Dla wykonania tego zadania strcat() musi znaleźć zerowy terminator na końcu pierwszego argumentu. Zaprojektuj klasę String tak, aby definicje jej funkcji składowych pozwoliły uniknąć tego przeszukiwania.
Napisz program, który kopiuje plik tekstowy i wyświetla liczbę skopiowanych znaków. Sprawdź, czy podana przez program liczba znaków jest równa liczbie, wyświetlanej przez polecenie „ls -l” systemu Unix.
Napisz program, który tworzy plik tekstowy, a następnie wyświetla znaki tego pliku w odwrotnej kolejności.
Napisz program, który tworzy plik tekstowy, a następnie zamienia miejscami każdą parę znaków w tym pliku, np. abcd -> badc.
Napisz program, który kopiuje plik tekstowy, zamieniając w trakcie kopiowania małe litery na duże i odwrotnie.
Napisz program, który tworzy plik wyjściowy „TEST”, wpisuje do niego tekst „Hello” i dwie liczby: dec 100 i hex 100. Po zamknięciu pliku program otwiera go jako plik wejściowy i odczytuje informację.
Napisz program, który czyta tekst programu C++ utrzymywanego w pliku, którego nazwa jest podawana w wierszu rozkazowym. Program powinien drukować na standardowym wyjściu wszystkie zawarte w odczytanym tekście komentarze z `//' i `/*...*/'. Uwaga: Strzeż się łańcuchów *...*.
Napisz program, który tworzy dwywymiarową tablicę 10 punktów równoodległych wzdłuż osi x. Wydrukuj zawartość tablicy. Następnie przesuń każdy element tablicy przez dodanie do jej współrzędnej y liczby, równej jej współrzędnej x i ponownie wydrukuj zawartość tablicy.
Utwórz klasę Line, która kreśli znakiem ASCII odcinek linii na ekranie. Umieść długość odcinka w prywatnej zmiennej o nazwie len. Konstruktor klasy Line powinien przyjmować jako parametr długość odcinka linii. Destruktor powinien wymazywać odcinek.
Zdefiniuj klasę Dice (kostka do gry) z jedną prywatną zmienną całkowitą, która przechowuje liczby od 1 do 6. Utwórz funkcję roll(), która korzysta ze standardowego generatora liczb pseudolosowych rand() dla generacji liczb od 1 do 6 o rozkładzie równomiernym. Funkcja roll() powinna wyświetlać te liczby.
Dla klasy Letters
{ public: letters(char c): ch(c) {} char get_ch() {return ch; } private: char ch; };
utwórz 10-elementową tablicę obiektów i zainicjuj w nich element ch wartościami od `A' do `J'. Pokaż, że tablica faktycznie zawiera te wartości.
Zdefiniuj klasę Numbers i jej klasy pochodne: Integer, LongInt i DecFloat. Zdefiniuj funkcję abs() i przeciąż ją tak, aby obliczała wartość bezwzględną odpowiednio typu int, long int i float. (Będą to odpowiedniki funkcji abs(), labs() i fabs() języka C).
*Zdefiniuj klasę Numbers i jej klasy pochodne. Dla klasy pochodnej Zespolone zdefiniuj cztery operacje arytmetyczne, wykorzystując:
(a) Definicje funkcji sum(), subtract(), multiply() i divide().
(b) Przeciążenie operatorów „+”, „-”, „*” i „/”.
*Zaprojektuj i zdefiniuj klasy dla jednokierunkowej listy cyklicznej, np.
Włącz w klasę własny iterator (zbiór funkcji, które pozwalają przemieszczać się krok po kroku po przechowywanych w liście wartościach), dający możliwość dostępu do pozycji listy, następujących po pozycji bieżącej.
*Zaprojektuj i zdefiniuj klasy dla dwukierunkowej listy cyklicznej, np.
Włącz w klasę własny iterator (zbiór funkcji, które pozwalają przemieszczać się krok po kroku po przechowywanych w liście wartościach), dający możliwość dostępu do pozycji listy, poprzedzających i następujących po pozycji bieżącej.
*Załóżmy, że programista P jest członkiem zespołu 10 osób piszących program interakcyjny. Pozostałe 9 osób piszą podsystemy, które implementują różne polecenia. Programista P jest odpowiedzialny za całą interakcję z użytkownikiem programu, włącznie z konstrukcją menu poleceń i wywołaniami poleceń, które zostały wybrane z menu. Ponieważ zbiór poleceń często się zmienia, programista P chciałby uniknąć konieczności rekompilacji swojej części programu, gdy polecenia są dodawane lub usuwane. Napisz klasę Polecenie (Command) tak, aby podsystem mógł dostarczyć polecenie przez utworzenie obiektu statycznego klasy Polecenie. Każdy obiekt klasy Polecenie powinien być inicjowany przez const char*, dając nazwę poleceniu i wskaźnik do funkcji bezargumentowej, która ma być wykonana. Wskazówka: Korzystaj z konstruktorów statycznych (konstruktory dla obiektów ze statycznym czasem życia) do zbudowania listy poleceń, używając niezainicjowanego statycznego obiektu wskaźnikowego na początku listy.
*Dla dokładnego zilustrowania konstrukcji kopii obiektu przy wejściu i jej destrukcji przy wyjściu z funkcji utwórz klasę Who (który). Konstruktor klasy Who powinien mieć jeden argument znakowy, który należy wykorzystać do identyfikacji obiektu i wyświetlenia komunikatu
Constructing Who #x
gdzie x jest znakiem identyfikującym dany obiekt. Przy destrukcji obiektu powinien być wyświetlony komunikat:
Destructing Who #x
gdzie - jak poprzednio, x identyfikuje obiekt. Klasa Who powinna zawierać funkcję make_who(), której wynikiem jest obiekt klasy Who. Nadaj każdemu obiektowi unikatową nazwę. Skomentuj wyświetlane komunikaty.
*Podaj praktyczny przykład, w którym reguła, mówiąca że obiekty tymczasowe są traktowane jako obiekty stałe (const), pozwala kompilatorowi C++ wykryć „oczywisty” błąd programistyczny.
*Zdefiniuj klasę set, której obiekty są zbiorami liczb całkowitych. Zbiór jest kolekcją wartości bez relacji porządku, przy czym wartości nie mogą się powtarzać. Klasa set ma następujące funkcje składowe:
set(int sz = 4); ~set(); void insert(int v); int member(int v); void remove(int v);
*Konstruktor tworzy zbiór pusty, który może maksymalnie zawierać sz wartości. Wielkość zbioru może rosnąć w miarę wstawiania dodatkowych danych. Funkcja insert() wstawia wartość v, jeśli jeszcze nie jest ona elementem zbioru. Funkcja remove() usuwa wartość v, jeśli wartość ta należy do zbioru. Funkcja member() zwraca 1 (true), jeśli v należy do zbioru, a wartość 0 (false), jeśli v nie należy do zbioru. Dodaj do klasy set iterator (zbiór funkcji, które pozwalają przemieszczać się krok po kroku po przechowywanych w zbiorze wartościach w pewien sposób, np. w kolejności, w której wartości są przechowywane w pamięci).
*Dla schematu dziedziczenia:
class A { /*...*/ };
class B: virtual public A { /*...*/ };
class C: virtual public A { /*...*/ };
class Z: public A { /*...*/ };
class MA: public B, public C, public Z { /*...*/ };
sprawdź jednoznaczność odwołań do elementów klasy bazowej A. W przypadku stwierdzenia niejednoznaczności zmodyfikuj definicje. Wypróbuj także zastosowanie operatora zasięgu „::”.
Dla szablonu
template <class T>
T max(T a, T b) { return a > b ? a : b; }
napisz program, który drukuje największy element tablicy:
(a) o elementach typu int
(b) o elementach typu char.
*Dla szablonu
template <class T>
T max(const T* array, int size) { /*...*/ }
napisz program, który znajduje (i drukuje) wartość maksymalnego elementu w tablicy.