Wybrane programy przykładowe z ćwiczeń

Wstęp do informatyki (semestr zimowy)

Poniżej znajdą Państwo niektóre programy omawiane/tworzone/modyfikowane przez nas na ćwiczeniach. Nie jest to stricte materiał dydaktyczny - raczej coś w rodzaju "bloga z kodami", ot dla zgrubnej informacji, co było robione.

W trakcie ćwiczeń często będziemy modyfikowali te programy, lub wręcz pisali je od nowa (by były lepsze!)

Poniższe pliki źródłowe możesz pobierać, klikając w nazwę programu.

Ćwiczenia 9

c9-kopiuj-plik.c

  1. /*
  2.  * Program kopiuje zawartość pliku tekstowego na stdout
  3.  */
  4.  
  5. #include <stdio.h>
  6. #define N 32
  7. /* bufor na nazwę pliku */"Podaj nazwe pliku (uwaga: mniej niż %d znaki):\n", N);
  8. scanf("%s""r"/* czy dało się otworzyć? */
  9. {
  10. /* komunikat o błędzie wypiszemy na stderr */"! Nie moge otworzyc pliku %s\n"/* kończymy program, zwracając nietypową wartość */
  11. }
  12.  
  13. /* kopiujemy znak po znaku, aż do napotkania końca pliku *//* równoważnie: putchar(c) */

c9-rozwiniecie.c

  1. /* wyświetla zapis liczby całkowitej w systemie o podstawie BASE,
  2. przy czym BASE <= 16 */
  3.  
  4. #include <stdio.h>
  5.  
  6. #define BASE 3 /* podstawa systemu; NIE MOŻE BYĆ WIĘKSZA OD 16, ze względu na sposób prezentacji wyniku! */
  7. /* liczba = k*BASE + cyfra, gdzie
  8. k = liczba/BASE
  9. (część całkowita z dzielenia).
  10. Zatem
  11. cyfra = liczba % BASE
  12. więc w ten sposób możemy
  13. znaleźć ostatnią cyfrę rozwinięcia w bazie BASE.
  14. Jednak przed wydrukowaniem tej cyfry, powinniśmy znaleźć
  15. rozwinięcie liczby "k"! */
  16.  
  17. /* Krok1: znajdź rozwinięcie liczby k */
  18. rozwin(liczba/BASE);
  19.  
  20. /* Krok 2: wypisz ostatnią cyfrę rozwinięcia */"%X", liczba % BASE); /* wydruk cyfry w formacie hex */"Podaje liczbę do konwersji:\n");
  21. scanf("%d""(%d)_10 = (", liczba);
  22.  
  23. /* kilka przypadków szczegónych *//* rozwinięcie zera jest zawsze zerem */"0\n"/* liczbę ujemną musimy poprzedzić znakiem "-" */"-");
  24. /* wykonujemy dalej rozwinięcie liczby dodatniej */
  25. liczba = -liczba;
  26. }
  27.  
  28. /* teraz na pewno "liczba" jest dodatnia,
  29. przystępujemy do rozwinięcia */")_%d\n"

Ćwiczenia 8

c8-przeglad-tablicy-blad-rozw.c

  1. /* Losujemy liczbę i sprawdzamy, czy odpowiada jej dodatni element tablicy A. Jesli tak, to piszem "TRAFIONY", jesli nie, to piszemy PUDLO.
  2. */
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #define N 3; //BLAD: średnik
  7. //BLAD: odwrotna kolejność warunków
  8. "TRAFIONY\n""PUDLO\n"

