Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ====== Funkcje c.d. ====== ===== Biblioteka standardowa ===== Język C udostępnia zbiór podstawowych funkcji zawartych w tzw. [[http://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny|bibliotece standardowej]]. \\ Oto kilka przydatnych plików nagłówkowych dostępnych w każdej wersji języka C: * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#math.h|math.h]] - funkcje matematyczne, np.: * funkcje trygonometryczne ''sin()'', ''cos()'', * pierwiastek kwadratowy ''sqrt()'', potęga ''pow()'' * logarytm naturalny ''log()'', logarytm dziesiętny ''log10()'', funkcja wykładnicza ''exp()'' * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#ctype.h|ctype.h]] - klasyfikacja znaków, np.: * ''isupper()'' sprawdza, czy znak jest mała literą, * ''toupper()'' zamienia mała literę na dużą * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#stdlib.h|stdlib.h]] - zbiór podstawowych funkcji, np.: * ''rand()'' generator liczb losowych. Funkcja zwraca losową wartość całkowitą z zakresu od 0 do ''RAND_MAX'' * ''exit()'' zamknięcie programu * ''system()'' uruchomienie polecenia systemowego * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#string.h|string.h]] - funkcje do manipulacji napisami, np.: * ''strcmp()'' porównanie kolejności alfabetycznej dwóch napisów * ''strcpy()'' skopiowanie napisu * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#time.h|time.h]] - obsługa czasu, np.: * ''clock()'' czas wykonywania programu * ''time()'' czas, który upłynął od dnia 1 stycznia 1970 roku * [[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#stdio.h|stdio.h]] - obsługa wejścia/wyjścia, np. ''fprintf()'', ''fscanf()'' Chcąc skorzystać z funkcji z biblioteki należy na początku pliku włączyć odpowiedni plik nagłówkowy za pomocą dyrektywy ''#define''. ==== Przykład: funkcja rand() ==== Funkcja ''[[https://pl.wikibooks.org/wiki/C/rand|rand()]]'' pochodzi z biblioteki ''[[https://pl.wikibooks.org/wiki/C/Biblioteka_standardowa/Indeks_tematyczny#stdlib.h|stdlib.h]]'' i pozwala wygenerować losową wartość całkowitą. Tak wygląda deklaracja tej funkcji: <code C> int rand(void); </code> Funkcja ta przy każdym uruchomieniu zwraca liczbę całkowitą pseudolosową z zakresu od 0 do ''RAND_MAX''. Kolejne wartości pseudolosowe powstają w sposób iteracyjny i ich kolejność zależy od początkowej wartości, tzw. ziarna. Generator liczb losowych można zainicjować dowolna liczbą całkowitą ''seed'' za pomocą funkcji ''srand()'' <code C> void srand(int seed); </code> Chcąc uzyskać przy każdorazowym uruchomieniu programu inny ciąg liczb losowych można zainicjować generator wartością związaną z aktualnym czasem: funkcja ''[[https://pl.wikibooks.org/wiki/C/time|time()]]'' z biblioteki ''time.h'' zwraca liczbę sekund, które upłynęły od dnia 1 stycznia 1970 roku godziny 0:00:00 czasu uniwersalnego. Poniży program wykorzystuje funkcję ''rand()'' do przeprowadzenia symulacji wyników 10-cio krotnego rzutu kostką (losowa wartość od 1 do 6). <file C kostka.c> #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i, x; srand(time(0)); for(i=0; i<10; i++) { x = rand() % 6 + 1; printf("%d\n", x); } return 0; } </file> ==== Ćwiczenie: liczba pi ===== Napisz funkcję o nazwie ''pi'', która za pomocą metody Monte Carlo wyznaczy przybliżoną wartość liczby $\pi$. Metoda Monte Carlo pozwala obliczyć przybliżoną wartość pola powierzchni ćwiartki koła o promieniu $r=1$ za pomocą procesu losowego, w którym wykonujemy $n$ losowań punktów w obszaru kwadratu o boku 1. Przybliżona wartość pola ćwiartki koła będzie równa $\frac{k}{n}$, gdzie $k$ to ilość trafień w tarczę koła (ćwiartki) a $n$ to ilość wszystkich losowań. Ćwiartka koła na odcinku $[0,1]$ opisana jest funkcją $$y = \sqrt{1-x^2} $$ {{ zajecia:mn1_2021_2:mc_pi.png?400 |}} Z wzoru na pole koła wynika że pole ćwiartki koła $P = \frac{1}{4}\pi r^2 = \frac{\pi}{4}$, stąd $$\pi = 4\cdot P \approx 4 \frac{k}{n} $$ Algorytm: - ustaw $k = 0$ (ilość trafień) - powtórz $n$ razy: - wylosuj współrzędne punktu $(x , y)$, gdzie $x,y \in [0,1]$ - jeżeli punkt $(x , y)$ trafił w koło (tzn. jeśli $y < \sqrt{1+y^2}$) wówczas zwiększamy zmienną $k$ o jeden - zwróć wynik $4\frac{k}{n}$ Funkcja ''pi'' zdefiniowana jest zgodnie ze specyfikacją:\\ **Argumenty funkcji**: argumentem funkcji jest liczba całkowita ''n'' określająca ilość losowań. \\ **Wartość zwracana**: funkcja zwraca liczbę rzeczywistą, przybliżoną wartość liczby $\pi$ Napisz program, który korzystając z funkcji ''pi'' wyznaczy i wypisze przybliżoną wartość liczby $\pi$ uzyskaną dla $n=1, 10, 100, 1000, 10000, 100000, 1000000$ losowań. **Przykładowy wynik działania programu** <code> N pi ------------------- 1 0.000000 10 2.800000 100 3.000000 1000 3.144000 10000 3.124400 100000 3.137120 1000000 3.141528 10000000 3.141430 </code> ==== Ćwiczenie: pomiar czasu ==== Do programu z poprzedniego ćwiczenia (liczba pi) dodaj procedurę pomiaru czasu wykonywania procedury wyznaczania liczby $\pi$ metodą Monte Carlo. Dla każdej z liczby losowań $n=1, 10, \ldots, 1000000$ program wypisuje czas działania funkcji ''pi'' zmierzony za pomocą funkcji ''clock()'' z biblioteki ''time.h''. Wynik przedstaw w sekundach, tzn. jednostki czasu określone przez funkcję ''clock()'' należy podzielić przez ''CLOCKS_PER_SEC''. **Przykładowy wynik działania programu** <code> N pi czas [s.] ---------------------- 1 4.000000 0.000014 10 2.800000 0.000002 100 3.080000 0.000005 1000 3.072000 0.000036 10000 3.133600 0.000324 100000 3.144280 0.003397 1000000 3.139108 0.028748 10000000 3.140749 0.264698 </code> ===== Tablica jako argument funkcji ===== Argumentem funkcji może być również tablica, wówczas definicja funkcji wygląda w następujący sposób: <code C> void funkcja(int tablica[]) { int x; x = tablica[2]; } </code> Zwróć uwagę, że tablica deklarowana w argumencie (''int tablica[]'') nie zawiera informacji o rozmiarze. Wewnątrz funkcji nie ma informacji o tym jak dużo elementów mieści tablica. W przypadku funkcji, które mają działać dla dowolnie dużych tablic, informacja o rozmiarze musi być przekazana wartością drugiego argumentu. Przykład definicji funkcji, która liczy sumę ''n'' elementów tablicy ''tab'': <code C> float suma(float tab[], int n) { float s = 0; int i = 0; while( i < n ) { s = s + tab[i]; i = i + 1; } return s; } </code> Wywołanie funkcji, której argumentem jest tablica nie różni się niczym od wywołania funkcji, której argumentami są zmienne typów prostych. W argumencie funkcji podajemy nazwę tablicy. Przykład: <code C> int main() { float t[100], x; t[0] = 5; t[1] = 2; x = suma(t, 2); } </code> <WRAP center round important 60%> Tablica, która jest argumentem funkcji, nie jest kopiowana do funkcji, tj. funkcja działa na oryginalnej tablicy i może zmodyfikować jej zawartość. </WRAP> ===== Przykład: funkcja wczytująca liczby do tablicy ===== <file C tab_suma.c> #include <stdio.h> #define MAX 100 void wczytaj(float t[], int n) { int i; printf("\nPodaaj kolejne liczby:\n"); for(i=0;i<n;i++) { printf("tab[%d]=",i); scanf("%f",&t[i]); } } float suma(float tab[], int n) { float s = 0; int i; for(i=0; i < n; i++) s = s + tab[i]; return s; } int main() { int n; float tablica[MAX], x; printf("Podaj rozmiar tablicy: "); scanf("%d", &n); wczytaj(tablica, n); x = suma(tablica, n); printf("Suma liczb wynosi %f\n", x); return 0; } </file> ==== Ćwiczenie: Średnia i odchylenie standardowe ==== Zdefiniuj dwie funkcje o nazwie ''srednia()'' oraz ''odchylenie()'' zgodnie z poniższa specyfikacją. Funkcja ''srednia()'' wyznacza średnią arytmetyczną ''n'' liczb rzeczywistych umieszczonych w tablicy.\\ **Argumenty funkcji**: * tablica z liczbami rzeczywistymi, * liczba całkowita ''n'' określająca ilość liczb znajdujących się w tablicy **Wartość zwracana**: * wartość rzeczywista, średnia arytmetyczna wartości z tablicy dana wzorem: \[ \bar{x}=\frac{1}{n}\sum_{i=1}^n x_i\] Funkcja ''odchylenie()'' wyznacza wartość odchylenia standardowego liczb zawartych w tablicy. \\ Odchylenie standardowe dla $n$ wartości $x_1, x_2, \ldots, x_n$ wyznacz ze wzoru: \[ s=\sqrt{\frac{1}{n-1}\sum_{i=1}^n\left(x_i - \bar{x}\right)^2} \] gdzie $\bar{x}$ oznacza wartość średnią. \\ **Argumenty funkcji**: * tablica z liczbami rzeczywistymi, * liczba całkowita ''n'' określająca ilość liczb znajdujących się w tablicy **Wartość zwracana**: * wartość odchylenia standardowego wartości z tablicy Napisz program, który korzystając z funkcji ''srednia'' i ''odchylenie'' wyznaczy i wyświetli wartość średnią oraz wartość odchylenia standardowego ''n'' podanych przez użytkownika liczb rzeczywistych. Zakładamy, że liczb nie będzie więcej niż 1000. Wartość ''n'' oraz ciąg ''n'' liczb podaje użytkownik na początku działania programu. **Przykład:** Ile elementow ? n = 5 Wprowadz liczby t[0] = 5.3 t[1] = 2.3 t[2] = -5.4 t[3] = 3.14 t[4] = 32 Srednia = 7.468000 Odchylenie = 12.787060 ===== Zadanie: losowanie lotto ====== Napisz program, który wylosuje ''K'' liczb całkowitych z zakresu od 1 do ''N'' bez zwracania. Wykorzystaj w tym celu funkcję ''wymieszaj()'' zaimplementowaną zgodnie z podaną specyfikacją. Zdefiniuj funkcję o nazwie ''wymieszaj()'', która przestawia w sposób losowy pozycję liczb znajdujących się w tablicy.\\ **Argumenty funkcji**: * tablica z liczbami całkowitymi, * liczba całkowita ''n'' określająca ilość liczb znajdujących się w tablicy **Wartość zwracana**: * brak wartości zwracanej. Efektem działania funkcji jest zmiana pozycji elementów tablicy. Algorytm mieszania elementów w tablicy zawierającej $n$ elementów: * dla każdego elementu tablicy $i=0, 1, 2, \ldots, n-1$ wykonaj: * wylosuj wartość całkowitą $k$ z zakresu od 0 do $n-1$ (losowa pozycja w tablicy) * zamień wartości elementu $i$-tego z elementem $k$-tym Napisz program, który korzystając z funkcji ''wymieszaj()'' przeprowadzi losowanie lotto, tj. wypisze ''K'' losowych wartości z zakresu od 1 do ''N''.\\ Na początku programu użytkownik podaje dwie wartości całkowite ''K'' i ''N''. Następnie:\\ 1. wypełnij bęben losujący kulami ponumerowanymi od 1 do ''N'' \\ 2. dokonaj losowania (wymieszanie zawartości bębna losującego za pomocą funkcji ''wymieszaj()'') \\ 3. wypisz numery ''K'' kul znajdujących się na początku \\ **Przykład (przy każdym uruchomieniu uzyskujemy inną sekwencje)** K = 6 N = 49 33 1 25 29 17 42 Rozwiązanie (plik źródłowy) umieść w Moodle pod adresem https://moodle.umk.pl/WFAIIS/mod/assign/view.php?id=6277