Wersja podstawowa

Transkrypt

Wersja podstawowa
Wersja podstawowa
Utworzyć cztery pliki: lista.h, lista.c, main.c oraz Makefile. W pliku lista.h
zadeklarować strukturę, która będzie przechowywać wskaźnik na tablicę int zaalokowaną za
pomocą instrukcji malloc, długość a tej tablicy, oraz liczbę n elementów listy (n może być
mniejsze od a, bo oznacza ilość używanych elementów T, w odróżnieniu od a, które oznacza ilość
wszystkich elementów).
struct lista { int *T; int n, a; };
oraz cztery funkcje
struct lista *
void
void
void
int
l_new(int); l_old(struct lista *); l_println(struct lista *); l_push(struct lista *, int);
l_pull(struct lista *);
Plik lista.c powinien zaczynać się linijkami
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include "lista.h"
Dalej powinna znajdować się definicja funkcji l_new, która tworzy listę o podanej pojemności
początkowej i zwraca wskaźnik do niej:
struct lista * l_new(int ini) { struct lista *L; assert(ini > 0); L = malloc(sizeof *L); L­>n = 0; L­>a = ini; L­>T = malloc(L­>a * sizeof L­>T[0]); return L; }
(wywołanie funkcji assert też musi się tam znaleźć. Należy się tą funkcją zapoznać i wiedzieć,
co robi w tym konkretnym przypadku).
Funkcja l_old powinna uwalniać (za pomocą free) pamięć zajmowaną przez tablicę T oraz
przez daną strukturę:
void l_old(struct lista *L) { free(L­>T); free(L); }
Funkcja l_push powinna dopisywać na końcu listy podaną liczbę, poprzez (1) sprawdzenie, czy
T jest wystarczająco duże, żeby pomieścić dodatkową wartość i ewentualne powiększenie T z
zachowaniem zawartości, następnie (2) dopisanie danej liczby na koniec T i uaktualnienie pola n
w strukturze.
Funkcja l_pull, gdy argumentem jest niepusta lista, powinna zdejmować (czyli skracać listę o
jeden) i zwracać ostatni element tej listy. Gdy argumentem jest lista pusta, l_pull powinna
pozostawić ją (listę) bez zmian i zwrócić zero.
Funkcja l_println powinna drukować zawartość danej listy na standardowym wyjściu,
rozdzieloną przecinkami, zamkniętą w nawiasy kwadratowe i zakończoną znakiem nowej linii, tak
żeby sekwencja wywołań
l_push(L, 5);
l_push(L, 1);
l_push(L, 2);
l_println(L);
l_push(L, 1);
l_println(L);
printf(“%d, “, l_pull(L));
l_println(L);
spowodowała wypisanie
[5, 1, 2]
[5, 1, 2, 1]
1, [5, 1, 2]
Zawartość pliku Makefile ma być następująca
debug: gcc ­Wall ­g lista.c main.c ­omain przy czym wywołanie gcc musi być oddzielone od lewej krawędzi tabulacją (nie spacjami).
Plik main.c powinien wyglądać tak:
#include <stdio.h> #include "lista.h" int main(void) { struct lista *L; L = l_new(1); #error uzupelnic
l_old(L); return 0; }
przy czym linijka #error uzupelnic powinna zawierać sekwencję działań na liście L, która
(sekwencja) pozwoli przetestować poprawność napisanych funkcji. Należy też zapoznać się z
dyrektywami #error i #warning.
Wersja czwórkowa
Do zbioru funkcji działających na listach dodać funkcje
int
struct lista *
int
int
int
l_at(const struct lista *, int);
l_newstr(const char *); l_max(const struct lista *);
l_min(const struct lista *);
l_suma(const struct lista *);
Funkcja l_at powinna zwracać (nie usuwając z listy) element o podanym indeksie. Jeśli indeks
jest ujemny, powinien być zinterpretowany jako liczony od końca, np. wywołanie l_at(L, ­1) powinno zwrócić element ostatni, a wywołanie l_at(L, ­2) przedostatni. W przypadku
podania indeksu spoza zakresu, funkcja l_at powinna zwracać zero.
Zwrócić uwagę na modyfikator const w powyższej deklaracji. W wersji czwórkowej należy
dopisać go do deklaracji i definicji wszystkich funkcji które nie powodują zmiany zawartości listy.
Funkcja l_newstr powinna tworzyć nową listę o zawartości podanej w formie napisu, na
przykład l_newstr(“1 3 3 7”) tworzy listę o elementach 1, 3, 3, 7. Wszystkie znaki z
wyjątkiem cyfr i minusa powinny być traktowane jako separatory, np.
l_newstr(“[1,3,3,7]”)
również powinno tworzyć listę o zawartości 1, 3, 3, 7, podobnie jak
l_newstr(“[1,3,...,3,7]”)
oraz
l_newstr(“|1?|3|3*|*7”)
Pomocna będzie funkcja strtol z nagłówka <stdlib.h> lub funkcja strtok z nagłówka
<string.h>.
Funkcje l_max i l_min znajdują największy i najmniejszy element listy. W przypadku listy
pustej jako argumentu, l_max i l_min powinny zwracać odpowiednio INT_MIN i INT_MAX
(zdefiniowane w nagłówku <limits.h>).
Funkcja l_suma powinna zwracać sumę (arytmetyczną) elementów. Suma elementów pustej listy
to zero.
Wersja piątkowa
Wszystko to, co w wersji czwórkowej. Ponadto do zbioru funkcji należy dodać funkcje
int
void
l_podzb(const struct lista *, const struct lista *);
l_sort(struct lista *);
Funkcja l_podzb sprawdza, czy lista podana jako pierwszy argument jest podlistą listy podanej
jako drugi argument. Na przykład [3, 1, 2] jest podlistą listy [1, 2, 1, 5, 3], ale [1, 2, 1] nie jest podlistą listy [1, 2, 3].
Funkcja l_sort sortuje zawartość listy. Metoda sortowania dowolna, kierunek (rosnący /
malejący) też (dowolny, w sensie zawsze malejący, albo zawsze rosnący).

Podobne dokumenty