c8-przeglad-tablicy-blad.c

  1. /*
  2. Losujemy liczbę i sprawdzamy, czy odpowiada jej dodatni element tablicy A.
  3. Jesli tak, to piszem "TRAFIONY", jesli nie, to piszemy PUDLO.
  4.  
  5. UWAGA: w programie SĄ BŁĘDY - Twoim celem jest je znaleźć i poprawić.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #define N 3;
  11. "TRAFIONY\n""PUDLO\n"

Ćwiczenia 7

c7-silnia.c

  1. /* Przykład, jak pisać funkcje z kodem testującym */
  2.  
  3. /*
  4.  * Funkcja silnia(n) wyznacza wartość "n"!
  5.  * Ograniczenie: "n" musi być nieujemne i niezbyt duże
  6.  * ze względu na to, że wynik bardzo szybko rośnie
  7.  * wraz z "n"
  8.  *//* zwracana wartość silni *//* implementacja nierekurencyjna */#ifdef DEBUG
  9. /*
  10. skompiluj
  11. gcc -DDEBUG -o silnia silnia.c,
  12. aby wygenerować program testujący funkcję silnia()
  13. */
  14.  
  15. #include <stdio.h>
  16. "Test funkcji silnia():\n""\t%2d! = %d\n"#endif
  17.  

Ćwiczenia 6

c6-hanoi.c

  1. /*
  2. Napisz program, rozwiązujący zagadnienie wież Hanoi,
  3. zob. zadanie z wykładu 2.
  4. */
  5.  
  6. #include <stdio.h>
  7. /* przy okazji, będziemy zliczali wszystkie wykonane przestawienia;
  8. w tym celu wygodnie użyć zmiennej globalnej *//* zamiast numerować słupki, tym razem nazwiemy je literami *//* jeśli tylko jest coś do zrobienia (tzn. wysokość wieży jest > 0 */
  9.  
  10. /* krok 1: najpierw musimy doprowadzić do sytuacji,
  11. gdy na lewym został jeden (największy!) krążek,
  12. a na środkowym jest reszta wieży */
  13. hanoi(n-1, lewy, prawy, srodkowy);
  14.  
  15. /* krok drugi: teraz po prostu musimy przenieść lewy krążek na
  16. prawy słupek */"Ruch: %lld. Przenies krazek ze slupka '%c' na slupek '%c'\n", liczba_ruchow, lewy, prawy);
  17.  
  18. /* krok 3: teraz musimy przenieść już tylko n-1 krążków ze
  19. środkowego na prawy! */"Podaj wysokosc lewej wiezy\n");
  20. scanf("%d", &n);
  21.  
  22. /* slupki: Lewy, Srodkowy, Prawy oznaczamy literami,
  23. odpowiednio 'L', 'S', 'P' */
  24.  
  25. hanoi(n, 'L', 'S', 'P'

c6-permutuj-in-situ.c

  1. /* Napisz program, który wypisuje, działając in situ, wszystkie permutacje zadanej tablicy */
  2.  
  3. #include <stdio.h>
  4. #define N 4 /* rozmiar permutowanej tablicy */
  5. /* tablica, zawierająca liczby do spermutowania;
  6. wygodniej będzie nam użyć tablicy globalnej *//* będziemy liczyli wszystkie wykonane permutacje;
  7. powinno ich na końcu być N! nie przewidujemy dużych N,
  8. dlatego wystarczy nam typ "int" *//* zamienia ze sobą elementy "i" i "j" tablicy "A" *//* Drukuje zawartość tablicy "A".
  9. Ponieważ drukowanie oznacza, że znaleźliśmy nową permutację,
  10. przy okazji zwiększamy licznik wykonanych permutacji o 1 */"%4d | ""%d ""\n"/* szuka wszystkich permutacji początkowych n elementów tablicy "A" *//* wystarczy zamienić ostatni element
  11. z każdym z poprzedzających... */
  12. swap(i,n-1);
  13.  
  14. /* ...następnie spermutować wszystkie poprzedzające... */
  15. permutuj(n-1);
  16.  
  17. /* a na koniec - odwrócić wykonane zamiany! *//* skoro dotarliśmy do początku tablicy,
  18. możemy wydrukować gotową permutację *//* inicjalizacja tablicy "A" kolejnymi liczbami naturalnymi *//* drukujemy początkowe ustawienie tablicy */
  19.  
  20. /* wyznaczamy wszystkie permutacje */"===============\n""===============\n");
  21.  
  22. perm_count=0;drukuj(); /* drukujemy końcowe ustawienie tablicy */

