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

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

Wstęp do informatyki- wykład 11 Funkcje

Wstęp do informatyki- wykład 9 Funkcje

Wstęp do informatyki- wykład 9 Pętla while, do while,for -pętla w pętli- przykłady Funkcje

Wstęp do informatyki- wykład 7

Podstawy algorytmiki i programowania - wykład 5 C-struktury cd.

Wstęp do informatyki- wykład 6

Podstawy algorytmiki i programowania - wykład 2 Tablice dwuwymiarowe cd Funkcje rekurencyjne

Programowanie - wykład 4

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Funkcje. Deklaracja funkcji. Definicja funkcji. Wykorzystanie funkcji w programie.

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

4. Funkcje. Przykłady

Język C++ zajęcia nr 2

Podstawy algorytmiki i programowania - wykład 4 C-struktury

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

do instrukcja while (wyrażenie);

Wstęp do informatyki- wykład 7

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

Wstęp do programowania

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 5

Część 4 życie programu

Lab 9 Podstawy Programowania

Podstawy programowania skrót z wykładów:

Programowanie w C++ Wykład 3. Katarzyna Grzelak. 12 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 35

Podstawy programowania. Wykład: 7. Funkcje Przekazywanie argumentów do funkcji. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Przekazywanie argumentów wskaźniki

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Wstęp do informatyki- wykład 5 Instrukcja selekcji if-else Operatory arytmetyczne i logiczne

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Wstęp do informatyki- wykład 8 Pętla while, do while,for -pętla w pętli- przykłady Operator rzutowania Manipulatory

void Pobierz(Student &a); void Wypisz(Student a); void Ustaw_zaliczenia(Student t[],int r); void Wypisz_najlepszych(Student t[],int r, float prog);

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.

Programowanie strukturalne i obiektowe. Funkcje

Podstawy Programowania

Wstęp do programowania

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

3. Instrukcje warunkowe

Podstawy algorytmiki i programowania - wykład 1 Tablice powtórzenie Tablice znaków Tablice dwuwymiarowe

1 Podstawy c++ w pigułce.

I - Microsoft Visual Studio C++

7. Pętle for. Przykłady

Wstęp do programowania

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com

Wstęp do Programowania, laboratorium 02

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Języki i techniki programowania Ćwiczenia 2

2. Zmienne i stałe. Przykłady Napisz program, który wypisze na ekran wynik dzielenia 281 i 117 w postaci liczby mieszanej (tj. 2 47/117).

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

Podstawy Programowania Podstawowa składnia języka C++

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Program 6. Program wykorzystujący strukturę osoba o polach: imię, nazwisko, wiek. W programie wykorzystane są dwie funkcje:

referencje Wykład 2. Programowanie (język C++) Referencje (1) int Num = 50; zdefiniowano zmienną Num (typu int) nadając jej wartość początkową 50.

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

C++ wprowadzanie zmiennych

Wstęp do programowania

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

Wykład 5: Klasy cz. 3

KURS C/C++ WYKŁAD 8. Deklaracja funkcji informuje komplilator jaką wartość funkcja będzie zwracała i jakiego typu są jej argumenty.

Zmienne, stałe i operatory

Program znajduje największa lub najmniejsza z podanych liczb. Liczby podajemy dopóki nam sie nie znudzi.

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Programowanie proceduralne w języku C++ Funkcje

Pytania sprawdzające wiedzę z programowania C++

Program 14. #include <iostream> #include <ctime> using namespace std;

Metody Metody, parametry, zwracanie wartości

Informatyka I: Instrukcja 4.2

> C++ wskaźniki. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki 26 kwietnia 2017

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

Podstawy algorytmiki i programowania - wykład 3 Funkcje rekurencyjne Wyszukiwanie liniowe i binarne w tablicy

Język C, tablice i funkcje (laboratorium, EE1-DI)

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Programowanie komputerowe. Zajęcia 1

Wstęp do programowania

C-struktury wykład. Dorota Pylak

Wstęp do informatyki- wykład 5 Instrukcja selekcji if-else Operatory arytmetyczne i logiczne Wyrażenie warunkowe operator selekcji Instrukcja switch

W dowolnym momencie można zmienić typ wskaźnika.

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Wstęp do programowania. Wykład 1

Transkrypt:

1 Wstęp do informatyki- wykład 10 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, 2012 www.cplusplus.com 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.

