ansi C

Celem zajęć jest zapoznanie studentów z językiem programowania C.

literatura

Literatura papierowa:

  • B.W.Kernighan, D.M.Ritchie: Język ANSI C. WNT, Warszawa 1994.

Literatura elektroniczna:

terminy
  • wykład: poniedziałek 14-16 s.25 (M.Piotrów)
  • laboratorium: środa 18-20 s.110

powrót na początek strony


Laboratorium

zasady zaliczenia przedmiotu
ogólnie:
W semestrze będzie opublikowanych (na tej stronie) 12 list z zadaniami i projekt. Zadania będą publikowane w internecie na kwadrans przed rozpoczęciem zajęć. Za każde poprawnie zaprogramowane zadanie będzie można otrzymać do 5 punktów. Na trzech ostatnich zajęciach trzeba będzie zrealizować indywidualnie przydzielony projekt, za który można będzie dostać do 20 punktów. Dodatkowe 20 punktów będzie można uzyskać z kolokwium przeprowadzonego w trakcie wykładu pod koniec semestru. W czasie semestru można więc zebrać do 100 punktów.
obecności:
Zadania do zaprogramowania będą ogłaszane tuż przed zajęciami, dlatego obecność na zajęciach jest obowiązkowa.
prezentacje:
Zadania należy realizować i prezentować w czasie trwania pracowni. Kto nie zdąży, może zaprogramować zadanie w domu i pokazać je w następnym tygodniu na początku zajęć. Za zadanie zrobione na pracowni można dostać do 5 punktów, a za zadanie spóżnione o tydzień do 3 punktów (spóźnienia ponad tygodniowe nie będą w ogóle punktowane). W trakcie prezentacji programu trzeba się liczyć z pytamiami dotyczącymi zadania: metoda rozwiązania, zastosowane konstrukcje językowe, itp.
oceny:
Aby zaliczyć laboratorium na ocenę dostateczną trzeba do końca semestru zdobyć 50 punktów; na ocenę bardzo dobra trzba będzie zgromadzić 90 punktów; oceny pośrednie pozostają w liniowej zależności od przedstawionych wymagań granicznych.
listy zadań
4 października 2006 (lista 1):
  1. Napisz program, który wczytuje liczbę rzeczywistą oznaczającą prędkość pojazdu liczoną w km/h. Oblicz i wypisz, ile wynosi ta prędkość liczona w mi/h i m/s.
    Uwaga: 1[km]=0.621371[mi].
  2. Napisz program, który wczytuje liczbę całkowitą i sprawdza, czy jest to liczba pierwsza.
11 października 2006 (lista 2):
  1. Napisz program, który wczytuje długość ciągu, a później ciąg liczb całkowitych. Określ jaka jest w tym ciągu wartość najmniejsza i największa.
    Uwaga: Program nie powinien spamiętywać wczytywanych danych.
  2. Napisz program, który wczytuje dwie liczby naturalne i wypisuje ich największy wspólny dzielnik i najmniejszą wspólną wielokrotność.
18 października 2006 (lista 3):
  1. Napisz program, który przepisze tekst ze standardowego wejścia na standardowe wyjście, i który w trakcie działania przytnie długie linie do 63 znaków.
    Uwaga: Skorzystaj z funkcji fgets().
  2. Napisz program, który wczytuje ze standardowego wejścia kolejne znaki, aż do napotkania symbolu EOF. Na końcu program powinien wypisać na standardowym wyjściu dla błędów statystykę dotycząca wczytanego tekstu: ile było wszystkich przeczytanych znaków, ile było białych znaków, z ilu linii składał się tekst oraz jaka była długość najdłuższego wiersza.
    Uwaga: Program powinien czytać znak po znaku funkcją getchar().
  3. Napisz program, który sprawdzi czy podane przez użytkownika argumenty wywołania programu są nieujemnymi całkowitymi liczbami dziesiętnymi. Dla każdego argumentu który jest liczbą, program powinien wypisać ile bitów jest potrzebnych do jej zapamiętania w systemie dwójkowym.
    Uwaga: Podane liczby mogą być bardzo długie, nie mieszczące się w zakresie żadnego standardowego typu całkowitoliczbowego.
