ANSI C

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

literatura

Literatura papierowa:

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

Literatura elektroniczna:

terminy
  • wykład: wtorek 16-18 s.25 (M.Piotrów)
  • laboratorium:
    środa 16-18 s.108
    czwartek 14-16 s.110
ogłoszenia
14.12.2007
Zadania z listy 10 będą opublikowane wcześniej (w piątek o 16:15). Proszę więc solidnie przygotować się na ostatnie tym roku laboratorium.
13.12.2007
Zadanie 3 i 4 z listy 9 będzie można oddawać z tygodniowym opóźnieniem za całą liczbę punktów.
6.12.2007
Zadanie 3 i 4 z listy 8 będzie można oddawać z tygodniowym opóźnieniem za całą liczbę punktów.
29.11.2007
Zadanie 2 i 4 z listy 7 będzie można oddawać z tygodniowym opóźnieniem za całą liczbę punktów.
28.11.2007
Zadania z list 6-9 będzie można oddawać z tygodniowym opóźnieniem za połowę punktów.
22.11.2007
Zadania z listy 6 można dokończyć w domu i oddać w terminie następnej pracowni za połowę punktów.
2.11.2007
Pierwszy ranking w moich grupach już jest zrobiony.
2.10.2007
Pierwszy ranking ukaże się na początku listopada.

powrót na początek strony


zasady zaliczania przedmiotu
ogólnie:
W semestrze będzie opublikowanych (na tej stronie) 10 list z zadaniami i projekt. Zadania będą publikowane w internecie na kwadrans przed rozpoczęciem zajęć. Za wszystkie poprawnie zaprogramowane zadania będzie można otrzymać do 4 punktów. Na pięciu ostatnich zajęciach trzeba będzie zrealizować indywidualnie przydzielony projekt, za który można będzie dostać do 30 punktów. Kolejne 30 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, nie może już oddawać zadań zrobionych w domu w terminie późniejszym. Za zrobione na pracowni zadanie można dostać od 0 do 1 punkta (ze skokiem co 0.1). 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.
laboratorium 1

Pisanie na standardowym wyjściu i czytanie ze standardowego wejścia.

laboratorium 1 - czwartek,

  1. Dane jest równanie liniowe postaci  ax+b=0 . Napisz program, który wczyta dwie liczby rzeczywiste a≠0 i b będące parametrami tego równania, a następnie wyliczy i wypisze jego rozwiązanie z dokładnością do 3 miejsc po kropce dziesiętnej.
  2. Napisz program, który wydrukuje w sposób estetyczny tabelę z kodami dla znaków ASCII (należy wypisać kod znaku w postaci dziesiętnej i szestnaskowej a potem sam znak). Program powinien wydrukować tabelę tylko dla znaków o kodach od 32 do 126 (19 wierszy po 5 znaków). Znaki należy wydrukować w taki sposób, aby kolejność ich kodów była uporządkowana kolumnami.
    Uwaga: Można założyć że szerokość konsoli to 80 znaków.
  3. Napisz program, który wypisze w słupku kolejne potęgi 2 zaczynając od 20 a kończąc na 230. Cyfry jedności mają się znajdować w tej samej kolumnie dla wszystkich wypisywanych liczb.
  4. 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]. W swoim programie zdefiniuj odpowiednią stałą symboliczną o wartości 0.621371 za pomocą dyrektywy #define i wykorzystaj ją do obliczeń.

laboratorium 1 - środa,

  1. Dany jest trójkąt prostokątny o bokach a, b i c, przy czym c jest krawędzią przeciwprostokątną. Napisz program, który wczyta dwie dodatnie liczby rzeczywiste a i b będące długościami krawędzi przyprostokątnych w tym trójkącie, a następnie wyliczy i wypisze długość krawędzi przeciwprostokątnej z dokładnością do 9 miejsc po kropce dziesiętnej.
  2. Napisz program, który wydrukuje w sposób estetyczny tabliczkę mnożenia dla liczb od 1 do 20. Ponieważ macierz z tabliczką mnożenia jest symetryczna, więc wydrukuj tylko jej górną część.
    Uwaga: Można założyć że szerokość konsoli to 80 znaków.
  3. Napisz program, który wypisze w słupku kolejne potęgi 2 zaczynając od 20 a kończąc na 2-10. Kropki dziesiętne mają się znajdować w tej samej kolumnie dla wszystkich wypisywanych liczb. Nie należy wypisywać nieznaczących zer pojawiających się na końcu liczby.
  4. Napisz program, który wczytuje liczbę rzeczywistą oznaczającą odległość pomiędzy dwoma punktami liczoną w metrach. Oblicz i wypisz, ile wynosi ta odległość liczona w calach i stopach.
    Uwaga: 1[in]=25.3995[mm] oraz 1[ft]=12[in]. W swoim programie zdefiniuj odpowiednie stałe symboliczne o wartościach 0.0253995 i 0.304794 za pomocą dyrektyw #define i wykorzystaj je do bliczeń.