Funkcje wywołanie funkcji funkcje typu void Wywołanie funkcji typu void: Funkcje typu void wywołujemy w osobnej linii używając jej nazwy i podając parametry, a całość kończąc średnikiem. #include<iostream> using namespace std; void powitanie(int n); //deklaracja funkcji int main() powitanie(5); //instrukcja wywołania funkcji //na konsoli:czesc! Czesc! Czesc! Czesc! Czesc! void powitanie(int n)//definicja funkcji for(int i = 0; i < n; i++) cout << "Czesc! "; cout << endl; 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; 3

Parametry funkcji i przekazywanie przez wartość Zajmijmy się teraz sposobem przesyłania argumentów do funkcji. Najpierw jednak sprawa nazewnictwa. //definicja double cube(double x) return x*x*x; //wartość typu double nazwy które widzimy w pierwszej linijce definicji funkcji są to tzw. argumenty formalne funkcji. Czasem zwane parametrami formalnymi. 4

Parametry funkcji i przekazywanie przez wartość int main() double q = cube(3);//wywołanie funkcji w main cout << q << endl; To natomiast, co pojawia się w nawiasie w momencie wywoływania tej funkcji czyli w naszym przypadku 3 to tak zwane argumenty (parametry) aktualne. Czyli takie argumenty, z którymi aktualnie funkcja ma wykonać pracę. Często mówi się prościej: argumenty wywołania funkcji bo z tymi argumentami funkcję wywołujemy. W standardzie C++ używa się słowa argument dla określenia parametrów aktualnych, a słowa parametr dla param. formalnych. 5

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

Parametry funkcji i przekazywanie przez wartość - przykład void zwieksz(int formalny) formalny += 1000; // zwiekszenie liczby o 1000 cout << "W funkcji modyfikuje arg formalny\n\t" << " i teraz arg formalny = "<< formalny << endl; Jak widać, w tej funkcji zwiększa się wartość parametru formalnego funkcji. Funkcję tę wywołujemy na przykład w takim fragmencie programu: int main() int aktu = 2; cout << "Przed wywolaniem, aktu = " << aktu << endl; zwieksz(aktu); cout << "Po wywolaniu, aktu = " << aktu << endl; 7

Parametry funkcji i przekazywanie przez wartość Jeżeli wykonamy taki fragment programu, to otrzymamy: Przed wywolaniem, aktu = 2 W funkcji modyfikuje arg formalny i teraz arg formalny = 1002 Po wywolaniu, aktu = 2 Do funkcji przesyłamy tylko wartość liczbową zmiennej aktu (czyli argumentu aktualnego). Wartość ta służy do inicjalizacji parametru formalnego, czyli zmiennej lokalnej tworzonej przez funkcję na stosie. Jest to więc jakby zrobienie kopii w obrębie funkcji. Funkcja pracuje na tej kopii. Czyli w naszym przykładzie dodanie 1000 nie nastąpiło do komórki pamięci, gdzie tkwi aktu, ale do tej zmiennej lokalnej na stosie, gdzie mieści się kopia (o nazwie formalny). Po opuszczeniu funkcji ten fragment stosu jest niszczony, znika więc też kopia. 8

Parametry funkcji i przekazywanie przez wartość Ponieważ przy przekazywaniu parametrów przez wartość do funkcji przesyłamy tylko wartość liczbową argumentu aktualnego, to przy wywołaniu funkcji możemy w miejsce argumentów podstawiać: zainicjalizowane wcześniej zmienne albo stałe, lub wyrażenia, np.: double q = cube(1.2); //wywołanie funkcji double side = 4; cout << cube(side); 9

Funkcje definiowanie funkcji przed main() Każda nazwa przed jej użyciem musi zostać zadeklarowana. Dotyczy to też nazw funkcji. Funkcje muszą więc być deklarowane. Jednakże każda definicja (funkcji) jest także przy okazji jej deklaracją. Jeżeli więc w pliku definicja funkcji jest wcześniej (po prostu wyżej) niż linijka z jakimkolwiek wywołaniem tej funkcji, to nie trzeba osobnej deklaracji tej funkcji. Jeśli natomiast funkcja nie jest osobno deklarowana, a wywołanie następuje w linijce powyżej definicji tej funkcji, wówczas kompilator zaprotestuje komunikatem o błędzie. 10

11 Parametry funkcji i przekazywanie przez wartość - przykład //f-cja oblicza ilość cyfr danej liczby całkowitej include<iostream> using namespace std; int ilecyfr(int n) n = abs(n); int ile = 0; //licznik cyfr liczby //do while bo każda liczba ma przynajmniej 1 cyfrę do ile++; //zwiekszamy licznik n /= 10; //pozbywamy się policzonej cyfry while(n! = 0); return ile;