25 października 2006 (lista 4):
  1. Zaprogramuj prosty kalkulator. Ma on działać w pętli: najpierw wczytuje liczbę rzeczywistą, potem symbol działania arytmetycznego, i znowu liczbę a potem znowu symbol działania, itd. Program ma działać w pętli, wyliczając na bieżąco wyniki operacji arytmetycznych, aż do wczytania symbolu równości (=).
    Uwaga: Dopuszczalne operacje arytmetyczne to: dodawanie (+), odejmowanie (-), mnożenie (*) i dzielenie (/).
    Uwaga: Program należy zabezpieczyć przed wczytaniem błędnych danych.
  2. Napisz program, który wywołany z dwoma parametrami r (liczba rzeczywista r≥0) i k (liczba naturalna k<100) wyliczy i stablicuje wartości pi dla i=0...k-1 określone następującym wzorem rekurencyjnym:
          p0 = 1
          pi = (r/pi-1+pi-1)/2 : i>0
    Na koniec program ma wypisać w dwóch kolumnach następujące wyniki: w pierwszej kolumnie wartości pi a w drugiej różnicę pomiędzy pi a pierwiastkiem kwadratowym z r (użyj funkcji sqrt z biblioteki matematycznej).
    Uwaga: Program należy zabezpieczyć przed podaniem błędnych danych.
8 listopada 2006 (lista 5):
  1. Napisz program, który wczytuje liczbę całkowitą reprezentującą rok. Program ma sprawdzić, czy podany rok jest przestępny i wypisać odpowiedni komunikat. Do testowania przestępności roku użyj funkcji czyPrzestepny(int), która zwraca 1 gdy rok jest przestępny, albo 0 w przeciwnym przypadku.
  2. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje dwie liczby całkowite reprezentujące odpowiednio miesiąc i rok. Program ma sprawdzić, ile dni ma zadany miesiąc (luty ma różną liczbę dni w zależności od roku). Skorzystaj z dwuwymiarowej tablicy dniWMiesiacu, w której są zapisane liczby dni w poszczególnych miesiącach, osobno dla lat zwykłych i przestępnych. Do tablicy tej powinieneś się odwoływać w nastepujacy sposób: dniWMiesiacu[czyPrzestepny(rok)][mies].
  3. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje trzy liczby całkowite reprezentujące odpowiednio dzień, miesiąc i rok. Program ma wyliczyć, ile dni upłynęło do zadanego dnia od początku roku, oraz ile dni zostało jeszcze do jego końca włącznie z tym dniem. Skorzystaj z pomocniczej tablicy dwuwymiarowej dniOdPoczRoku, która będzie zawierała informacje o liczbie dni od poczatku roku do końca poprzedniego miesiąca minus jeden dzień. Obie wartości będziesz mógł wtedy bardzo prosto wyliczyć. Przykładowo, dystans czasowy od początku roku do 1 stycznia wynosi 0 dni, a od 1 grudnia do końca roku 31 dni.
  4. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje trzy liczby całkowite reprezentujące odpowiednio dzień, miesiąc i rok. Program ma sprawdzić czy podana data jest prawidłowa (miesiąc z zakresu 1...12, dzień 1...). Weź też pod uwagę fakt, że kalendarz Gregoriański obowiązuje od 15 października 1582. W swoim programie koniecznie zaimplementuj funkcję porownanieDat(int,int,int,int,int,int) porównującą dwie daty, która będzie odpowiadać wartością -1 gdy pierwsza data jest późniejsza niż druga, 0 gdy daty są takie same, 1 gdy pierwsza data jest wcześniejsza niż druga.
  5. (kontynuacja poprzedniego zadania)
    Napisz program, który dwukrotnie wczytuje trzy liczby całkowite reprezentujące odpowiednio dzień, miesiąc i rok (wczytujemy dwie daty). Program ma sprawdzić, czy podane daty są poprawne, a potem wyliczyć, ile dni upłynęło od pierwszej daty do drugiej. Liczba tych dni ma wynieść 0 gdy obie daty są takie same, a w przypadku gdy pierwsza data jest późniejsza niż druga program powinien wypisać liczbę ujemną.