Ćwiczenia 5

c5-fibonacci-rec.c

  1. /*
  2. Ciąg Fibonacciego określony jest wzorem rekurencyjnym:
  3. <i>F<sub>n+2</sub>=F<sub>n+1</sub> + F<sub>n</sub></i>.
  4. Napisz program, znajdujący <i>k</i>-ty wyraz ciągu Fibonacciego, gdy <i>F<sub>0</sub>=0</i> oraz <i>F<sub>1</sub>=1</i>. Dodatkowe: zmodyfikuj program tak, by można było zadawać dowolne wartości <i>F<sub>0</sub></i> oraz <i>F<sub>1</sub></i>.
  5. */
  6.  
  7. #include <stdio.h>
  8. #define K 45
  9.  
  10. /* używamy unsigned, bo wszystkie nasze liczby są dodatnie
  11. i tym samym dwukrotnie zwiększamy zakres dostępnych wartości */
  12.  
  13. /* używamy long int, aby zwiększyć zakres dostępnych wartości
  14. w porównaniu z int *//* zwróć uwagę na format wydruku:
  15.  
  16. => muszę podać "%ld", aby zaznczyć, że
  17. drukowana liczba jest typu long int
  18.  
  19. => muszę podać "%lld", aby zaznczyć, że
  20. drukowana liczba jest typu long long int
  21. */
  22.  
  23. /* sprawdzenie, czy działa */"F(%d) = %lld = %ld\n", \
  24. k, Fibonacci(k), FibonacciRec(k));
  25. }
  26.  
  27. /* wykonanie zadania */"F(%d) = %ld\n""F(%d) = %lld\n"

c5-max-podsuma.c

  1. /*
  2. Dla zadanej tablicy liczb całkowitych A rozmiaru N
  3. wyznaczyć indeksy m oraz M takie, że m < M oraz suma
  4. s(m,M) = A_m + A_{m+1} + ... + A_{M-1}
  5. jest największa możliwa. Wypisać m, M oraz s(m,M).
  6.  
  7. Kolokwium, 2006
  8. */
  9.  
  10. #include <stdio.h>
  11. #define N 10
  12. /* zadana tablica liczb całkowitych *//* s, m, M - wg treści zadania *//* będziemy sumować tablicę od miejsca "start" aż do końca, badając
  13. wartość sumy częściowej. Gdy będzie większa od dotychczasowego maksimum,
  14. zmienimy jego wartość i będziemy dalej kontynuować sumowanie */
  15.  
  16. podsuma = 0; /* wartość sumy elementów A[start]...A[i] *//* obliczona podsuma jest większa
  17. od dotychczasowgo maksimum;
  18. należy więc zapisać jej parametry */
  19. s = podsuma;
  20. m = start;
  21. M = i+1;
  22. }
  23. }
  24. }
  25.  
  26. /* zostały obliczone wszystkie możliwe podsumy */"s(%d,%d)=%d\n"

Ćwiczenia 4

c4-fibonacci.c

  1. /*
  2. Ciąg Fibonacciego określony jest wzorem rekurencyjnym:
  3. <i>F<sub>n+2</sub>=F<sub>n+1</sub> + F<sub>n</sub></i>.
  4. Napisz program, znajdujący <i>k</i>-ty wyraz ciągu Fibonacciego, gdy <i>F<sub>0</sub>=0</i> oraz <i>F<sub>1</sub>=1</i>. Dodatkowe: zmodyfikuj program tak, by można było zadawać dowolne wartości <i>F<sub>0</sub></i> oraz <i>F<sub>1</sub></i>.
  5. */
  6.  
  7. #include <stdio.h>
  8. #define K 45
  9. "Fibonacci(%d) = %d\n"

