Processing math: 100%
  • Funkcje
    • Ćwiczenia
  • Trochę więcej szczegółów
    • Typy
    • Ćwiczenia
    • Typy — pułapki
    • Ćwiczenia
  • Funkcje po raz drugi
    • Ćwiczenia
  • Instrukcja warunkowa
    • Ćwiczenia

Funkcje

Pewne zestawy operacji, przykładowo zależne od zmiennych, możemy zebrać w grupy (funkcje) i wywoływać tak jak circle() i line(). Przykład z poprzedniego ćwiczenia możemy zamknąć w funkcji:

void obrazek(int h, int r) {
  line( 10, 0, 0, h);
  line( 10, 0, 2 * r, h);
  circle( 10 + r, h, r);
}

Pierwsza linia deklaruje funkcję, która jest zależna od dwóch parametrów: h i r. Taką funkcję, możemy przykładowo wywołać tak: obrazek(100, 50);. Spowoduje to wykonanie powyższych trzech operacji dla h=100 i r=50.

Pamiętaj: Nową funkcję napisz przed funkcją main.

W funkcji main wywołujemy funkcję obrazek, tak jak circle czy line:

void main() {
    graphics(200, 200);
    obrazek(100, 50);   
    wait();
}

Ćwiczenia

Napisz i wywołaj dowolne dwie z poniższych funkcji:

  • prostokat(x, y, a, b) — Rysuje prostokąt o bokach a i b i środku w (x,y).
  • kwadrat(x, y, r) — Rysuje kwadrat o boku 2r, środku w (x,y) i wpisane koło o promieniu r.
  • ludzik(x, y, h) — Rysuje ludzika o wysokości h i środku głowy w (x,y).
  • olimpiada(x,y) — Rysuje koła olimpijskie o środku w (x,y).
  • okno(a) — Używając funkcji do rysowania prostokąta rysuje okno o boku a.

Trochę więcej szczegółów

Omówmy pewne rzeczy trochę dokładniej.

Typy

W C i C++ musimy deklarować zmienne, tzn. musimy powiedzieć, jakich będziemy używać zmiennych i jakich będą one typów. Deklaracje piszemy typ zmienna1, zmienna2, ...;. Najważniejsze typy to:

  • int — Liczba całkowita (32-bitowa, od 231 do 231).
  • float — Liczba zmiennoprzecinkowa. Może opisywać ułamki dziesiętne z ok. 7 cyframi znaczącymi (32-bity)
  • double — Liczba zmiennoprzecinkowa. Ma 16 cyfr znaczących (64-bity).

Pamiętaj: Jeśli używasz liczb rzeczywistych (a nie całkowitych), używaj typu double.

Pierwszym przykładem niech będzie:

double a;
a = 0;

while (a < 2 * 3.14) {
    circle(a * 100, sin(a) * 100 + 100, 3);
    a = a + 0.001;
}

Program ten, za pomocą kółek o promieniu 3, narysuje wykres funkcji sinus przeskalowany o 100.

Ćwiczenia

Używając analogicznej pętli, wykonaj dowolne dwa z poniższych zadań:

  • Narysuj wykres a2.
  • Narysuj punkty o współrzędnych x=100sina+100 i y=100cosa+100.
  • Narysuj punkty o współrzędnych x=100sinacos4a+100 i y=100cosacos4a+100.
  • Narysuj punkty o współrzędnych x=100rsina+100 i y=100rcosa+100, gdzie r=cosa+23 (niech r będzie kolejną zmienną).

Typy — pułapki

Ważne, aby pamiętać, że liczby bez przecinka dziesiętnego, są uważane za całkowite, tzn. wykonywane są na nich działania tak jak dla liczb całkowitych. Dlatego 1/4 da jako wynik 0! Wynik 0.25 zostanie obcięty do liczby całkowitej. Żeby tego uniknąć, możemy napisać 1.0/4 lub jeszcze lepiej 1.0/4.0. Możemy także bezpośrednio ‘rzutować’ zmienną z typu int na typ double pisząc: (double) zmienna.