15 listopada 2006 (lista 6):
  1. Dość często potrzebujemy ustawiać lub sprawdzać wartości pojedynczych bitów w słowie typu int lub unsigned int. Zdefiniuj dwie funkcje: jedną do odczytywania wartości określonego bitu (funkcja ma zwracać wartość 0 lub 1), a drugą do ustawiania wartości określonego bitu (funkcja ma ustawić bit na 1 tylko wtedy gdy parametr ma wartość różną od 0):
          int jakiBit (unsigned &komorka, int nrBitu);
          void ustawBit (unsigned &komorka, int nrBitu, int wartosc);
    Przy programowaniu tych funkcji skorzystaj z operatorów bitowych. Następnie napisz krótki program testowy, sprawdzający ich poprawne działanie (numer bitu to wartość z zakresu od 0 do (sizeof(unsigned)<<3)-1).
  2. (kontynuacja poprzedniego zadania)
    Zaprogramuj analogiczne funkcje działające na całych tablicach:
          int jakiBit (unsigned *tablica, int nrBitu);
          void ustawBit (unsigned *tablica, int nrBitu, int wartosc);
    Przy programowaniu tych funkcji skorzystaj z poprzednio zdefiniowanych procedur. Następnie napisz krótki program testowy, sprawdzający ich poprawne działanie (numer bitu to nieujemna liczba całkowita).
  3. (kontynuacja poprzedniego zadania)
    Zadeklaruj globalną tablicę unsigned sito[] o najmniejszym możliwym rozmiarze, która będzie zawierała co najmniej MAX_BIT bitów (wartość MAX_BIT zdefiniuj dyrektywą #define dla preprocesora, na przykład jako 221). Zaprogramuj dodatkową funkcję, która wypełni tą tablicę wartościami 1 tylko na tych pozycjach, które odpowiadają liczbom pierwszym (na i-tej pozycji znajduje się 1 tylko wtedy, gdy liczba i jest pierwsza):
          void sitoEratostenesa ();
    Popraw funkcje jakiBit() i ustawBit(), tak aby sprawdzały one wartość parametru nrBitu (dla wartości <0 lub ≥MAX_BIT funkcja jakiBit() zawsze zwraca 0 a funkcja ustawBit() nie robi nic).
    Napisz też funkcję, która dla zadanej liczby całkowitej sprawdzi, czy jest ona pierwsza (zwracana wartość to 1) czy nie (zwracana wartość to 0); twoja funkcja powinna poprawnie odpowiadać dla wszystkich wartości typu int, również dla liczb <0 i ≥MAX_BIT.
          int czyPierwsza (int liczba);
    Następnie napisz krótki program testowy, wypisujący wszystkie liczby pierwsze niewiększe od zadanej liczby wczytanej ze standardowego wejścia. Komunikaty zachęcające do wpisywania danych należy kierować na standardowe wyjście dla błędów.
  4. (kontynuacja poprzedniego zadania)
    Podziel poprzednie zadanie na pięć części: plik nagłówkowy z deklaracjami funkcji do odczytywania i ustawiania bitów, plik nagłówkowy z deklaracją funkcji do inicjalizacji sita Eratostenesa i z deklaracją funkcji do testowania pierwszości liczby (pliki nagłówkowe powinny posiadać dyrektywy włączania warunkowego #ifndef i #endif dla preprocesora), pliki źródłowe z implementacjami funkcji z odpowiednich plików nagłówkowych (zadeklaruj w jednym statyczną tablicę bitową z sitem Eratostenesa) a także plik źródłowy z funkcją main(), która w pętli będzie wczytywała liczbę całkowitą i wypisywała komunikat o jej pierwszości.
29 listopada 2006 (lista 7):
  1. Zaprojektuj strukturę węzła w drzewie binarnych poszukiwań; w węźle będziemy pamiętać napisy (tablice znaków) o różnej długości. Zdefiniuj parę funkcji, która będzie odpowiedzialna za utworzenie nowego węzła w pamięci wolnej i rekurencyjne usunięcie go wraz z całym poddrzewem (napis pamiętany w węźle także ma być przechowywany w pamięci wolnej).
          Wezel * utworz (char *nap);
          void usun (Wezel *wezel);
    Następnie dopisz rekurencyjne funkcje do wstawiania nowej wartości (napisu) do węzła i sprawdzania czy zadana wartość (napis) jest w tym drzewie pamiętana.
          Wezel * wstaw (char *nap);
          Wezel * szukaj (char *nap);
    Podziel to zadanie na plik nagłówkowy i plik źródłowy.
  2. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje ze standardowego wejścia wiersz po wierszu, aż do napotkania symbolu EOF. Wczytane wiersze program ma umieszczać w drzewie binarnych poszukiwań zdefiniowanym w porzednim zadaniu. Następnie program powinien wypisać wszystkie przeczytane wiersze w porządku inorder na standardowe wyjście a na końcu usunąć całe drzewo.
          void inorder (Wezel *wezel, FILE *wy);
    Procedura wypisująca zawartość drzewa powinna być rekurencyjna.
  3. (kontynuacja poprzedniego zadania)
    Poprzednie zadanie należy uzupełnić procedurami, które policzą wysokość drzewa i liczbę liści w drzewie. Po wczytaniu danych należy te informacje wypisać na standardowym wyjściu dla błędów (przed usunięciem drzewa).
          int wysokosc (Wezel *wezel);
          int liscie (Wezel *wezel);
    Procedury te także mają być rekurencyjne.
6 grudnia 2006 (lista 8):
  1. Napisz program, który wczyta nazwę pliku tekstowego, a następnie wypisze jego zawartość, o ile plik istnieje, na standardowym wyjściu. Plik należy napierw otworzyć do czytania, potem przeczytać go linia po linii, a na końcu zamknąć. Jeśli linia jest dłuższa niż 79 znaków, to pozostałe znaki w tej linii należy zignorować.
  2. W tekstowym pliku z danymi jest zapisanych N liczb rzeczywistych a1, ..., aN. Format pliku z danymi jest taki, że w pierwszej linii jest zapisana liczba całkowita N typu int, a w kolejnych liniach pooddzielane białymi znakami wartości rzeczywiste a1, ..., aN typu double. Należy te liczby odczytać, zapamiętując je równocześnie w dynamicznie przydzielonej tablicy. Na koniec trzeba je zapisać do pliku binarnego (bez wartości N na początku) i zwolnić przydzieloną pamięć.
  3. (kontynuacja poprzedniego zadania)
    W binarnym pliku z danymi jest zapisane są liczby typu double. Określ ile tych liczb jest zapisanych w pliku, przydziel dynamicznie odpowiedni obszar pamięci i wczytaj je tam. Następnie policz średnią arytmetyczną i odchylenie standardowe i wypisz te wielkości na standardowym wyjściu. Na końcu zwolnij przydzieloną pamięć.
13 grudnia 2006 (lista 9):
  1. Napisz program, który przekopiuje zawartość jednego pliku do drugiego. Nazwy plików mają być podawane jako argumenty wywołania programu. Jeżeli plik docelowy już istnieje, program powinien się zapytać użytkownika, czy chce zastąpić plik, dołączyć pierwszy do drugiego, zmienić nazwę drugiego, czy też zrezygnować.
    Uwaga: Sprawdź, czy program wywołano z prawidłową liczbą argumentów, oraz czy podane nazwy są poprawnymi nazwami plików i czy pierwszy z nich istnieje w lokalnym systemie.
  2. Napisz program, który porówna ze sobą zawartości dwóch plików z dokładnością do białych znaków w obrębie linii. Nazwy plików mają być podawane jako argumenty wywołania programu. Po napotkaniu pierwszej różnicy program powinien wypisać numer wiersza i numer pozycji w wierszu, w którym występuje różnica, po czym przerwać dalsze porównywanie.
    Uwaga: Sprawdź, czy program wywołano z prawidłową liczbą argumentów, oraz czy podane nazwy są nazwami istniejących plików w lokalnym systemie.
20 grudnia 2006 (lista 10):
  1. Napisz program, który (de)szyfruje podany w linii poleceń plik. Kluczem powinno być jedno słowo podawane jako drugi argument wywołania programu. Szyfrowanie powinno cyklicznie "przykładać" klucz do pliku i odpowiednio modyfikować jego zawartość. Na parach kolejnych znaków pliku i klucza wykonuj operację XOR (^); kiedy zabraknie liter klucza, należy zacząć ponownie od jego początku. Metodę szyfrowania tekstu zadanym kluczem zaprogramuj koniecznie jako oddzielną funkcję (zadeklarowaną w pliku nagłówkowym).
    Wskazówka: Sprawdź, czy program wywołano z prawidłową liczbą argumentów, oraz czy podana nazwa pliku jest nazwą istniejącego pliku w lokalnym systemie.
  2. Napisz program do mnożenia macierzy. Program najpierw wczytuje liczbę wierszy i liczbę kolumn macierzy A, alokuje pamięć na tę macierz i wczytuje kolejno jej elementy. Potem ten sam proces czytania powtarza dla macierzy B. Zauważ, że liczba kolumn w macierzy A musi być taka sama jak liczba wierszy w macierzy B. Następnie program powinien obliczyć iloczyn tych macierzy i zapamiętać go w dynamicznie przydzielonej pamięci. Na końcu wypisz wynik na standardowe wyjście.
    Wskazówka: Macierz powinna być pamiętana w tablicy tablic (pierwsza tablica zawiera wskaźniki tablic jednowymiarowych).
    Uwaga: Przygotuj poprawne dane w pliku tekstowym i uruchom program podając mu nazwę tego pliku.
projekt

Przydział zadań projektowych: (html)

ranking

Punktacja z laboratoriów: (html)

powrót na początek strony


Ogłoszenia

21.12.2006
Zostały przydzielone indywidualne projekty. Termin ich realizacji mija 17 stycznia 2006 r.
10.10.2006
Pierwszy ranking ukaże się na początku listopada 2006 r.

powrót na początek strony