c4-minimum.c

  1. /*
  2. Napisz program, który wyznacza najmniejszy CO DO MODUŁU element w zadanej tablicy liczb całkowitych.
  3.  
  4. Autor: Piotr Krzyżanowski
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h> /* prototyp dla abs() */
  9.  
  10. #define N 10 /* rozmiar tablicy */
  11. /* deklaracja tablicy i jej inicjalizacja *//* szukane minimum i jego współrzędna *//* zmienne pomocnicze */
  12.  
  13. /* na początek nie mamy lepszego kandydata *//* gdy napotkany element jest mniejszy,
  14. wybieramy go jako bieżące minimum */"Najmniejszy co do modułu element tablicy to A[%d]=%d.\n"

c4-srednie.c

  1. /*
  2. Zadanie 1.1
  3. ============
  4. Napisz program, który liczy średnie:
  5. arytmetyczną, kwadratową i harmoniczną z zadanej tablicy
  6. liczb typu CAŁKOWITEGO.
  7.  
  8. Autor: Piotr Krzyżanowski
  9. */
  10. #include <stdio.h>
  11. #include <math.h>
  12. #define N 5
  13. /* dla niej będziemy liczyć średnie *//* suma = liczby[0] +...+ liczby[N-1] *//* sumakw = liczby[0]^2 +...+ liczby[N-1]^2 *//* sumainv = 1/liczby[0] +...+ 1/liczby[N-1] */
  14. /* wciąż używamy typu rzeczywistego,
  15. bo średnie nie będą całkowite! *//* szukana srednia arytmetyczna *//* szukana srednia arytmetyczna *//* szukana srednia arytmetyczna */
  16.  
  17. /* inicjalizacja tablicy "liczby",
  18. tutaj: kolejnymi liczbami nieparzystymi: *//* obliczenie sum pomocniczych, z których później:
  19. sr_arytm = suma / N
  20. sr_kwadr = (sumakw / N)^(1/2)
  21. sr_harmo = N / sumainv
  22. *//* może być niebezpieczne, gdy liczby są duże */
  23.  
  24. sumainv += (1.0/liczby[i]);
  25. /* UWAGA: "1/liczby[i]" nie zadziała,
  26. bo dzielenie liczb całkowitych daje liczbę całkowitą! */"Srednie zadanych liczb:""\n\tarytmetyczna\t%f\n\tkwadratowa\t%f\n\tharmoniczna\t%f\n"

c4-szachy-wieze.c

  1. /*
  2. Napisz program, który dla zadanej szachownicy N x N (przy czym N < 10) wczytuje pozycję Wieży (np. 3 2 oznacza, ze Wieza jest w 3. wierszu i 2. kolumnie szachownicy) i następnie drukuje szachownicę z zaznaczonymi polami szachowanymi przez tę Wieżę.
  3.  
  4. Przykład dla N=4
  5.  
  6. *******************************************************************
  7. * Program wskazuje pola szachowane przez Wieżę na szachownicy 4x4 *
  8. *******************************************************************
  9. Podaj wiersz i kolumnę, w której ma być Wieża:
  10. 3 2
  11. Oto pola szachowane:
  12. 1 2 3 4
  13. 1 + 1
  14. 2 + 2
  15. 3 + + + + 3
  16. 4 + 4
  17. 1 2 3 4
  18.  
  19. W przypadku podania pozycji poza szachownicą (np. "0 20") program ma drukować pustą szachownicę i komunikat o błędzie.
  20.  
  21. Wersja "trudniejsza": zamiast podawać pozycje w postaci "numer_wiersza numer_kolumny", umożliwić podawanie pozycji w notacji szachowej, tzn. zamiast "3 2" pisalibyśmy "c 2".
  22.  
  23. Wersja "jeszcze trudniejsza": dopuścić szachownice wymiaru większego niż 9
  24. */
  25.  
  26. #include <stdio.h>
  27. #define N 9 /* rozmiar szachownicy */
  28. /* pozycja wieży: (w,k) *//* zmienne pomocnicze */"*******************************************************************\n""* Program wskazuje pola szachowane przez Wieżę na szachownicy %dx%d *\n""*******************************************************************\n""Podaj wiersz i kolumnę, w której ma być Wieża, oddzielając je spacjami\n\ti naciśnij ENTER:\n");
  29. scanf("%d %d""Bledne dane: musi byc 1 <= wiersz, kolumna <= %d.\n", N);
  30.  
  31. /* wiersz z numerami kolumn */" "" %d""\n");
  32.  
  33. /* kolejne wiersze szachownicy */" %d", i); /* i - numer wiersza *//* j - numer kolumny */" "" +"" %d\n", i); /* numer wiersza */
  34. }
  35. /* wiersz z numerami kolumn */" "" %d""\n"