Parametry funkcji i przekazywanie przez wartość - przykład int main() cout<< "liczba 834 ma "<< ilecyfr(834) << " cyfr "<< endl; int liczba; cout << "podaj liczbe calkowita "; cin >> liczba; cout << "liczba "<< liczba <<" ma " << ilecyfr(liczba) << " cyfr "<< endl; 12

Parametry funkcji przekazywanie przez wartość przykład2 //funkcja zwraca najmniejsza cyfrę wśród cyfr //liczby będącej parametrem funkcji, np. 537 int mincyfra(int n) n = abs(n); int minc = n%10; //ostatnia cyfra do minc n /= 10; //skracamy ostatnia cyfra while(n > 0) int c = n%10; if(c < minc) minc = c; n = n/10; // n/=10; return minc; 13

Parametry funkcji przekazywanie przez wartość przykład2 //funkcja oblicza przybliżoną wartość ln 2 za //pomocą n początkowych wyrazów szeregu //ln2 = 1-1/2 + 1/3 1/4 +...+(-1) (n-1) 1/n //n parametr funkcji, dla n<=0 f-cja zwraca 0 include <iostream> using namespace std; double ln2(int n) double s = 0.0; for(int i = 1, zn = 1; i <= n; i++, zn = -zn) s += zn*1.0/i;// / rzeczywiste stad 1.0 return s; int main() cout << ln2(10); 14

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; 15

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; 16

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

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

Przesyłanie argumentów przez referencję Po zakończeniu działania funkcji likwiduje się śmieci: kopię zmiennej a. adres obiektu b, który to obiekt wewnątrz funkcji przezywaliśmy ref. Ten adres został zlikwidowany. ( My tracimy adres, ale np. funkcja main ma ten adres u siebie zanotowany). 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. 19

20 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;

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

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; 22

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; 23

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 24

Referencje Referencja wartość, która zawiera informacje o położeniu innej wartości w pamięci lub nośniku danych. W C++, referencje są implementowane jako oferująca mniej możliwości, ale bezpieczniejsza odmiana wskaźników. Podobnie jak i one, referencje wskazują tutaj na pewien obszar pamięci z tą różnicą, że nie mogą być modyfikowane. Do referencji można przypisać adres tylko raz, a jej dalsze używanie niczym się nie różni od używania zwykłej zmiennej. Operacje jakie wykona się na zmiennej referencyjnej, zostaną odzwierciedlone na zmiennej zwykłej, z której pobrano adres. Referencje deklaruje się jak zmienne z podaniem znaku &: TypDanych & referencja Taki zapis byłby możliwy w liście argumentów funkcji, jednak w ciele funkcji referencja musi być od razu zainicjalizowana. 25

Referencje Zapisujemy do niej adres innej zmiennej : TypDanych & referencja = innazmienna; Od tej pory można używać obu tych zmiennych zamiennie. Poniższe przypisania dadzą więc ten sam efekt: innazmienna = 9; referencja = 9; Zobaczmy działanie referencji na konkretnym przykładzie: int i = 0; int &ref_i = i; cout << i; // wypisuje 0 ref_i = 1; cout << i; // wypisuje 1 cout << ref_i; // wypisuje 1 26

l-wartości (lvalue) i r-wartości (rvalue) W instrukcji przypisania: zmienna = 50; // do zmiennej wpisujemy liczbę 50 to po obu stronach znaku = mogą stać tylko wyrażenia określonego typu. Nie można na przykład napisać tak: 50 = zmienna;//blad! Nie można wstawić czegoś do 50 Po lewej stronie znaku przypisania, musi być coś, do czego w ogóle da się cokolwiek wpisywać. Można coś wpisać do zmiennej, ale nie da się nic wpisać do liczby 50. Ogólnie mówiąc: wyrażenia, które wolno postawić po lewej stronie znaku przypisania, nazywamy l-wartościami. Wyrażenie, które nie może stać po lewej stronie (zatem tylko po prawej), nazywamy r-wartością (rvalue). 27