Pamiętaj: Wszędzie, gdzie robisz obliczenia, używaj double. Unikaj mieszania liczb całkowitych i zmiennoprzecinkowych. Nigdy nie pisz ułamków jako 1/3!

Ćwiczenia

Przeanalizuj (i przetestuj) wynik tego programu. Które linie nie dadzą pożądanego efektu?

double a;
a = 0;

while (a < 2) {
    circle(a * 100, sin(a * 3.14) * 100 + 100, 3);
    circle(a * 100, sin(a * (314 / 100)) * 100 + 100, 3);
    circle(a * 100, sin((a * 314) / 100) * 100 + 100, 3);
    a = a + 0.001;
}

Funkcje po raz drugi

Zestawy operacji, które powtarzamy w programie wielokrotnie, możemy zamknąć w funkcjach. Taka funkcja ,,połyka’’ parametry i coś z nimi robi. Dla przykładu:

void kreski(int n, double r) {
  int i;
  i = 0;
  
  while (i < n) {
    line(i, 0, i, r * i);
    i = i + 1;
  }
}

W pierwszej linii mówimy:

  • jak nazywa się funkcja — kreski,
  • jakie ma parametry — n typu int i r typu double,
  • jakiego typu zwraca wartość — w naszym wypadku void oznacza, że nic nie zwraca.

Gdy gdziekolwiek w funkcji main użyjemy wywołania kreski(20, 0.4); jako efekt działania funkcji otrzymamy 20 pionowych kresek o długości od 0 do 0.419 (dlaczego 19 a nie 20?).

Taką funkcję możemy wykonać wielokrotnie dla różnych wartości n i r:

void main() {
  graphics(200,200);

  kreski(10, 1.000);    
  kreski(20, 0.500);    
  kreski(30, 0.333);    
  kreski(40, 0.250);    

  wait();
}

Ćwiczenia

Napisz i wywołaj dwie spośród niżej wymienionych funkcji:

  • Funkcja, która narysuje ludzika wysokości h i środku głowy w (x,y).
  • Funkcja, która w pętli narysuje tłum (używając poprzedniej funkcji).
  • Funkcja, która narysuje n kółek w punkcie (x,y) o coraz większych promieniach.
  • Funkcję, która narysuje wielokąt foremny o n bokach.

Instrukcja warunkowa

Kolejnym bloczkiem składowym programowania, jest instrukcja warunkowa. Sprawdza ona warunek i wykonuje pewną część kodu, gdy tylko warunek jest spełniony.

double x, y;
x = 2.0;

if (x > 0) {
  y = sqrt(x);
} else {
  y = 0;
}

Instrukcje te sprawdzają czy x>0 i jeśli jest to prawdą, wstawiają x do zmiennej y. Gdy warunek nie jest spełniony, wykonywana jest część po else, więc wstawiane jest 0 do y. W ten sposób możemy zabezpieczyć się na przykład przed niemożliwymi obliczeniami, albo uzależnić działanie programu od jakiś wartości.

Zobaczmy prosty przykład:

double a;
a = 0;

while (a < 2 * 3.14) {
  if (a < 2) {
    circle(sin(a) * 100 + 100, cos(a) * 100 + 100, 5);
  } else {
    circle(sin(a) * 100 + 100, cos(a) * 100 + 100, 10);
  }
  
  a = a + 0.001;
}

Gdyby nie instrukcja if, ten program narysował by koło z małych kółek. Teraz, gdy kąt a przekroczy 2 radiany, zmieni promień kółeczka z 5 na 10

Ćwiczenia

Napisz program który:

  • Dla parametru w rysuje wykres x2w, przeskalowany o 100 w obu kierunkach i przesunięty na środek okna (patrz poprzedni przykład).
  • Narysuje większe kółka w miejscach przecięcia wykresu z osią x (jeżeli przecina).
  • Zmodyfikuj program aby działał dla dowolnych a, b, c i funkcji ax2+bx+c.