laboratorium 2

Funkcje. Czytanie ze standardowego wejścia ze sprawdzaniem poprawności.

laboratorium 2 - czwartek,

  1. Napisz program, który wczyta liczbę naturalną n a następnie obliczy i wypisze sumę kwadratów 12 + 22 + ... + n2.
    Do wyliczania takiej sumy zdefiniuj oddzielną funkcję. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowego parametru (liczby mniejszej od 1 albo napisu którego nie można przekształcić na liczę).
    Uwaga: Istnieje wzór na sumę kwadratów: 12 + 22 + ... + n2 = (n(n+1)(2n+1)) / 6.
    Wskazówka: Sprawdź w dokumentacji co zwraca funkcja scanf().
  2. Napisz program, który wczyta a≠0, b i c współczynniki równania kwadratowego ax2+bx+c = 0 a następnie obliczy i wypisze ile to równanie ma pierwiastków.
    Do wyliczania liczby pierwiastków równania kwadratowego zdefiniuj oddzielną funkcję. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowych danych.
  3. Zdefiniuj funkcje min() i max(), które wyznaczają odpowiednio element minimalny i maksymalny spośród pary liczb rzeczywistych. Następnie napisz program, który wczyta dwie liczby i wypisze je w kolejności niemalejącej.
    Zabezpiecz się przed wczytaniem nieprawidłowych danych.
  4. Napisz program, który wczyta liczbę naturalną p a następnie sprawdzi czy jest to liczba pierwsza.
    Do testowania pierwszości liczby zdefiniuj osobną funkcję. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowych danych.

laboratorium 2 - środa,

  1. Napisz program, który wczyta liczbę naturalną n a następnie obliczy i wypisze sumę sześcianów 13 + 23 + ... + n3.
    Do wyliczania takiej sumy zdefiniuj oddzielną funkcję. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowego parametru (liczby mniejszej od 1 albo napisu którego nie można przekształcić na liczę).
    Uwaga: Istnieje wzór na sumę sześcianów: 13 + 23 + ... + n3 = (n(n+1))2 / 4.
    Wskazówka: Sprawdź w dokumentacji co zwraca funkcja scanf().
  2. Napisz program, który wczyta trzy liczby całkowite a, b i c a następnie wyznaczy i wypisze wartość środkową (medianę).
    Do wyznaczenia mediany spośród trzech wartości zdefiniuj oddzielną funkcję. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowych danych.
  3. Zdefiniuj funkcje sgn() i abs(), które wyznaczają odpowiednio znak liczby rzeczywistej (wartości -1 dla ujemnych, +1 dla dodatnich i 0 dla zera) i wartość bezwzględną. Następnie napisz program, który wczyta liczbę i wypisze jej znak i wartość bezwlędną.
    Zabezpiecz się przed wczytaniem nieprawidłowych danych.
  4. Napisz program, który wczyta dwie liczby naturalne p i q a następnie wyliczy i wypisze ich najwięszy wspólny dzielnik.
    Do wyliczenia najwięszego wspólnego dzielnika zdefiniuj osobną funkcję, implementującą algorytm Euklidesa. Dodatkowo zabezpiecz się przed wczytaniem nieprawidłowych danych.
laboratorium 3

Pliki nagłówkowe i źródłowe. Funkcje rekurencyjne.

laboratorium 3 - czwartek,

  1. Na poprzednich zajęciach zaprogramowałeś/~aś funkcję do testowania pierwszości dla podanej liczby całkowitej. Teraz Twoje zadanie polega na tym, aby podzielić tamten program na kilka części: plik nagłówkowy z deklaracją funkcji pierwsza(int) testującej pierwszość liczby, plik źródłowy z definicją tej funkcji, oraz plik źródłowy z funkcją główną main().
    Stwórz projekt, który zawiera tylko pliki źródłowe, skompiluj go a potem uruchom program.
  2. Napisz program, który wczyta dwie liczby naturalne p i r a następnie wyliczy i wypisze wartość pr. Do wyliczenia pr zdefiniuj osobną funkcję rekurencyjną, implementującą algorytm szybkiego potęgowania. Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  3. Napisz program, który wczyta liczbę naturalną n a następnie wyliczy i wypisze wartość n!. Do wyliczenia silni n! zdefiniuj osobną funkcję rekurencyjną. Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  4. Napisz program, który wczyta liczbę naturalną n a następnie wyliczy i wypisze wartość n-tego wyrazu w ciągu Fibonacciego Fn. Do wyliczenia n-tego wyrazu w ciągu Fibonacciego zdefiniuj funkcję rekurencyjną zgodnie z wzorem:
    F0 = 0
    F1 = 1
    Fn = Fn-1 + Fn-2 dla n≥2
    Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.

