Spis treści

Funkcje, skrypty i instrukcje sterujące

Skrypt

Przykład: skrypt 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 <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.
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


Przykład: 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 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.

 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:

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$

  1. jeżeli $a=b$ to $a$ jest największym wspólnym dzielnikiem. Zakończ program
  2. jeżeli $a<b$ to podstaw do $b$ wartość $b-a$ i wróć do punktu 1
  3. 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

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

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 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:

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).