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.
/* * Program kopiuje zawartość pliku tekstowego na stdout */ #include <stdio.h> #define N 32 /* bufor na nazwę pliku */"Podaj nazwe pliku (uwaga: mniej niż %d znaki):\n", N); scanf("%s""r"/* czy dało się otworzyć? */ { /* komunikat o błędzie wypiszemy na stderr */"! Nie moge otworzyc pliku %s\n"/* kończymy program, zwracając nietypową wartość */ } /* kopiujemy znak po znaku, aż do napotkania końca pliku *//* równoważnie: putchar(c) */c9-rozwiniecie.c
/* wyświetla zapis liczby całkowitej w systemie o podstawie BASE, przy czym BASE <= 16 */ #include <stdio.h> #define BASE 3 /* podstawa systemu; NIE MOŻE BYĆ WIĘKSZA OD 16, ze względu na sposób prezentacji wyniku! */ /* liczba = k*BASE + cyfra, gdzie k = liczba/BASE (część całkowita z dzielenia). Zatem cyfra = liczba % BASE więc w ten sposób możemy znaleźć ostatnią cyfrę rozwinięcia w bazie BASE. Jednak przed wydrukowaniem tej cyfry, powinniśmy znaleźć rozwinięcie liczby "k"! */ /* Krok1: znajdź rozwinięcie liczby k */ rozwin(liczba/BASE); /* Krok 2: wypisz ostatnią cyfrę rozwinięcia */"%X", liczba % BASE); /* wydruk cyfry w formacie hex */"Podaje liczbę do konwersji:\n"); scanf("%d""(%d)_10 = (", liczba); /* kilka przypadków szczegónych *//* rozwinięcie zera jest zawsze zerem */"0\n"/* liczbę ujemną musimy poprzedzić znakiem "-" */"-"); /* wykonujemy dalej rozwinięcie liczby dodatniej */ liczba = -liczba; } /* teraz na pewno "liczba" jest dodatnia, przystępujemy do rozwinięcia */")_%d\n"Ćwiczenia 8
c8-przeglad-tablicy-blad-rozw.c
/* Losujemy liczbę i sprawdzamy, czy odpowiada jej dodatni element tablicy A. Jesli tak, to piszem "TRAFIONY", jesli nie, to piszemy PUDLO. */ #include <stdio.h> #include <stdlib.h> #define N 3; //BLAD: średnik //BLAD: odwrotna kolejność warunków "TRAFIONY\n""PUDLO\n"c8-przeglad-tablicy-blad.c
/* Losujemy liczbę i sprawdzamy, czy odpowiada jej dodatni element tablicy A. Jesli tak, to piszem "TRAFIONY", jesli nie, to piszemy PUDLO. UWAGA: w programie SĄ BŁĘDY - Twoim celem jest je znaleźć i poprawić. */ #include <stdio.h> #include <stdlib.h> #define N 3; "TRAFIONY\n""PUDLO\n"Ćwiczenia 7
c7-silnia.c
/* Przykład, jak pisać funkcje z kodem testującym */ /* * Funkcja silnia(n) wyznacza wartość "n"! * Ograniczenie: "n" musi być nieujemne i niezbyt duże * ze względu na to, że wynik bardzo szybko rośnie * wraz z "n" *//* zwracana wartość silni *//* implementacja nierekurencyjna */#ifdef DEBUG /* skompiluj gcc -DDEBUG -o silnia silnia.c, aby wygenerować program testujący funkcję silnia() */ #include <stdio.h> "Test funkcji silnia():\n""\t%2d! = %d\n"#endifĆwiczenia 6
c6-hanoi.c
/* Napisz program, rozwiązujący zagadnienie wież Hanoi, zob. zadanie z wykładu 2. */ #include <stdio.h> /* przy okazji, będziemy zliczali wszystkie wykonane przestawienia; 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 */ /* krok 1: najpierw musimy doprowadzić do sytuacji, gdy na lewym został jeden (największy!) krążek, a na środkowym jest reszta wieży */ hanoi(n-1, lewy, prawy, srodkowy); /* krok drugi: teraz po prostu musimy przenieść lewy krążek na prawy słupek */"Ruch: %lld. Przenies krazek ze slupka '%c' na slupek '%c'\n", liczba_ruchow, lewy, prawy); /* krok 3: teraz musimy przenieść już tylko n-1 krążków ze środkowego na prawy! */"Podaj wysokosc lewej wiezy\n"); scanf("%d", &n); /* slupki: Lewy, Srodkowy, Prawy oznaczamy literami, odpowiednio 'L', 'S', 'P' */ hanoi(n, 'L', 'S', 'P'c6-permutuj-in-situ.c
/* Napisz program, który wypisuje, działając in situ, wszystkie permutacje zadanej tablicy */ #include <stdio.h> #define N 4 /* rozmiar permutowanej tablicy */ /* tablica, zawierająca liczby do spermutowania; wygodniej będzie nam użyć tablicy globalnej *//* będziemy liczyli wszystkie wykonane permutacje; powinno ich na końcu być N! nie przewidujemy dużych N, dlatego wystarczy nam typ "int" *//* zamienia ze sobą elementy "i" i "j" tablicy "A" *//* Drukuje zawartość tablicy "A". Ponieważ drukowanie oznacza, że znaleźliśmy nową permutację, 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 z każdym z poprzedzających... */ swap(i,n-1); /* ...następnie spermutować wszystkie poprzedzające... */ permutuj(n-1); /* a na koniec - odwrócić wykonane zamiany! *//* skoro dotarliśmy do początku tablicy, możemy wydrukować gotową permutację *//* inicjalizacja tablicy "A" kolejnymi liczbami naturalnymi *//* drukujemy początkowe ustawienie tablicy */ /* wyznaczamy wszystkie permutacje */"===============\n""===============\n"); perm_count=0;drukuj(); /* drukujemy końcowe ustawienie tablicy */Ćwiczenia 5
c5-fibonacci-rec.c
/* Ciąg Fibonacciego określony jest wzorem rekurencyjnym: <i>F<sub>n+2</sub>=F<sub>n+1</sub> + F<sub>n</sub></i>. 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>. */ #include <stdio.h> #define K 45 /* używamy unsigned, bo wszystkie nasze liczby są dodatnie i tym samym dwukrotnie zwiększamy zakres dostępnych wartości */ /* używamy long int, aby zwiększyć zakres dostępnych wartości w porównaniu z int *//* zwróć uwagę na format wydruku: => muszę podać "%ld", aby zaznczyć, że drukowana liczba jest typu long int => muszę podać "%lld", aby zaznczyć, że drukowana liczba jest typu long long int */ /* sprawdzenie, czy działa */"F(%d) = %lld = %ld\n", \ k, Fibonacci(k), FibonacciRec(k)); } /* wykonanie zadania */"F(%d) = %ld\n""F(%d) = %lld\n"c5-max-podsuma.c
/* Dla zadanej tablicy liczb całkowitych A rozmiaru N wyznaczyć indeksy m oraz M takie, że m < M oraz suma s(m,M) = A_m + A_{m+1} + ... + A_{M-1} jest największa możliwa. Wypisać m, M oraz s(m,M). Kolokwium, 2006 */ #include <stdio.h> #define N 10 /* 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 wartość sumy częściowej. Gdy będzie większa od dotychczasowego maksimum, zmienimy jego wartość i będziemy dalej kontynuować sumowanie */ podsuma = 0; /* wartość sumy elementów A[start]...A[i] *//* obliczona podsuma jest większa od dotychczasowgo maksimum; należy więc zapisać jej parametry */ s = podsuma; m = start; M = i+1; } } } /* zostały obliczone wszystkie możliwe podsumy */"s(%d,%d)=%d\n"Ćwiczenia 4
c4-fibonacci.c
/* Ciąg Fibonacciego określony jest wzorem rekurencyjnym: <i>F<sub>n+2</sub>=F<sub>n+1</sub> + F<sub>n</sub></i>. 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>. */ #include <stdio.h> #define K 45 "Fibonacci(%d) = %d\n"c4-minimum.c
/* Napisz program, który wyznacza najmniejszy CO DO MODUŁU element w zadanej tablicy liczb całkowitych. Autor: Piotr Krzyżanowski */ #include <stdio.h> #include <stdlib.h> /* prototyp dla abs() */ #define N 10 /* rozmiar tablicy */ /* deklaracja tablicy i jej inicjalizacja *//* szukane minimum i jego współrzędna *//* zmienne pomocnicze */ /* na początek nie mamy lepszego kandydata *//* gdy napotkany element jest mniejszy, wybieramy go jako bieżące minimum */"Najmniejszy co do modułu element tablicy to A[%d]=%d.\n"c4-srednie.c
/* Zadanie 1.1 ============ Napisz program, który liczy średnie: arytmetyczną, kwadratową i harmoniczną z zadanej tablicy liczb typu CAŁKOWITEGO. Autor: Piotr Krzyżanowski */ #include <stdio.h> #include <math.h> #define N 5 /* 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] */ /* wciąż używamy typu rzeczywistego, bo średnie nie będą całkowite! *//* szukana srednia arytmetyczna *//* szukana srednia arytmetyczna *//* szukana srednia arytmetyczna */ /* inicjalizacja tablicy "liczby", tutaj: kolejnymi liczbami nieparzystymi: *//* obliczenie sum pomocniczych, z których później: sr_arytm = suma / N sr_kwadr = (sumakw / N)^(1/2) sr_harmo = N / sumainv *//* może być niebezpieczne, gdy liczby są duże */ sumainv += (1.0/liczby[i]); /* UWAGA: "1/liczby[i]" nie zadziała, 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
/* 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żę. Przykład dla N=4 ******************************************************************* * Program wskazuje pola szachowane przez Wieżę na szachownicy 4x4 * ******************************************************************* Podaj wiersz i kolumnę, w której ma być Wieża: 3 2 Oto pola szachowane: 1 2 3 4 1 + 1 2 + 2 3 + + + + 3 4 + 4 1 2 3 4 W przypadku podania pozycji poza szachownicą (np. "0 20") program ma drukować pustą szachownicę i komunikat o błędzie. 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". Wersja "jeszcze trudniejsza": dopuścić szachownice wymiaru większego niż 9 */ #include <stdio.h> #define N 9 /* rozmiar szachownicy */ /* 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"); scanf("%d %d""Bledne dane: musi byc 1 <= wiersz, kolumna <= %d.\n", N); /* wiersz z numerami kolumn */" "" %d""\n"); /* kolejne wiersze szachownicy */" %d", i); /* i - numer wiersza *//* j - numer kolumny */" "" +"" %d\n", i); /* numer wiersza */ } /* wiersz z numerami kolumn */" "" %d""\n"c4-znaki.c
/* Program zlicza liczby dodatnie, ujemne i zera w zadanej tablicy A typu float */ #include <stdio.h> #define N 9 "Dana tablica:\n""\tA[%2d] = %e\n", i, el); /* ś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
/* 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: 43 120 1 komputer ma wypisać: Podane liczby uporzadkowane malejaco: 120, 43, 1. */ #include <stdio.h> "Program porządkuje podane 3 liczby w kolejności malejacej\n""Podaj 3 liczby, oddzielajac je spacjami i nacisnij ENTER\n"); scanf("%d %d %d"/* zamien c z a */ temp = c; c = a; a = temp; } /* teraz na pewno c jest mniejsza od a *//* zamien c z b */ temp = c; c = b; b = temp; } /* teraz na pewno c zawiera najmniejszą z podanych liczb */ /* pozostaje więc uporządkować a i b *//* zamien b z a */ temp = b; b = a; a = temp; } /* teraz na pewno b nie jest większe od a - KONIEC! */"Podane liczby uporzadkowane malejaco:\n\t%d >= %d >= %d\n"c3-palindrom.c
/* Napisz program, który sprawdza, czy podany napis jest palindromem. */ #include <stdio.h> #define N 7 "abccfba""Sprawdzam, czy napis \"%s\" jest palindromem\n""Napis \"%s\" %sjest palindromem.\n", Napis, JestPalindromem == 0 ? "NIE " : ""c3-przestepny-opt.c
/* Napisz program, który sprawdza (korzystając z _jednej_ instrukcji warunkowej), czy podany rok jest przestępny. */ #include <stdio.h> "Program sprawdza, czy wpisany rok jest przestepny\n""Wpisz rok\n"); scanf("%d"/* inny zabawny sposób wyświetlania wyniku */"Rok %d %s jest przestepny", rok, przestepny > 0 ? "nie " : ""c3-przestepny.c
/* Napisz program, który sprawdza, czy podany rok jest przestępny. */ #include <stdio.h> "Program sprawdza, czy wpisany rok jest przestepny\n""Wpisz rok\n"); scanf("%d", &rok); /* 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
/* Napisz program, który sumuje kolejne _zadane_ potęgi liczb naturalnych z _zadanego_ zakresu, np. k^p + (k+1)^p + ... + (m-1)^p + m^p. Tam, gdzie znasz szybszy sposób obliczenia takiej sumy, wykorzystaj go. */ #include <stdio.h> /* 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"); scanf("%d %d %d"/* najpierw obliczmy idop, tzn. p-ta potege liczby i *//* wyliczona potege dodajmy do s */"Szukana suma to: %d\n", s); /* 1. popraw tak, by dla p, dla których jest znany gotowy wzór na wynik (np. p=1), program od razu z niego korzystał */Ćwiczenia 2
c2-imie.c
/* Napisz program, wczytujący dwa imiona i wypisujący je, uzupełniając wydruk dodatkowym napisem o stałej treści, np. gdy podamy ALA i ADAM jako imiona, program pisze "Witaj, ALA. Widze, ze ALA i ADAM to zgrana para! Czy znacie nazwisko Babacki?" */ #include <stdio.h> "Babacki""Adam""Witaj, tu %s\n""? Podaj swoje imie i nacisnij ENTER\n"); scanf("%s", imie1); /* dlaczego wysypie sie, gdy podamy okolo 40 znakow */"? Podaj drugie imie, %s\n", imie1); scanf("%s", imie2); /* dlaczego wysypie sie, gdy podamy okolo 40 znakow */"Witajcie, %s oraz %s!\nCzy znacie nazwisko %s?\n", imie1, imie2, nazwisko); /* popraw program, by produkował sensowniejsze napisy */c2-pierwszy.c
/* Napisz program, wypisujący na terminal napis "Zaczynam programowac w C!" */ #include <stdio.h> "Zaczynam programowac w C!\n"); /* zmień program tak, by każdy wyraz pojawiał się w nowym wierszu */c2-suma-poteg.c
/* Napisz program, który sumuje kolejne czwarte potęgi liczb naturalnych. Wersja (nieco) rozszerzona: program, który sumuje kolejne _zadane_ potęgi liczb naturalnych z _zadanego_ zakresu, np. k^p + (k+1)^p + ... + (m-1)^p + m^p. Tam, gdzie znasz szybszy sposób obliczenia takiej sumy, wykorzystaj go. */ #include <stdio.h> "Suma czwartych poteg kolejnych liczb naturalnych\n""\t1^4+2^4+...+n^4 = ?\n""Podaj n i nacisnij ENTER:\n"); scanf("%d""Szukana suma to: %d\n", s); /* 1. zmień program tak, by liczył sumę dowolnych potęg: 1^k+2^k+...+n^k */ /* 2. popraw tak, by dla k, dla których jest znany gotowy wzór na wynik, program od razu z niego korzystał */c2-sumator.c
/* Napisz program, który sumuje dwie podane przez użytkownika liczby całkowite. */ #include <stdio.h> "*\n* Sumator\n*\n""Wpisz dwie liczby calkowite, oddzielajac je spacjami i nacisnij ENTER\n"); scanf("%d %d""Odp: %d + %d = %d\n", a, b, c); /* 1. czy ZAWSZE dostaniesz prawidłowy wynik? */ /* 2. zmień program tak, by akceptował także liczby rzeczywiste */