c4-znaki.c

  1. /*
  2. Program zlicza liczby dodatnie, ujemne i zera w zadanej tablicy A typu float
  3. */
  4. #include <stdio.h>
  5. #define N 9
  6. "Dana tablica:\n""\tA[%2d] = %e\n", i, el);
  7.  
  8. /* śmieszny sposób zliczania */"Liczba elementów dodatnich: %2d\n""Liczba elementów zerowych: %2d\n""Liczba elementów ujemnych: %2d\n"

Ćwiczenia 3

c3-kolejnosc.c

  1. /*
  2. Napisać program, który wczytuje trzy liczby całkowite i wypisuje je na ekran w kolejności od największej do najmniejszej, np. gdy użytkownik poda:
  3.  
  4. 43 120 1
  5.  
  6. komputer ma wypisać:
  7.  
  8. Podane liczby uporzadkowane malejaco: 120, 43, 1.
  9.  
  10. */
  11.  
  12. #include <stdio.h>
  13. "Program porządkuje podane 3 liczby w kolejności malejacej\n""Podaj 3 liczby, oddzielajac je spacjami i nacisnij ENTER\n");
  14. scanf("%d %d %d"/* zamien c z a */
  15. temp = c; c = a; a = temp;
  16. }
  17. /* teraz na pewno c jest mniejsza od a *//* zamien c z b */
  18. temp = c; c = b; b = temp;
  19. }
  20. /* teraz na pewno c zawiera najmniejszą z podanych liczb */
  21. /* pozostaje więc uporządkować a i b *//* zamien b z a */
  22. temp = b; b = a; a = temp;
  23. }
  24. /* teraz na pewno b nie jest większe od a - KONIEC! */"Podane liczby uporzadkowane malejaco:\n\t%d >= %d >= %d\n"

c3-palindrom.c

  1. /*
  2. Napisz program, który sprawdza,
  3. czy podany napis jest palindromem.
  4. */
  5. #include <stdio.h>
  6. #define N 7
  7. "abccfba""Sprawdzam, czy napis \"%s\" jest palindromem\n""Napis \"%s\" %sjest palindromem.\n", Napis, JestPalindromem == 0 ? "NIE " : ""

c3-przestepny-opt.c

  1. /*
  2. Napisz program, który sprawdza
  3. (korzystając z _jednej_ instrukcji warunkowej),
  4. czy podany rok jest przestępny.
  5. */
  6. #include <stdio.h>
  7. "Program sprawdza, czy wpisany rok jest przestepny\n""Wpisz rok\n");
  8. scanf("%d"/* inny zabawny sposób wyświetlania wyniku */"Rok %d %s jest przestepny", rok, przestepny > 0 ? "nie " : ""

c3-przestepny.c

  1. /*
  2. Napisz program, który sprawdza,
  3. czy podany rok jest przestępny.
  4. */
  5. #include <stdio.h>
  6. "Program sprawdza, czy wpisany rok jest przestepny\n""Wpisz rok\n");
  7. scanf("%d", &rok);
  8.  
  9. /* jak poniższe sprawdzenie zamknąć w jednej instrukcji "if"? *//* zabawny sposób wyświetlania wyniku w zależności od jego wartości */"Rok %d ""nie ""jest przestepny!\n"