laboratorium 3 - środa,

  1. Na poprzednich zajęciach zaprogramowałeś/~aś funkcję do wyznaczania największego wspólnego podzielnika dla podanej pary liczb całkowitych. Teraz Twoje zadanie polega na tym, aby podzielić tamten program na kilka części: plik nagłówkowy z deklaracją funkcji nwd(int,int) obliczającej największy wspólny dzielnik dla pary liczb, plik źródłowy z definicją tej funkcji, oraz plik źródłowy z funkcją główną main().
    Stwórz projekt, który zawiera tylko pliki źródłowe, skompiluj go a potem uruchom program.
  2. Napisz program, który wczyta dwie liczby naturalne p i r a następnie wyliczy i wypisze wartość pr. Do wyliczenia pr zdefiniuj osobną funkcję rekurencyjną, implementującą algorytm szybkiego potęgowania. Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  3. Napisz program, który wczyta dwie liczby naturalne r i d a następnie wyliczy i wypisze wartość ⌊logp d⌋. Do wyliczenia logarytmu ⌊logp d⌋ zdefiniuj osobną funkcję rekurencyjną. Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  4. Napisz program, który wczyta dwie liczby naturalne n i k a następnie wyliczy i wypisze wartość symbolu Newtona (nk). Do wyliczenia symbolu Newtona zdefiniuj funkcję rekurencyjną zgodnie z wzorem:
    (n0) = (nn) = 1 dla n≥0
    (nk) = (n-1k-1) + (n-1k) dla 0<k<n
    Dodatkowo zabezpiecz program przed podaniem nieprawidłowych danych.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
laboratorium 4

Tablice znaków. Przetwarzanie łańcuchów znakowych.

laboratorium 4 - czwartek,

  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 40 znaków.
    Wskazówka: Skorzystaj z funkcji fgets().
  2. Napisz program, który wczytuje do tablicy znakowej napis ze standardowego wejścia i sprawdza, czy jest on palindromem.
    Uwaga: Twój program nie powinien rozróżniać małych i wielkich liter.
    Uwaga: Wczytany napis ma mieć nie więcej niż 79 znaków.
    Wskazówka: Palindrom to napis, który ma to samo znaczenie niezależnie od tego, czy czytamy go normalnie czy wspak. Przykładowe znane palindromy w języku polskim to: Kajak, Anna, KobyłaMaMałyBok, ZakopaneNaPokaz, MożeJutroTaDamaDaTortuJeżom.
  3. Napisz program, który wczyta pojedyncze słowo do tablicy znakowej i wypisze jego długość. Do policzenia wszystkich znaków w napisie zdefiniuj własną funkcję:
        int str_length (const char *str);
  4. Napisz program, który wczyta ze standardowego wejścia wszystkie 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 oraz ile w tym tekście wystąpiło liter i ile znaków przestankowych (kropek, przecinków, itp).
    Uwaga: Do zliczania znaków przestankowych posłuż się instrukcją wyboru switch.

laboratorium 4 - środa,

  1. Napisz program, który przepisze tekst ze standardowego wejścia na standardowe wyjście z pominięciem linii, które zaczynają się od odstępu (znak spacji lub tabulacji).
    Wskazówka: Skorzystaj z funkcji fgets().
  2. Napisz program, który wczytuje do tablicy znakowej napis ze standardowego wejścia i sprawdza, czy zawiera on dwie takie same litery obok siebie.
    Uwaga: Twój program nie powinien rozróżniać małych i wielkich liter.
    Uwaga: Wczytany napis ma mieć nie więcej niż 79 znaków.
  3. Napisz program, który wczyta pojedyncze słowo do tablicy znakowej i wypisze je wspak. Do przekształcenia napisu zdefiniuj własną funkcję:
        void str_reverse (char *str);
  4. Napisz program, który wczyta ze standardowego wejścia wszystkie 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, z ilu linii składał się tekst oraz ile cyfr wystąpiło w tym tekście.
laboratorium 5

Operatory arytmetyczne i logiczne.

