wykład 8 Agata Półrola Wydział Matematyki i Informatyki UŁ semestr zimowy 2018/2019
Podprogramy Czasami wygodnie jest wyodrębnić jakiś fragment programu jako pewną odrębną całość umożliwiają to podprogramy. języki programowania oferują często dwa rodzaje podprogramów: funkcje i procedury
Różnica miedzy procedurami i funkcjami (w językach z oboma rodzajami podprogramów): funkcja zazwyczaj operuje na pewnych argumentach (nie modyfikując ich) i zwraca pewną obliczoną wartość (jedną) procedura zazwyczaj operuje na pewnych argumentach, może je modyfikować i w ten sposób zwrócić pewną wyliczoną wartość lub wartości Funkcje i procedury zazwyczaj umieszcza się je w części deklaracyjnej programu lub w odrębnej jednostce kompilacyjnej
Podprogramy w C++ w C/C++ mamy tylko funkcje funkcje C/C++ mogą działać jak procedury lub jak funkcje z poprzedniego slajdu, zależnie od podania argumentów i od typu zwracanej wartości
Przykład (Program z funkcją) # include <iostream > using namespace std ; void szczekanie ( int i); // ----------------------- int main () int ile ; cout << " program PIES. podaj liczbe > "; cin >> ile ; szczekanie ( ile ); return 0; // --------------------------- void szczekanie ( int i) for ( int k =1; k <=i; k=k +1) cout << "hau - hau \n";
Każda funkcja: ma nazwę, która ją identyfikuje zwraca wynik pewnego typu ma pewne parametry (argumenty) wywołujemy ją za pomocą nazwy przed pierwszym wywołaniem funkcji wymagana jest jej deklaracja. Definicja funkcji (jej ciało, czyli treść) może nastąpić dalej.
Deklaracja funkcji Składnia deklaracji: typ wyniku nazwa funkcji ( lista parametrów ); Przykłady deklaracji: double pole_kwadratu ( int bok ); int fun ( int p1, float p2, char p3); void f( int a); char funkcja (); int zlicz ( void ); Słowo void oznacza, że funkcja nie zwraca żadnej wartości lub nie ma żadnych argumentów. Nazwa funkcji z pustymi nawiasami oznacza, że funkcja nie ma żadnych argumentów Puste nawiasy również oznaczają że funkcja jest bezparametrowa (nie przyjmuje argumentów) funkcje nie zwracające wartości są podobne do procedur w językach programowania w których dostępne są oba rodzaje podprogramów
Przykład (Funkcja bezparametrowa nie zwracająca wartości) # include <iostream > using namespace std ; void wizytowka (); // to samo co void wizytowka ( void ) // ------------------------------------- int main () wizytowka (); // nie " wizytowka ; " return 0; // ------------------------------------- void wizytowka () cout << " Jan Kowalski \n" " programista C ++\n";
Nazwy argumentów umieszczone w nawiasach deklaracji funkcji są nieistotne dla kompilatora i można je pominąć. Typów pominąć nie można Przykład (Równoważne deklaracje) int potega ( int podstawa, int wykladnik ); int potega (int, int );
Wywołanie funkcji przez inną funkcję W czasie wykonywania funkcji może nastąpić wywołanie innej funkcji wykonywanie bieżącej funkcji jest wówczas chwilowo przerywane, a rozpoczyna się wykonanie drugiej z funkcji. Po zakończeniu jej wykonania sterowanie wraca do pierwszej funkcji, do miejsca w któym zostało przerwane funkcja wywoływana przez inną funkcję nie musi być zdefiniowana przed wywołaniem (jej ciało może być jeszcze w tym miejscu nieznane ), ale deklaracja funkcji musi już być znana kompilatorowi (tj. nazwa, typ wyniku i typy argumentów)
Zwracanie wyniku zwracanie wartości funkcji odbywa się za pomocą instrukcji return postaci return zwracany wynik ; wykonanie instrucji return kończy działanie funkcji (dalsze jej instrukcje, jeśli istnieją, nie są wykonywane) jeśli typ wyrażenia zwracany wynik nie zgadza się z typem wyniku podanym w deklaracji funkcji, to zwracany wynik jest odpowiednio konwertowany, o ile jest to możliwe
Przykład (Oddzielna deklaracja i definicja) # include <iostream > using namespace std ; // ************************************* int minimum ( int a, int b); // ************************************* int main () int n1,n2; cout << " podaj liczbe "; cin >> n1; cout << " podaj druga liczbe "; cin >> n2; cout << " mniejsza wartoscia jest " << minimum (n1,n2) << "\n"; return 0; int minimum ( int a, int b) if (a<b) return a; else return b;
Przykład (Połączona deklaracja i definicja) # include <iostream > using namespace std ; // ************************************* int minimum ( int a, int b) if (a<b) return a; else return b; // ************************************* int main () int n1,n2; cout << " podaj liczbe "; cin >> n1; cout << " podaj druga liczbe "; cin >> n2; cout << " mniejsza wartoscia jest " << minimum (n1,n2) << "\n"; return 0; %------------------------------------------------
Przykład (Funkcja wywołująca inną funkcję -cz.1) # include <iostream > # include <cmath > using namespace std ; // ------------------------------------------- bool czy_trojkat ( double a, double b, double c); double obwod_trojkata ( double a, double b, double c); double pole_trojkata ( double a, double b, double c); // -------------------------------------------- int main () double b1,b2,b3, pole ; cout << " podaj dlugosci pobow trojkata "; cin >> b1 >> b2 >> b3; if ( czy_trojkat (b1,b2,b3)) pole = pole_trojkata (b1,b2,b3); cout << " pole trojkata wynosi " << pole << ", jego obwod to " << obwod_trojkata (b1,b2,b3) << "\n"; else cout << " liczby nie moga byc bokami trojkata \n"; return 0; // ---------------------------------
Przykład (Funkcja wywołująca inną funkcję - cz.2 (cd)) // --------------------------------- bool czy_trojkat ( double a, double b, double c) if (a <=0 b <=0 c <=0) return false ; if (a+b>c && a+c>b && b+c > a) return true ; else return false ; // --------------------------------- double obwod_trojkata ( double a, double b, double c) return a+b+c; // ---------------------------------- double pole_trojkata ( double a, double b, double c) double p,w; p = obwod_trojkata (a,b,c) /2; w = sqrt (p*(p-a)*(p-b)*(p-c)); return w;
Funkcja main() Główną funkcją programu (wykonywaną gdy uruchamiamy program) jest funkcja main() postaci int main () /*... kod programu... */ return 0; zwrot wartości 0 (do systemu operacyjnego który uruchomił program) oznacza pomyślne zakończenie wykonania
Zmienne globalne i lokalne Możemy zdefiniować pewne zmienne, które są dostępne (widoczne) we wszystkich funkcjach danego programu. Są to tzw. zmienne globalne. użycie wielu zmiennych globalnych utrudnia kontrolę nad ich wartościami Zmienne zadeklarowane wewnątrz funkcji (w jej ciele) są zmiennymi lokalnymi tej funkcji zmienne definiowane wewnątrz funkcji są zazwyczaj przechowywane na tzw. stosie (ang. stack; obszarze podręcznym, zazwyczaj o szybszym dostępie); zmienne globalne są zazwyczaj przechowywane na tzw. stercie (ang, heap; zazwyczaj o wolniejszym dostępie)
nazwa (zmienna) zdefiniowana poza ciałem jakiejkolwiek funkcji ma zasięg globalny (jest dostępna we wszystkich funkcjach programu) lokalne nazwy (zmienne) są widoczne tylko wewnątrz funkcji w których zostały zdefiniowane w obu przypadkach dana nazwa widoczna jest tylko poniżej linii w której została zdefiniowana konsekwencje: funkcja nie może się odwołać do zmiennych lokalnych innej funkcji dwie funkcje mogą mieć zmienne lokalne o takich samych nazwach
Parametry formalne i aktualne Argumenty (parametry) podane w definicji funkcji nazywamy argumentami formalnymi (parametrami formalnymi) Przykład double obwod_trojkata ( double a, double b, double c) return a+b+c; a, b i c to parametry formalne
Parametry formalne i aktualne Argumenty użyte przy wywołaniu funkcji nazywamy argumentami aktualnymi (parametrami aktualnymi) Przykład cout << obwod_trojkata ( b1, b2, b3) ; b1, b2 i b3 to parametry aktualne