====== 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]]
type pole_kola
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
help pole_kola
'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 ' 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.
pole_kola
r = 5
pole = 78.540
whos
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
===== 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]]
function pole = pole_kola2(r)
% Skrypt wyznacza pole koła o promieniu r
pole = pi * r^2;
end
pole_kola2(5)
ans = 78.540
podstawienie wyniku z funkcji
pole = pole_kola2( 3 );
printf('Pole koła o promieniu 3 wynosi %f\n', pole);
Pole koła o promieniu 3 wynosi 28.274334
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}}
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
objetosc_stozka(1, 3)
ans = 3.1416
===== 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**
x = -1
if x < 0
printf('Wartość %f jest mniejsza od zera\n', x);
end
x = -1
Wartość -1.000000 jest mniejsza od zera
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
5 < 3 % porównywanie liczb
4 == 3 + 1
'z' < 'a' % porównywanie znaków
3 ~= 4
x = 1 == 2
ans = 0
ans = 1
ans = 0
ans = 1
x = 0
===== 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 |
x = 42; y = 3;
x < y && y > 5
x > y || y - 1 == x
xor(x > y, 'b' < 'a')
~x
xor(1, true)
ans = 0
ans = 1
ans = 1
ans = 0
ans = 0
===== Instrukcja if else =====
**if** warunek\\
instrukcje wykonane, gdy warunek jest prawdziwy\\
**else**\\
instrukcje wykonane, gdy warunek nie jest prawdziwy\\
**end**
x = 42
if mod(x, 2) == 0
printf('Liczba %d jest parzysta', x);
else
printf('Liczba %d jest nieparzysta', x);
end
x = 42
Liczba 42 jest parzysta
**Ć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**
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
x = 42
Liczba 42 jest większa lub równa 10
===== Pętla while =====
**while** warunek\\
instrukcje wykonywane dopóki warunek jest prawdziwy\\
**end**
x = 1
while x < 10
printf('%d ', x);
x = x + 1;
end
x = 1
1 2 3 4 5 6 7 8 9
===== 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 $ab$ 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**
for i=[3 5 7]
printf('Pole koła o promieniu %f wynosi %f\n', i, pole_kola2(i));
end
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
===== Instrukcje zagnieżdzone =====
Przykład: tabliczka mnożenia
% tabliczka mnożenia
n = 10
for i=1:n
for j=1:n
printf('%3d ', i*j);
end
printf('\n');
end
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
===== 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
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
Liczba 11 jest liczbą pierwszą
for n=1:20
if n == 13
continue
end
printf('%d ', n)
end
1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20
===== 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]]
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
argumenty
argumenty()
argumenty(13)
argumenty(13, 44)
42
42
Jeden argument
13
Podałeś więcej niż 1 argument
13
**Ć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).