laboratorium 5 - środa,

  1. Napisz program, który wczytuje liczbę całkowitą reprezentującą rok. Program ma sprawdzić, czy podany rok jest przestępny i wypisywać odpowiedni komunikat.
    Uwaga: Do testowania przestępności zdefiniuj osobną funkcję, która zwróci 1 gdy rok jest przestępny albo 0 gdy nie jest przestępny:
        int przestepny (int rok);
  2. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje datę w postaci trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok. Program ma wyliczyć i wypisać, który to jest dzień w roku (licząc od 1 stycznia do podanedo dnia włącznie) oraz ile dni pozostało do Sylwestra (od podanego dnia do 31 grudnia).
    Uwaga: Luty ma różną liczbę dni w zależności od roku. Do obliczeń skorzystaj z dwuwymiarowej tablicy dniWMiesiacu[2][13], w której będą 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]
    Do wyliczenia liczby dni jakie upłynęły od początku roku do zadanego dnia zdefiniuj osobną funkcję:
        int od1stycznia (int dz, int mies, int rok);
  3. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje datę w postaci trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok. Program ma sprawdzić czy podana data jest prawidłowa (miesiąc z zakresu 1...12, dzień z zakresu 1...28/29/30/31). Należy wziąć pod uwagę fakt, że kalendarz Gregoriański obowiązuje od 15 października 1582 roku.
    Uwaga: Do sprawdzenia poprawności daty zdefiniuj osobną funkcję, która odpowie wartością true gdy data jest poprawna albo wartością false w przeciwnym przypadku:
        bool poprawna_data (int dz, int mies, int rok);
  4. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje datę w postaci trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok. Program ma wyliczyć i wypisać ile dni upłynęło od początku obowiązywania kalendarza Gregoriańskiego, czyli od 15 października 1582 roku).
    Uwaga: W swoim programie zaimplementuj funkcję wyliczającą ile dni upłynęło od wirtualnej daty 1 stycznia 1 roku:
        int od1roku (int dz, int mies, int rok);
    Funkcja ta powinna wykonaywać obliczenia bez używania pętli czy rekurencji.

laboratorium 5 - czwartek,

  1. Napisz program, który wczytuje liczbę całkowitą reprezentującą rok. Program ma sprawdzić, czy podany rok jest przestępny i wypisywać odpowiedni komunikat.
    Uwaga: Do testowania przestępności zdefiniuj osobną funkcję, która zwróci 1 gdy rok jest przestępny albo 0 gdy nie jest przestępny:
        int przestepny (int rok);
  2. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje datę w postaci trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok. Program ma wyliczyć i wypisać, który to jest dzień w roku (licząc od 1 stycznia do podanedo dnia włącznie) oraz ile dni pozostało do Sylwestra (od podanego dnia do 31 grudnia).
    Uwaga: Luty ma różną liczbę dni w zależności od roku. Do obliczeń skorzystaj z dwuwymiarowej tablicy dniWMiesiacu[2][13], w której będą 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]
    Do wyliczenia liczby dni jakie upłyną od zadanego dnia do końca roku zdefiniuj osobną funkcję:
        int do31grudnia (int dz, int mies, int rok);
  3. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje datę w postaci trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok. Program ma sprawdzić czy podana data jest prawidłowa (miesiąc z zakresu 1...12, dzień z zakresu 1...28/29/30/31). Należy wziąć pod uwagę fakt, że kalendarz Gregoriański obowiązuje od 15 października 1582 roku.
    Uwaga: Do sprawdzenia poprawności daty zdefiniuj osobną funkcję, która odpowie wartością true gdy data jest poprawna albo wartością false w przeciwnym przypadku:
        bool poprawna_data (int dz, int mies, int rok);
  4. (kontynuacja poprzedniego zadania)
    Napisz program, który wczytuje dwie daty w postaci pary trzech liczb całkowitych reprezentujących kolejno dzień, miesiąc i rok w pierwszej dacie oraz dzień, miesiąc i rok w drugiej dacie. Program ma wyliczyć i wypisać ile dni upłynęło od pierwszej daty do drugiej. Liczba tych dni ma wynieść 0 gdy obie daty są takie same, w przypadku gdy pierwsza data jest późniejsza niż druga program powinien wypisać liczbę ujemną.
    Uwaga: W swoim programie zaimplementuj funkcję wyliczającą ile dni upłynęło od wirtualnej daty 1 stycznia 1 roku:
        int od1roku (int dz, int mies, int rok);
    Funkcja ta powinna wykonaywać obliczenia bez używania pętli czy rekurencji.
laboratorium 6

Tablice i wskaźniki. Alokacja pamięci.