int a = 6, b = 40; l-wartości (lvalue) i r-wartości (rvalue) a + b = 10; // Błąd: wyrażenie (a+b) nie jest //l-wartością (jest tylko rwartoscią) a = (a + b); // Poprawnie a = (6+a) *3; // r-wartościami są wyrażenia (6+a), // 3 oraz całość (6+a)*3; L-wartość to wyrażenie oznaczające zmienną(obiekt) ( może to być sam obiekt, referencja lub wskaźnik na obiekt). Ogólniej mówiąc: L-wartość to wyrażenie określające jakieś miejsce w pamięci, którego adres można poznać. R-wartość to wartość chwilowa, obiekt tymczasowy (lub napisana dosłownie liczba), która zostaje obliczona, użyta i odtąd staje się niepotrzebna. 28

Referencje do l-wartości i r-wartości Referencje o których mówiliśmy do tej pory to przezwiska, (kolejne nazwy, aliasy) dla istniejących obiektów posiadających nazwę czyli lwartości. int obiekt; int & ref_obiektu = obiekt; //ref. do l-wartości Przed standardem C++11 dostępny był tylko ten jeden rodzaj referencji. Od C++ 11 można tworzyć tzw. referencję do r-wartości. Jest to nazwa dla obiektu tymczasowego, który sam nie ma nazwy. Aby stworzyć taką referencję używamy nie jednego ale dwóch znaków &: int && ref_rwartosci = 3+12*22; // referencja do r-wartości 29

Stałe referencje Od powyższej reguły istnieje wyjątek. Od dawna możemy tworzyć stałą referencję do typu, do której przypisujemy wartość tymczasową: const int& e = 5; // OK! Taka sytuacja została dopuszczona, aby można było w wywołaniu takiej funkcji: void funkcja(const int&); podać wartość bezpośrednio - bez tworzenia wcześniej specjalnej zmiennej i stałej referencji do niej: funkcja(5); // OK! 30

Referencje jako argumenty funkcji - przykład #include <iostream> using namespace std; void fun_przez_wartosc( int wart ) ++wart; // inkrementacja lokalnej kopii cout << "arg. przez wartosc = "<< wart <<" \n"; int main() int obj = 40; // obj jest lwartością fun_przez_wartosc(obj);//arg. przez wartosc = 41 cout << " main: obj = " << obj //main: obj = 40 fun_przez_wartosc(80+1); //arg. przez wartosc = 82 /*do funkcji odbierającej argument przez wartość można wysłać zarówno obiekt, jak i liczbę. W funkcji działamy na kopii.*/ 31

Referencje jako argumenty funkcji - przykład #include <iostream> using namespace std; void fun_ref_lwartosci(int & ref_lwartosc) cout << "fun_ref_lwartosci(" << ref_lwartosc << ")\n"; ++ref_lwartosc; // inkrementacja oryginału int main() int obj = 40; // obj jest lwartością fun_ref_lwartosci(obj);//fun_ref_lwartosci(40) cout << "w main obj = " << obj << endl; //w main obj = 41 //f-ja odbiera argument jako referencję do obiektu //- lwartości, ref_lwartosc jest aliasem obj 32

Referencje jako argumenty funkcji - przykład #include <iostream> using namespace std; void fun_ref_lwartosci(int & ref_lwart) cout << "fun_ref_lwartosci(" << ref_lwart << ")\n"; ++ref_lwart; // inkrementacja oryginału int main() int obj = 40; // obj jest lwartością fun_ref_lwartosci(obj);//fun_ref_lwartosci(40) cout << "w main obj = " << obj << endl; //w main obj = 41 /*f-ja odbiera argument jako ref. do lwartości, to ref_lwart - alias obj,a obj musi być lwartoscią */ 33

Referencje jako argumenty funkcji - przykład #include <iostream> using namespace std; void fun_ref_constlwart(const int & ref_stala_lwart) cout << "fun_ref_constlwart(" << ref_stala_lwart << ")\n"; //inkrementacja zabroniona, bo ref. jest do const int main() int obj = 40; // obj jest lwartością fun_ref_constlwart(obj); fun_ref_constlwart(80+3); //ok bo const /*funkcja ma wprawdzie dostęp do oryginalnego obiektu, ale bez możliwości modyfikowania go*/ 34

Referencje jako argumenty funkcji - przykład #include <iostream> using namespace std; void fun_ref_rwart(int && ref_wart_tymczas) cout << "fun_ref_rwart "; // inkrementacja rwartości ++ref_wart_tymczas; cout << ref_wart_tymczas; int main() fun_ref_rwart(80+4); //fun_ref_rwart 85 /*f-cja odbiera argument przez referencję do rwartości, to można jej wysłać jako argument tylko rwartości(czyli liczby, wyrażenia itd.)*/ 35