Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Save this PDF as:
 WORD  PNG  TXT  JPG

Wielkość: px
Rozpocząć pokaz od strony:

Download "Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)"

Transkrypt

1 1 Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną) Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania. Wydanie VI, Helion, Jerzy Grębosz, Opus magnum C++11, Helion, 2017 B. Stroustrup, Język C++. Kompendium wiedzy. Wydanie IV, Helion, 2014 S. B. Lippman, J. Lajoie, Podstawy języka C++, WNT, Warszawa 2003.

2 Definiowanie funkcji funkcje zwracające wartość #include<iostream> using namespace std; double cube(double x); //prototyp- deklaracja funkcji int main() double q = cube(1.2); //wywołanie funkcji double side; cout << " podaj bok :"; cin >> side; cout << "Kostka o boku "<< side<< " ma pojemnosc " << cube(side) <<" cm3" <<endl;//2 wywołanie double cube(double x) //definicja funkcji return x*x*x; 2

3 Parametry funkcji i przekazywanie przez wartość double cube(double x); //prototyp C++ normalnie przekazuje parametry do funkcji przez wartość, oznacza to, że jeśli do funkcji przekazywana jest liczba, to tworzona jest nowa zmienna. Argumenty przesłane do funkcji są zatem tylko kopiami. Jakiekolwiek działanie na nich nie dotyczy oryginału. double side = 5; double vol = cube(side); Kiedy funkcja cube jest wywoływana tworzona jest nowa zmienna x typu double inicjalizowana wartością 5, cube() działa na kopii side, a nie na oryginale. 3

4 Przesyłanie argumentów przez referencję W C++ argumenty możemy przesyłać do funkcji nie tylko przez wartość ale i przez referencję, czyli przez przezwisko. #include <iostream> using namespace std; void zer(int wart, int &ref);//deklaracja int main() int a = 44, b = 77; cout << "Przed wywolaniem funkcji: a = " << a << ", b = " << b << endl; zer(a, b); //wywołanie cout << "Po powrocie z funkcji: a = " << a << ", b = " << b << endl; 4

5 Przesyłanie argumentów przez referencję void zer(int wart, int &ref) cout << "\tw funkcji przed zerowaniem \n" wart = 0; ref = 0; << "\twart = " << wart << ", ref = " << ref << endl; cout << "\tw funkcji po zerowaniu \n" << "\twart = " << wart << ", ref = " << ref << endl; 5

6 Przesyłanie argumentów przez referencję void zer(int wart, int &ref);//deklaracja W rezultacie działania tego programu na ekranie pojawi się: Przed wywolaniem funkcji: a = 44, b = 77 W funkcji przed zerowaniem wart = 44, ref = 77 W funkcji po zerowaniu wart = 0, ref = 0 Po powrocie z funkcji: a = 44, b = 0 Funkcja zer, przyjmuje dwa argumenty: pierwszy z nich jest przesyłany przez wartość, drugi natomiast przez referencję &. Widać, że argument, który funkcja przyjmowała przez wartość, nie został zmodyfikowany. Natomiast zmienna, którą funkcja odebrała przez referencję została zmodyfikowana. 6

7 Przesyłanie argumentów przez referencję void zer(int wart, int &ref);//deklaracja zer(a, b); //wywołanie dla a = 44, b = 77; W tym przypadku do funkcji zamiast liczby 77 (wartość zmiennej b) został wysłany adres zmiennej b w pamięci komputera. Ten adres funkcja sobie odebrała i (na stosie) stworzyła sobie referencję, czyli komórce pamięci o przysłanym adresie nadała pseudonim (przezwisko, alias) ref. Referencja jest inną nazwą danej zmiennej. Zatem ta sama komórka, na którą w main mówiło się b, stała się teraz w funkcji zer znana pod przezwiskiem ref. Są to dwie różne nazwy, ale określają ten sam obiekt. Zatem gdy do obiektu o przezwisku ref wpisano zero to znaczy, że odbyło się to faktycznie na obiekcie b. 7

8 8 Przesyłanie argumentów przez referencję Wniosek: przesłanie argumentów funkcji przez referencję pozwala tej funkcji na modyfikowanie zmiennych znajdujących się poza tą funkcją. Ten sposób przesyłania stosuje się m.in. do dużych obiektów, gdyż przesłanie ich przez wartość (wymagające zrobienia kopii) powodowałoby spowolnienie wywoływania takiej funkcji. W przypadku gdy taka funkcja jest wywoływana bardzo wiele razy, może to być ważnym czynnikiem. Jeszcze innym sposobem przesłania argumentu może być przekazywanie przez wskaźnik.

9 9 Przesyłanie argumentów przez referencję - przykład /*f-cja obliczająca średnią geometryczną dwóch liczb rzeczywistych sqrt(x*y), jeśli któryś argument <0 nie da się policzyć średniej => f-cja logiczna, zwraca true, gdy da się obliczyć średnią, false w przeciwnym przypadku, średnia jako dodatkowy argument */ bool sredniag(double x, double y, double &srg) if (x >= 0 && y >= 0) srg = sqrt(x*y); return true; else return false;

10 Przesyłanie argumentów przez referencję - przykład #include <iostream> #include <cmath> using namespace std; bool sredniag(double x, double y, double &srg); int main() double a = 4.9, b = 5.8; double sg; if(sredniag(x, y, sg)) cout<<"srednia geometryczna "<< sg << endl; else cout<<"nie da sie obliczyc sredniej"<<endl; if(sredniag(4, 4, sg)) cout<<"srednia geometryczna "<<sg<<endl; else cout<<"nie da sie obliczyc sredniej"<<endl; bool sredniag(double x, double y, double &srg)... 10

11 Przesyłanie argumentów przez referencję przykład 2 Napisz funkcję sumailosccyfr, która dla zadanej parametrem liczby całkowitej jako wartość zwróci sumę cyfr tej liczby i jako parametr zwróci ilość jej cyfr. int sumailosccyfr(int n, int &ilc) if (n < 0) n = -n; //wartość bezwzględna int sc = 0; //zmienna na sumę cyfr ilc = 0; //zerujemy parametr ilość cyfr //pętla do-while, bo każda liczba nawet 0 // ma przynajmniej jedna cyfra do ilc++; //zwiększamy liczbę cyfr sc += n%10; //do sumy dodajemy ostania cyfra n/=10; //pozbywamy się policzonej już cyfry while(n > 0); return sc; 11

12 Przesyłanie argumentów przez referencję przykład 2 #include <iostream> using namespace std; int sumailosccyfr(int n, int &ilc); int main() int n; cout << "Podaj liczba "; cin >> n; int ilec; int sc = sumailosccyfr(n, ilec); cout<<"suma cyfr liczby "<< n <<" wynosi "<< sc <<", a liczba cyfr = "<< ilec << endl; 12

13 Przesyłanie argumentów przez referencję przykład 2 /*Jeśli chcemy funkcję wywołać w cout to musimy pamiętać, że wyrażenia w cout są opracowywane od prawej strony. Zatem poniższe wywołanie będzie się odnosić do nieobliczonej jeszcze wartości ilec: cout << "Suma cyfr liczby "<<125<<" wynosi " << sumailosccyfr(125, ilec) << ", a liczba cyfr = "<< ilec << endl; */ //wywołanie musi być zatem przestawione: cout<< "Liczba cyfr liczby " << 125 <<" wynosi " << ilec << ", a suma cyfr = " << sumailosccyfr(125, ilec)<<endl; //main int sumailosccyfr(int n, int &ilc)//definicja 13