c3-suma-poteg-lepsza.c

  1. /*
  2. Napisz program, który sumuje
  3. kolejne _zadane_ potęgi
  4. liczb naturalnych z _zadanego_ zakresu, np.
  5. k^p + (k+1)^p + ... + (m-1)^p + m^p.
  6.  
  7. Tam, gdzie znasz szybszy sposób obliczenia takiej sumy, wykorzystaj go.
  8. */
  9. #include <stdio.h>
  10. /* zgodnie ze specyfikacja zadania *//* s jest obliczona suma czesciowa *//* zmienne pomocnicze */"Suma p-tych poteg kolejnych liczb naturalnych od k do n\n""\tk^p+(k+1)^p+...+n^p = ?\n""? Podaj p, k, n, oddzielajac je SPACJAMI i nacisnij ENTER:\n");
  11. scanf("%d %d %d"/* najpierw obliczmy idop, tzn. p-ta potege liczby i *//* wyliczona potege dodajmy do s */"Szukana suma to: %d\n", s);
  12.  
  13. /* 1. popraw tak, by dla p, dla których jest znany gotowy wzór
  14. na wynik (np. p=1), program od razu z niego korzystał */

Ćwiczenia 2

c2-imie.c

  1. /*
  2. Napisz program, wczytujący dwa imiona i wypisujący je,
  3. uzupełniając wydruk dodatkowym napisem o stałej treści,
  4. np. gdy podamy ALA i ADAM jako imiona, program pisze
  5. "Witaj, ALA. Widze, ze ALA i ADAM to zgrana para!
  6. Czy znacie nazwisko Babacki?"
  7. */
  8. #include <stdio.h>
  9. "Babacki""Adam""Witaj, tu %s\n""? Podaj swoje imie i nacisnij ENTER\n");
  10. scanf("%s", imie1); /* dlaczego wysypie sie, gdy podamy okolo 40 znakow */"? Podaj drugie imie, %s\n", imie1);
  11. scanf("%s", imie2); /* dlaczego wysypie sie, gdy podamy okolo 40 znakow */"Witajcie, %s oraz %s!\nCzy znacie nazwisko %s?\n", imie1, imie2, nazwisko);
  12.  
  13. /* popraw program, by produkował sensowniejsze napisy */

c2-pierwszy.c

  1. /*
  2. Napisz program, wypisujący na terminal napis
  3. "Zaczynam programowac w C!"
  4. */
  5. #include <stdio.h>
  6. "Zaczynam programowac w C!\n");
  7.  
  8. /* zmień program tak, by każdy wyraz pojawiał się w nowym wierszu */

c2-suma-poteg.c

  1. /*
  2. Napisz program, który sumuje
  3. kolejne czwarte potęgi liczb naturalnych.
  4.  
  5. Wersja (nieco) rozszerzona: program, który sumuje
  6. kolejne _zadane_ potęgi
  7. liczb naturalnych z _zadanego_ zakresu, np.
  8. k^p + (k+1)^p + ... + (m-1)^p + m^p.
  9. Tam, gdzie znasz szybszy sposób obliczenia takiej sumy, wykorzystaj go.
  10. */
  11. #include <stdio.h>
  12. "Suma czwartych poteg kolejnych liczb naturalnych\n""\t1^4+2^4+...+n^4 = ?\n""Podaj n i nacisnij ENTER:\n");
  13. scanf("%d""Szukana suma to: %d\n", s);
  14.  
  15. /* 1. zmień program tak, by liczył sumę dowolnych potęg:
  16. 1^k+2^k+...+n^k */
  17. /* 2. popraw tak, by dla k, dla których jest znany gotowy wzór
  18. na wynik, program od razu z niego korzystał */

c2-sumator.c

  1. /*
  2. Napisz program, który sumuje dwie podane przez użytkownika
  3. liczby całkowite.
  4. */
  5. #include <stdio.h>
  6. "*\n* Sumator\n*\n""Wpisz dwie liczby calkowite, oddzielajac je spacjami i nacisnij ENTER\n");
  7. scanf("%d %d""Odp: %d + %d = %d\n", a, b, c);
  8.  
  9. /* 1. czy ZAWSZE dostaniesz prawidłowy wynik? */
  10. /* 2. zmień program tak, by akceptował także liczby rzeczywiste */