laboratorium 6 - środa,

  1. Napisz program, który wczyta dwie dodatnie liczby całkowite N i Z, a następnie wygeneruje N losowych liczb ze zbioru {0,1,...,Z-1} z rozkładem jednostajnym. Liczby te należy umieścić w dynamicznie przydzielonej tablicy. Program ma wypisać wszystkie wylosowane liczby, potem posortować je korzystając z funkcji standardowej qsort() i na kociec wypisać znowu te liczby w kolejności niemalejącej.
    Uwaga: Do losowania liczb całkowitych z podanego zakresu zdefiniuj osobną funkcję:
        int losuj (int pocz, int kon);
    Uwaga: Twój program powinien na końcu zwolnić przydzieloną pamięć.
  2. Napisz program, który wczyta dodatnią liczbę całkowitą N a potem ciąg N liczb rzeczywistych A0, A1, ..., AN-1. Liczby te należy umieścić w dynamicznie przydzielonej tablicy. Następnie program ma wyliczyć i wypisać średnią arytmetyczną oraz wartość minimalną i maksymalną spośród wczytanego ciągu liczb.
    Uwaga: Do obliczenia średniej aytmetycznej z podanego ciągu oraz do wyznaczenia wartości najmniejszej i największej zdefiniuj osobne funkcje:
        double srednia (int n, double *tab);
        double miminum (int n, double *tab);
        double maksimum (int n, double *tab);
    Uwaga: Do poruszania się po tablicy zastosuj wskaźniki.
    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
  3. Napisz program, który wczyta dodatnią liczbę całkowite N a potem N łańcuchów znakowych S0, S1, ..., SN-1. Każdy łańcuch należy umieścić w dynamicznie przydzielonej tablicy znakowej. Wskaźniki do łańcuchów także należy pamiętać w dynamicznie przydzielonej tablicy rozmiaru N. Następnie program ma wypisać wszystkie zapamiętane ciągi znaków.
    Uwaga: Do poruszania się po tablicy zastosuj wskaźniki.
    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
  4. (kontynuacja poprzedniego zadania)
    Wczytane w poprzednim programie ciągi znakowe należy posortować leksykograficznie, a potem wypisać je w kolejności on najmniejszego do największego.
    Uwaga: Do sortowania wykorzystaj funkcję standardową qsort().

laboratorium 6 - czwartek,

  1. Napisz program, który wczyta dodatnią liczbę całkowitą N, a następnie wygeneruje losowo N-elementową permutację (wymieszany ciąg liczb od 0 do N-1); zadbaj o to, by każda permutacja mogła być wylosowana z jednakowym prawdopodobieństwem. Wygenerowaną permutację należy zapamiętać w dynamicznie przydzielonej tablicy, a na końcu program ma ją wypisać.
    Uwaga: Do losowania liczb całkowitych z podanego zakresu zdefiniuj osobną funkcję:
        int losuj (int pocz, int kon);
    Uwaga: Twój program powinien na końcu zwolnić przydzieloną pamięć.
  2. Napisz program, który wczyta dodatnią liczbę całkowitą N a potem ciąg N liczb rzeczywistych A0, A1, ..., AN-1. Liczby te należy umieścić w dynamicznie przydzielonej tablicy. Następnie program ma wyliczyć i wypisać średnią arytmetyczną, średnią geometryczną oraz odchylenie standardowe.
    Uwaga: Do obliczenia odchylenia standardowego, średniej aytmetycznej i geometrycznej z podanego ciągu zdefiniuj osobne funkcje:
        double srednia_arytm (int n, double *tab);
        double srednia_geom (int n, double *tab);
        double odchylenie (int n, double *tab);
    Uwaga: Do poruszania się po tablicy zastosuj wskaźniki.
    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
  3. Napisz program, który wczyta dodatnią liczbę całkowite N a potem N dat D0, D1, ..., DN-1. Każda data to struktura z trzema polami do zapamiętania dnia, miesiąca i roku. Wszystkie daty należy umieścić w dynamicznie przydzielonej pamięci. Wskaźniki do dat także należy pamiętać w dynamicznie przydzielonej tablicy rozmiaru N. Następnie program ma wypisać wszystkie zapamiętane daty.
    Uwaga: Do poruszania się po tablicy zastosuj wskaźniki.
    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
  4. (kontynuacja poprzedniego zadania)
    Wczytane w poprzednim programie daty należy posortować w kolejności, a potem wypisać je w kolejności od najwcześniejszej do najpóźniejszej.
    Uwaga: Do sortowania wykorzystaj funkcję standardową qsort().
laboratorium 7

Alokacja pamięci. Dynamiczne struktury danych.

