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, skrypty i instrukcje sterujące ====== * **skrypt** jest programem, który możemy uruchomić w linii komend Matlaba, operuje na danych zdefiniowanych w przestrzeni roboczej (//workspace//) * skrypt może realizować **funkcję**, czyli dla danych argumentów wzraca wartość wyjściową. Zmienne wewnętrzne funkcji są zmiennymi lokalnymi * podstawowe instrukcje sterujące * instrukcja warunkowa ''%%if%%'' * pętla ''%%while%%'' i ''%%for%%'' ===== Skrypt ===== * nazwa skryptu staje się poleceniem * znak ''%%%%%'' rozpoczyna komentarz. Komentarz umieszczony na początku skryptu wyświetlany jest przez polecenie ''%%help%%'' Przykład: skrypt [[https://raw.githubusercontent.com/IS-UMK/pp2_matlab/master/pole_kola.m|pole_kola.m]] <code> type pole_kola </code> <code> pole_kola is the user-defined function defined from: /home/marek/work/zajecia/2020.zimowy/pp2/github/pole_kola.m % Skrypt wyznacza pole koła o promieniu 5 % wartość promienia r = 5 % wzór na pole koła pole = pi * r^2 </code> <code> help pole_kola </code> <code> 'pole_kola' is a script from the file /home/marek/work/zajecia/2020.zimowy/pp2/github/pole_kola.m Skrypt wyznacza pole koła o promieniu 5 Additional help for built-in functions and operators is available in the online version of the manual. Use the command 'doc <topic>' to search the manual index. Help and information about Octave is also available on the WWW at https://www.octave.org and via the help@octave.org mailing list. </code> <code> pole_kola </code> <code> r = 5 pole = 78.540 </code> <code> whos </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== ans 1x1 8 double pole 1x1 8 double r 1x1 8 double Total is 3 elements using 24 bytes </code> ===== Definicja funkcji ===== **function** //argumenty_wyjściowe// **=** //nazwa_funkcji// **(** //argumenty_wejściowe// **)**\\ **%** Komentarz stanowiący pomoc funkcji instrukcje skryptu **end** ---- * nazwa funkcji musi byc taka sama jak nazwa pliku * zwracane są wartości przypisane do //argumentów wyjściowych// * funkcja może mieć wiele argumentów wejsciowych i zwracać wiele wartości wyjściowych Przykład: [[https://raw.githubusercontent.com/IS-UMK/pp2_matlab/master/pole_kola2.m|pole_kola2.m]] <code> function pole = pole_kola2(r) % Skrypt wyznacza pole koła o promieniu r pole = pi * r^2; end </code> <code> pole_kola2(5) </code> <code> ans = 78.540 </code> podstawienie wyniku z funkcji <code> pole = pole_kola2( 3 ); printf('Pole koła o promieniu 3 wynosi %f\n', pole); </code> <code> Pole koła o promieniu 3 wynosi 28.274334 </code> Skrypt lub funkcja mogą byc uruchamiane wewnątrz innych skryptów i funkcji Przykład: funkcja [[https://raw.githubusercontent.com/IS-UMK/pp2_matlab/master/objetosc_stozka.m|objetosc_stozka.m]] wyznacza wartość: $$ V = \frac{1}{3} \pi r^2 h $$ gdzie argumentami skryptu są wartości: $r$ promień podstawy, $h$ wysokość stożka. {{zajecia:pp2_2020_2:stozek.png| image.png}} <code> function objetosc = objetosc_stozka(r, h) % Skrypt wyznacza objętość ztozka. % ArgumentyL % r - promień podstawy % h - wysokość stożka objetosc = pole_kola2(r) * h / 3; end </code> <code> objetosc_stozka(1, 3) </code> <code> ans = 3.1416 </code> ===== Zadanie 2 ===== Napisz funkcję o nazwie ''%%rzut_poziomy.m%%'', która wyznacza zasięg rzutu poziomego zgodnie ze wzorem $$ Z = v_0 \sqrt{\frac{2h}{g}}$$ Argumenty wejściowe funkcji: * $v_0$ prędkość początkowa * $h$ wysokość Stała przyśpieszenia ziemskiego $g \approx 9.80665$ Umieść w pliku komentarz, który spowoduje wypisanie stosownego opisu za pomocą polecenia ''%%help%%''. ===== Instrukcja warunkowa if ===== **if** warunek\\ instrukcje\\ **end** <code> x = -1 if x < 0 printf('Wartość %f jest mniejsza od zera\n', x); end </code> <code> x = -1 Wartość -1.000000 jest mniejsza od zera </code> Podobnie jak w języku C liczby całkowite występują w roli wartości logicznych: 0 to fałsz, 1 to prawda ===== Operatory relacji ===== ^ Operator ^ Znaczenie ^ | < | mniejsze niż | | <= | mniejsze lub równe | | > | większe niż | | >= | większe lub równe | | == | równe | | ~= | różne | **Uwaga**: ''%%=%%'' to operator przypisania a ''%%==%%'' to operator porównania <code> 5 < 3 % porównywanie liczb 4 == 3 + 1 'z' < 'a' % porównywanie znaków 3 ~= 4 x = 1 == 2 </code> <code> ans = 0 ans = 1 ans = 0 ans = 1 x = 0 </code> ===== Operatory logiczne ===== ^ Operator ^ Znaczenie ^ x=true y=true ^ x=true y=false ^x=false y=false ^ | x %%||%% y | lub (OR) | true | true |false | | x && y | i (AND) | true | false |false | | ~x | nie (NOT) | false | false |true | | xor(x, y) | exclusive OR | false | true |false | <code> x = 42; y = 3; x < y && y > 5 x > y || y - 1 == x xor(x > y, 'b' < 'a') ~x xor(1, true) </code> <code> ans = 0 ans = 1 ans = 1 ans = 0 ans = 0 </code> ===== Instrukcja if else ===== **if** warunek\\ instrukcje wykonane, gdy warunek jest prawdziwy\\ **else**\\ instrukcje wykonane, gdy warunek nie jest prawdziwy\\ **end** <code> x = 42 if mod(x, 2) == 0 printf('Liczba %d jest parzysta', x); else printf('Liczba %d jest nieparzysta', x); end </code> <code> x = 42 Liczba 42 jest parzysta </code> **Ćwiczenie**:\\ Napisz skrypt o nazwie ''%%rzut_moneta.m%%'', który po uruchomieniu wypisze komunikat “Orzeł” lub “Reszka”. Każdy z wyników może się pojawić z szansą 50%. Do wylosowania wyniku wykorzystaj funkcję ''%%rand%%''. ===== Instrukcja if elseif else ===== **if** warunek 1\\ instrukcje wykonane, gry warunek 1 jest prawdziwy\\ **elseif** warunek 2\\ instrukcje wykonane, gdy warunek 2 jest prawdziwy a warunek 1 jest nieprawdziwy\\ …\\ **else**\\ instrukcje wykonane w gdy warunek 1 i warunek 2 nie są prawdziwe\\ **end** <code> x = 42 if x < 0 printf('Liczba jest mniejsza od zera', x); elseif x < 10 printf('Liczba %d jest dodatnia i mniejsza od 10', x); else printf('Liczba %d jest większa lub równa 10', x); end </code> <code> x = 42 Liczba 42 jest większa lub równa 10 </code> ===== Pętla while ===== **while** warunek\\ instrukcje wykonywane dopóki warunek jest prawdziwy\\ **end** <code> x = 1 while x < 10 printf('%d ', x); x = x + 1; end </code> <code> x = 1 1 2 3 4 5 6 7 8 9 </code> ===== Zadanie 3 ===== Napisz funkcję ''%%nwd.m%%'', która wyznacza największy wspólny dzielnik dwóch liczb naturalnych za pomocą algorytmu Euklidesa. Algorytm Euklidesa: dla danych $a$ i $b$ - jeżeli $a=b$ to $a$ jest największym wspólnym dzielnikiem. Zakończ program - jeżeli $a<b$ to podstaw do $b$ wartość $b-a$ i wróć do punktu 1 - jeżeli $a>b$ to podstaw do $a$ wartość $a-b$ i wróć do punktu 1 Program wypisuje stosowny komunikat pomocy po wywołaniu ''%%help nwd%%''.\\ W przypadku, gdy jeden z argumentów jest mniejszy od 1 to wypisywany jest komunikat ''%%Niepoprawne dane%%'' a funkcja ''%%nwd%%'' zwraca wartość 0. ===== Pętla for ===== **for** zmienna **=** [ lista elementów ]\\ instrukcje\\ **end** <code> for i=[3 5 7] printf('Pole koła o promieniu %f wynosi %f\n', i, pole_kola2(i)); end </code> <code> Pole koła o promieniu 3.000000 wynosi 28.274334 Pole koła o promieniu 5.000000 wynosi 78.539816 Pole koła o promieniu 7.000000 wynosi 153.938040 </code> ===== Instrukcje zagnieżdzone ===== Przykład: tabliczka mnożenia <code> % tabliczka mnożenia n = 10 for i=1:n for j=1:n printf('%3d ', i*j); end printf('\n'); end </code> <code> n = 10 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100 </code> ===== break, continue ===== Wewnątrz pętli ''%%while%%'' i ''%%for%%'' można użyć instrukcji ''%%break%%'' oraz ''%%continue%%'' * instrukcja ''%%break%%'' przerywa działanie pętli * instrukcja ''%%continue%%'' przechodzi do następnej iteracji <code> n = 11; czy_pierwsza = true; for i = 2:n-1 if mod(n, i) == 0 czy_pierwsza = false; break end end if czy_pierwsza printf('Liczba %d jest liczbą pierwszą\n', n) else printf('Liczba %d nie jest liczbą pierwszą\n', n) printf('Znalazłem dzielnik %d\n', i) end </code> <code> Liczba 11 jest liczbą pierwszą </code> <code> for n=1:20 if n == 13 continue end printf('%d ', n) end </code> <code> 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 </code> ===== switch case ===== **switch** wyrażenie\\ **case** wartość1\\ instrukcje wykonane, gry wyrażenie == wartość1\\ **case** wartość2\\ instrukcje wykonane, gry wyrażenie == wartość2\\ …`\\ **otherwise**\\ instrukcje wykonane, gry nie zaszedł żaden z powyższych przypadków\\ **end** ---- Uwaga: w przeciwieństwie do języka C wykonywany jest zawsze tylko pasujący przypadek (brak instrukcji ''%%break%%'') Zmienna ''%%nargin%%'' zawiera liczbę argumentów podaną przy uruchomieniu funkcji. Można to wykorzystać do wstawienia domyślnych wartości argumentów. Przykład: skrypt [[https://raw.githubusercontent.com/IS-UMK/pp2_matlab/master/argumenty.m|argumenty.m]] <code> function argumenty(x) switch nargin case 0 x = 42; % wartość domyślna case 1 printf('Jeden argument\n') otherwise printf('Podałeś więcej niż 1 argument\n') end disp(x) end </code> <code> argumenty argumenty() argumenty(13) argumenty(13, 44) </code> <code> 42 42 Jeden argument 13 Podałeś więcej niż 1 argument 13 </code> **Ćwiczenie**\\ Skrypt ''%%rzut_moneta%%'' przepisz do postaci funkcji, która może przyjąć 2 argumenty.\\ Argumenty:\\ * $p$ prawdopodobieństwo wylosowania orła. Domyślna wartość $p=0.5$ * $n$ ilość powtórzeń rzutu. Dmyślna wartość $n=1$ W przypadku braku podania argumentów funkcja zachowuje się identyczne jak pierwotny skrypt, tj. z prawdopodobieństwem $p=0.5$ wylosuje orła lub reszkę. Podanie pierwszego argumentu definiuje prawdopodobieństwo wypadnięcia orła, zaź podanie drugiego argumentu pozwala ustwaić liczbę rzutów monetą (wynik wypisywany jest $n$ razy).