mgr inż. Wacław Libront * Bobowa 2019
ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu
Czym jest funkcja (procedura)? To zestaw instrukcji, które opisujemy jednym słowem, które porządkują strukturę programu przez podział na logiczne fragmenty, i które potem możemy wielokrotnie używać w programie głównym. Dzięki takiej organizacji skracamy kod programu, porządkujemy go w logicznie uporządkowane fragmenty, możemy go szybciej poprawiać oraz możemy pisać biblioteki funkcji, z których będziemy mogli korzystać w innych programach. W bibliotekach języka C++ mamy mnóstwo gotowych funkcji, na przykład wykorzystywane już pow i sqrt z biblioteki cmath.
typ nazwa (parametry){ instrukcje; return wartość; }
lub funkcja która nie zwraca żadnych wartości, tzw. procedura
void nazwa (parametry){ instrukcje;… }
Uwagi o funkcjach
Zadanie - Gwiazdki
Napisz funkcję GWIAZDKI, która „rysuje” na ekranie prostokąt z gwiazdek. Parametry funkcji
W i K – ile wierszy i kolumn. Dane wczytujemy z klawiatury w programie głównym. Zmodyfikuj program tak, aby środek prostokąta wypełniony był kropkami (brzeg z gwiazdek).
void GWIAZDKI(int W, int K){ for (int i=1;i<=W;i++){ for (int j=1;j<=K;j++) cout << "*"; cout << endl; } } void GWIAZDKI_1(int W, int K){ for (int i=1; i <= W; i++){ for (int j=1; j <= K; j++) if (i==1 || i==W || j==1 || j==K) cout << "*"; else cout << "-"; cout << endl; } } ... int wiersz,kolumna; cout << "Podaj wiersze: "; cin >> wiersz; cout << "Podaj kolumny: "; cin >> kolumna; GWIAZDKI(wiersz,kolumna); GWIAZDKI_1(wiersz, kolumna); |
Zadanie - Odległość
Oblicz odległość pomiędzy dwoma punktami A i B układu współrzędnych. Z klawiatury wpisujemy cztery wartości współrzędnych dwóch punktów A(x1,y1) i B(x2,y2).
float ODL(float x1, float y1, float x2, float y2){ return sqrt(pow(x2-x1,2)+pow(y2-y1,2)); } ... cout << ODL(1,1,3,3) << endl; |
funkcja oblicza odległość i zwraca wynik poprzez nazwę ODL
wartość odległości wyświetlana jest na ekranie konsoli
UWAGA. Ponieważ używamy funkcji matematycznych pow i sqrt, dlatego należy zadeklarować bibliotekę cmath.
Zasięg zmiennych - zmienne globalne i lokalne
Programy się komplikują, zaczynamy używać wielu zmiennych i nazwy tych zmiennych mogą się powtarzać – będą takie same w programie głównym i w funkcjach. Bez problemu można definiować zmienne o takich samych nazwach, ale powinniśmy stosować kilka zasad:
zmienne w funkcjach są lokalne, tworzone są w momencie wywołania funkcji i giną kiedy funkcja kończy działanie
zmienne w programie głównym są globalne, widoczne są też w zdefiniowanych funkcjach
zmienne zdefiniowane w funkcjach są ważniejsze niż takie same globalne
żeby nie było niejasności, to lepiej definiować zmienne i stałe w funkcjach z różnymi nazwami, na przykład dodawać dodatkowy przedrostek
Zadanie – Silnia
Napisz funkcję SILNIA z jednym parametrem N, która zwraca wartość silni. Sprawdź, czy parametr jest liczbą naturalną z przedziału 1-100.
Sprawdź działanie funkcji wypisując na ekranie wartość 5!.
Sprawdź działanie funkcji wypisując na ekranie wartości kolejnych silni dla liczb 1-100.
int SILNIA(int N){ int s=1; for (int i=1; i<=N; i++) s=s*i; return s; } int main(){ cout << SILNIA(5) << endl; } |
Przekazywanie parametrów – wartość i referencja
Przekazywanie parametrów przez wartość jest naturalne – wszystkie poprzednie funkcje tak miały – wstawialiśmy jako parametry dane, na których były wykonywane obliczenia i funkcja zwracała wynik – parametry wstawiane do funkcji nie ulegały zmianie.
Przekazywanie przez referencję daje dodatkowe możliwości – funkcja może zmieniać wartości przekazywanych do funkcji parametrów.
Po co to wszystko? Jeszcze większe możliwości dla programistów, bo funkcja może zwracać więcej niż jedną wartość i wygodniej operować złożonymi strukturami danych np. tablicami. Programowanie naprawdę się komplikuje (na własne życzenie programisty), jeśli zmienne globalne przekazywane przez referencję mają takie same nazwy jak lokalne.
void ZAMIANA_W(int x, int y){ int p=x; x=y; y=p; } void ZAMIANA_R(int &x, int &y){ int p=x; x=y; y=p; } ... int a=1; int b=2; ZAMIANA_W(a,b); cout << a << " " << b << endl; ZAMIANA_R(a,b); cout << a << " " << b << endl; |
Zadanie - Zagadka ze zmiennymi
W programie głównym zdeklarowano zmienną „i”, której nadano wartość 7. Funkcja US też posługuje się swoją wewnętrzną zmienną „i”. Ile „uśmieszków” wypisze na ekranie program?
void US(int ile){ for(int i=1;i<=ile;i++) cout<<":-)"; } ... int i=7; US(i); |
zmienna globalna i jest przekazywana do wnętrza funkcji poprzez parametr „ile”
we wnętrzu funkcji definiujemy zmienną lokalną „i” która steruje pętlą
zmienna globalna „i” w funkcji main jest przesłonięta przez zmienną lokalną „i” w funkcji US
W jaki sposób pisać programy, żeby kodować szybciej i bez błędów? Oto kilka wskazówek.
stosuj krótkie i zrozumiałe nazwy zmiennych, stałych i funkcji, np.: i, x, liczba, srednia
jeśli stosujesz dłuższe lub wielowyrazowe: NazwaZmiennej lub nazwa_zmiennej
dla zmiennych sterujących pętlami zarezerwuj i lub j
dziel program na logiczne części stosując bloki {} i funkcje
pisz swój program tak, aby był przejrzysty
stosuj osobne wiersze, wcięcia, komentarze
uczyń swój program „idiotoodpornym” – zawsze pisz, co użytkownik powinien zrobić
1) Napisz funkcje obliczające: pole powierzchni i obwód: kwadratu, prostokąta, koła, trójkąta, sześciokąta foremnego, trapezu. Wprowadź dane z klawiatury i wylicz wartości za pomocą funkcji. Sprawdź czy parametry funkcji są większe zera.
2) Napisz funkcje obliczające: pole powierzchni i objętość kuli, prostopadłościanu, stożka, ostrosłupa. Wprowadź dane z klawiatury i wylicz wartości za pomocą funkcji. Sprawdź czy parametry funkcji są większe zera.
3) Napisz funkcję KWADRATOWA, która wymaga trzech parametrów rzeczywistych: a, b, c, i która wyliczy i wypisze na ekranie pierwiastki równania kwadratowego. Jeśli równanie nie ma rozwiązań – funkcja wypisuje komunikat „brak pierwiastków”.
4) Napisz funkcję ULAMEK z jednym parametrem X, która zwraca wynik poniższego ułamka. Wylicz wartość ułamka dla kolejnych liczb naturalnych w przedziale 1..100.
5) Napisz funkcję o nazwie NEWTON z dwoma parametrami N i K, która w wyniku podaje wartość symbolu Newtona opisanego wzorem. Sprawdź, czy wpisane liczby są naturalne.
Przykładowe rozwiązania zadań
Jedynie ciężka umysłowa praca i zrozumienie działania
programu może nauczyć programowania!
//zadanie 1 double KwadratPole(double bok){ return bok*bok; } double KwadratObwod(double bok){ return 4*bok; } double KoloPole(double r){ return M_PI*r*r; } double KoloObwod(double r){ return 2*M_PI*r; } ... cout << "Wpisz liczbę: "; double liczba; cin >> liczba; cout << " Pole kwadratu=" << KwadratPole(liczba) << endl; cout << "Obwód kwadratu=" << KwadratObwod(liczba) << endl; cout << " Pole koła=" << KoloPole(liczba) << endl; cout << " Obwód koła=" << KoloObwod(liczba) << endl; cout << endl; |
//zadanie 2 double KulaPole(double r){ return 4*M_PI*r*r; } double KulaObjetosc(double r){ return 4.0/3.0*M_PI*r*r*r; } double SzescianPole(double bok){ return 6*bok*bok; } double SzescianObjetosc(double bok){ return bok*bok*bok; } ... cout << "Wpisz liczbę: "; double liczba; cout << " Pole kuli=" << KulaPole(liczba) << endl; cout << " Objętość kuli=" << KulaObjetosc(liczba) << endl; cout << " Pole Sześcianu=" << SzescianPole(liczba) << endl; cout << "Objętość Sześcianu=" << SzescianObjetosc(liczba) << endl; |
//zadanie 3 void KWADRATOWA(double a, double b, double c){ double delta=b*b-4*a*c; if (delta >= 0){ double x1=(-b-sqrt(delta))/(2*a); double x2=(-b+sqrt(delta))/(2*a); cout << "x1=" << x1 << endl; cout << "x2=" << x2 << endl; } else cout << "brak pierwiastków" << endl; } ... cout << "y(x)=x*x-3*x+2" << endl; KWADRATOWA(1,-3,2); |
//zadanie 4 double ULAMEK(int Y){ double X=Y; //return X+(X+(X+(X+(X+(X+X)/X)/X)/X)/X)/X; //albo double W; W=X+(X+(X+(X+(X+(X+X)/X)/X)/X)/X)/X; return W; } |
//zadanie 5 int SILNIA(int N){ int s=1; for (int i=1; i<=N;i++) s=s*i; return s; } int NEWTON(int N, int K){ double NE=SILNIA(N)/(SILNIA(K)*SILNIA(N-K)); return NE; } |
//zadanie 6 |
//SZABLON #include <stdlib.h> //system #include <iostream> //cout #include <iomanip> //fixed #include <cmath> //pow using namespace std; int main(){ setlocale(LC_ALL, ""); system("pause"); } |