laboratorium 7 - środa,

  1. W pliku nagłówkowym zdefiniuj strukturę reprezentującą węzeł listy jednokierunkowej struct Element, w której będzie pole nast wskazujące na następny element na liście oraz pole wartosc przechowujące liczbę całkowitą:
        struct Element
        {
            Element *nast;
            int wartosc;
        };
    Oprócz struktury zadeklaruj również funkcje wstawNaPocz() (wstawienie nowego elementu na początek listy), wstawNaKon() (wstawienie nowego elementu na koniec listy), ile() (policzenie ile jest elementów na liście) oraz wypisz() (wypisanie kolejno wszystkich wartości zapamiętanych w liście). Pierwszym argumentem tych funkcji powinien być wskaźnik na początek listy. Dalej, w oddzielnym pliku źródłowym zdefiniuj wymienione funkcje (zaimplementuj je iteracyjnie).
  2. (kontynuacja poprzedniego zadania)
    W oddzielnym pliku źródłowym napisz program testujący działanie zdefiniowanej przez Ciebie struktury danych. Testowanie ma się odbywać w sposób interakcyjny, a więc program ma realizować wydawane na konsoli polecenia. Powinniśmy mieć możliwość wydawania następujących rozkazów:
    • dopisanie elementu na początku listy:
      > poczatek 17
      >
    • dopisanie elementu na końcu listy:
      > koniec 43
      >
    • sprawdzenie liczby elementów na liście:
      > ile
      2
      >
    • wypisanie wszystkich elementów listy:
      > wypisz
      17, 37, 29, 23, 43
      >
    • wyjście z programu:
      > stop

    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
    Uwaga: Program ma być odporny na błędy użytkownika.
  3. (kontynuacja poprzedniego zadania)
    Do poprzedniego zadania dopisz funkcje wstaw() (wstawienie nowego elementu na i-tą pozycję w liście: i-ta pozycja oznacza, że i elementów poprzedza dany element) i usun() (usunięcie elementu z i-tej pozycjji w liście). Tak jak poprzednio, delaracje obu funkcji mają być umieszczone w pliku nagłówkowym, a definicje w pliku źródłowym (zaimplementuj je iteracyjnie). W programie testującym dopisz dwa rozkazy: wstaw i usun.
  4. (kontynuacja poprzedniego zadania)
    Do poprzedniego zadania dopisz funkcję odwroc() (odwrócenie kolejności elementów na liście). Tak jak poprzednio, delaracja funkcji ma być umieszczona w pliku nagłówkowym, a definicja w pliku źródłowym (zaimplementuj ją iteracyjnie). W programie testującym dopisz rozkaz: odwroc.

laboratorium 7 - czwartek,

  1. W pliku nagłówkowym zdefiniuj strukturę reprezentującą węzeł drzewa binarnych poszukiwań struct Element, w której będą pola lewe i prawe wskazujące odpowiednio na lewe i prawe poddrzewo zaczepione w danym węźle oraz pole wartosc przechowujące liczbę całkowitą:
        struct Element
        {
            Element *lewe, *prawe;
            int wartosc;
        };
    Oprócz struktury zadeklaruj również funkcje wstaw() (wstawienie nowego elementu do drzewa), ile() (policzenie ile jest elementów w drzewie) oraz wypisz() (wypisanie kolejno wszystkich wartości zapamiętanych w drzewie w porządku inorder). Pierwszym argumentem tych funkcji powinien być wskaźnik na korzeń drzewa lub poddrzewa. Dalej, w oddzielnym pliku źródłowym zdefiniuj wymienione funkcje (zaimplementuj je rekurencyjnie).
  2. (kontynuacja poprzedniego zadania)
    W oddzielnym pliku źródłowym napisz program testujący działanie zdefiniowanej przez Ciebie struktury danych. Testowanie ma się odbywać w sposób interakcyjny, a więc program ma realizować wydawane na konsoli polecenia. Powinniśmy mieć możliwość wydawania następujących rozkazów:
    • dopisanie elementu na początku listy:
      > wstaw 23
      >
    • sprawdzenie liczby elementów na liście:
      > ile
      9
      >
    • wypisanie wszystkich elementów listy:
      > wypisz
      11, 13, 17, 23, 37, 43, 47, 53, 57
      >
    • wyjście z programu:
      > stop

    Uwaga: Twój program powinien zwolnić na końcu przydzieloną pamięć.
    Uwaga: Program ma być odporny na błędy użytkownika.
  3. (kontynuacja poprzedniego zadania)
    Do poprzedniego zadania dopisz funkcje usun_min() (usunięcie elementu minimalnego z drzewa), usun_max() (usunięcie elementu maksymalnego z drzewa) i usun() (usunięcie z drzewa elementu o podanej wartości). Tak jak poprzednio, delaracje obu funkcji mają być umieszczone w pliku nagłówkowym, a definicje w pliku źródłowym (zaimplementuj je rekurencyjnie). W programie testującym dopisz trzy rozkazy: min, max i usun.
  4. (kontynuacja poprzedniego zadania)
    Do poprzedniego zadania dopisz funkcję drukuj() (wyświetlenie struktury drzewa wraz z wartościami w węzłach). Przykładowe wywołanie tej funkcji w programie testującym może wygenerować następujący wynik:
    • graficzna prezentacja drzewa:
      > drukuj
         +--*11
         |  +--*13
      +--*17
      |  +--*23
      *37
      +--*43
         |  +--*47
         +--*53
            +--*57
      >
    Tak jak poprzednio, delaracja funkcji ma być umieszczona w pliku nagłówkowym, a definicja w pliku źródłowym (zaimplementuj ją rekurencyjnie). W programie testującym dopisz rozkaz: drukuj.
laboratorium 8

Bity w słowie, unie, pola bitowe.

laboratorium 8 - środa,

  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 w słowie (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. Numer bitu to wartość z zakresu od 0 do (sizeof(unsigned)<<3)-1, więc gdy parametr nrBitu będzie spoza zakresu, to funkcja jakiBit ma zawsze zwracać 0, a funkcja ustawBit nic nie zrobi.
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  2. (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ą dla preprocesora #define, na przykład jako 220). Zaprogramuj dodatkową funkcję, która wypełni tą tablicę wartościami 1 tylko na tych pozycjach bitowych, które odpowiadają liczbom pierwszym (na i-tej pozycji znajduje się 1 tylko wtedy, gdy liczba i jest pierwsza):
        void sitoEratostenesa ();
    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 na standardowym wyjściu wszystkie liczby pierwsze z zakresu podanego przez użytkownika poprzez parametry wywołania programu.
    Uwaga: Skorzystaj z funkcji zdefiniowanych w poprzednim zadaniu.
    Uwaga: Program ma być odporny na błędy użytkownika.
  3. Zdefiniuj unię, która będzie zawierała pole typu int oraz pole będące tablicą znakową char[sizeof(int)]. Następnie napisz krótki program testowy korzystający z tej unii w celu sprawdzenia, czy liczby na twoim komputerze są zapisywane w systemie littleendian czy bigendian.
  4. Zdefiniuj pole bitowe do zapamiętywania czasu (5 bitów na godzinę, 6 bitów na minuty, 6 bitów na sekundy). Napisz też funkcję, która podane wartości typu int reprezentujące określoną godzinę upakuje do pola bitowego:
        struct Godzina upakuj (int g, int m, int s);
    Następnie napisz krótki program testowy, który odczytuje z parametrów wywołania programu jakąć godzinę, upakowuje ją do pola bitowego, a potem wypisuje na standardowym wyjściu wartość każdego z pól.

laboratorium 8 - czwartek,

  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 w słowie pobranym z tablicy (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 *tablica, int nrBitu);
        void ustawBit (unsigned *tablica, int nrBitu, int wartosc);
    Przy programowaniu tych funkcji skorzystaj z operatorów bitowych. Numer bitu to dowolna wartość całkowita, która pozwala odwoływać się do słowa w tablicy i bitu w tym słowie. Indeks słowa w tablicy wynosi nrBitu/sizeof(unsigned)<<3)-(nrBitu<0).
    Uwaga: Podziel program na pliki nagłówkowe i źródłowe.
  2. (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ą dla preprocesora #define, na przykład jako 220). Zaprogramuj dodatkową funkcję, która wypełni tą tablicę wartościami 1 tylko na tych pozycjach bitowych, które odpowiadają liczbom pierwszym (na i-tej pozycji znajduje się 1 tylko wtedy, gdy liczba i jest pierwsza):
        void sitoEratostenesa ();
    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 na standardowym wyjściu wszystkie liczby pierwsze z zakresu podanego przez użytkownika poprzez parametry wywołania programu.
    Uwaga: Skorzystaj z funkcji zdefiniowanych w poprzednim zadaniu.
    Uwaga: Program ma być odporny na błędy użytkownika.
  3. Zdefiniuj unię, która będzie zawierała pole typu int oraz pole typufloat. Następnie napisz krótki program testowy korzystający z tej unii w celu sprawdzenia, jak jest zapisywana liczba rzeczywista w standardzie IEEE-754 (23 najmniej znaczące bity to mantysa, potem jest 8 bitów cechy i 1 najbardziej znaczący bit to znak).
  4. Zdefiniuj pole bitowe do zapamiętywania daty (12 bitów na rok, 4 bity na miesiąc, 5 bitów na dzień). Napisz też funkcję, która podane wartości typu int reprezentujące określoną datę upakuje do pola bitowego:
        struct Data upakuj (int g, int m, int s);
    Następnie napisz krótki program testowy, który odczytuje z parametrów wywołania programu jakąć datę, upakowuje ją do pola bitowego, a potem wypisuje na standardowym wyjściu wartość każdego z pól.
laboratorium 9

Operacje na plikach.

laboratorium 9 - środa,

  1. Napisz program, który wczyta ze standardowego wejścia 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ć linia po linii, a na końcu zamknąć go. Jeśli linia jest dłuższa niż 79 znaków, to pozostałe znaki w tej linii należy zignorować.
    Wskazówka: Posłuż się funkcją fgets().
  2. Napisz program, który wczyta ze standardowego wejścia nazwę pliku tekstowego, a następnie zapisze w nim kolejne liczby ciągu Fibonacciego (F0 = 0, F1 = 1, a dla n>1 korzystamy ze wzoru Fn = Fn-1 + Fn-2), aż do wyczerpania zakresu liczb typu unsigned long. Każdą liczbę zapisz w oddzielnej linii. Plik należy napierw otworzyć do pisania, potem zapisać w nim kolejne liczby wspomnianego ciągu, a na końcu zamknąć go.
    Wskazówka: Posłuż się funkcją fprintf().
  3. W tekstowym pliku z danymi jest zapisanych N liczb rzeczywistych a0, a1, ..., aN-1. Zawartość pliku z danymi jest następująca: w pierwszej linii jest zapisana liczba całkowita N typu int, a w kolejnych liniach pooddzielane białymi znakami wartości rzeczywiste a0, a1, ..., aN-1 typu double. Należy te liczby odczytać, zapamiętując je w dynamicznie zaalokowanej tablicy. Na koniec trzeba je przepisać do pliku binarnego (bez wartości N na początku) i zwolnić przydzieloną pamięć.
    Uwaga: Nazwę pliku/plików przekaż poprzez parametry wywołania programu.
    Wskazówka: Posłuż się funkcją fscanf() i fwrite().
  4. (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 i wypisz na standardowym wyjściu średnią arytmetyczną z tych liczb. Na końcu zwolnij przydzieloną pamięć.
    Uwaga: Nazwę pliku przekaż poprzez parametry wywołania programu.
    Wskazówka: Posłuż się funkcją fread().

laboratorium 9 - czwartek,

  1. Napisz program, który wczyta ze standardowego wejścia 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ć linia po linii, a na końcu zamknąć go. Twój program powinien obcinać białe znaki na początku i na końcu każdej linii, a liniie puste pomijać przy wypisywaniu.
    Wskazówka: Posłuż się funkcją fgets().
  2. Napisz program, który wczyta ze standardowego wejścia nazwę pliku tekstowego, a następnie zapisze w nim kolejne liczby z trójkąta Pascala (P0,0 = 1, dla n>0 korzystamy ze wzoru Pn,0 = Pn,n = 1 oraz dla 0>k>n mamy Pn,k = Pn-1,k-1 + Pn-1,k), aż do wyczerpania zakresu liczb typu unsigned long. Każdy wiersz trójkąta Pascala zapisz w oddzielnej linii, a poszczególne liczby w obrębie wiersza poodzielaj pojedynczą spacją. Plik należy napierw otworzyć do pisania, potem zapisać w nim wspomniany trójkąt, a na końcu zamknąć go.
    Wskazówka: Posłuż się funkcją fprintf().
  3. W tekstowym pliku z danymi jest zapisanych N liczb rzeczywistych a0, a1, ..., aN-1. Zawartość pliku z danymi jest następująca: w pierwszej linii jest zapisana liczba całkowita N typu int, a w kolejnych liniach pooddzielane białymi znakami wartości rzeczywiste a0, a1, ..., aN-1 typu double. Należy te liczby odczytać, zapamiętując je w dynamicznie zaalokowanej tablicy. Na koniec trzeba je przepisać do pliku binarnego (bez wartości N na początku) i zwolnić przydzieloną pamięć.
    Uwaga: Nazwę pliku/plików przekaż poprzez parametry wywołania programu.
    Wskazówka: Posłuż się funkcją fscanf() i fwrite().
  4. (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 i wypisz na standardowym wyjściu średnią geometryczną z tych liczb. Na końcu zwolnij przydzieloną pamięć.
    Uwaga: Nazwę pliku przekaż poprzez parametry wywołania programu.
    Wskazówka: Posłuż się funkcją fread().
laboratorium 10

Operacje na plikach.

laboratorium 10 - środa,

  1. 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.
  2. 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ę (de)szyfrowania tekstu zadanym kluczem zaprogramuj jako oddzielną funkcję.
    Uwaga: Sprawdź, czy program wywołano z prawidłową liczbą argumentów, oraz czy podana nazwa pliku jest nazwą istniejącego pliku w lokalnym systemie.

laboratorium 10 - czwartek,

  1. Napisz program, który przeszuka plik poszukując w nim zadanego słowa. Nazwa pliku i słowo (lub kilka słów) mają być podawane jako argumenty wywołania programu. Program powinien wypisać wszystkie wiersze zawierające zadane słowo.
    Uwaga: 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, 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ę (de)szyfrowania tekstu zadanym kluczem zaprogramuj jako oddzielną funkcję.
    Uwaga: Sprawdź, czy program wywołano z prawidłową liczbą argumentów, oraz czy podana nazwa pliku jest nazwą istniejącego pliku w lokalnym systemie.
projekt

Przydział zadań projektowych: (html)

ranking

Punktacja z laboratoriów:
grupa ze środy 16-18
grupa z czwartku 14-16

powrót na początek strony