Programowanie proceduralne w języku C++ Funkcje

Podobne dokumenty
Wstęp do informatyki- wykład 11 Funkcje

Wstęp do informatyki- wykład 9 Funkcje

Wstęp do programowania

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

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

Programowanie Obiektowew języku C++ Zadania L4

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

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

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

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

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

Wstęp do programowania obiektowego, wykład 7

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

Programowanie Obiektowew języku C++ Zadania L4

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

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

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Wstęp do programowania

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

Techniki Programowania wskaźniki

Programowanie Obiektowo Zorientowane w języku C++ Klasy, pola, metody

Język C++ zajęcia nr 2

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

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.

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

Lab 9 Podstawy Programowania

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

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

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Wykład 5: Klasy cz. 3

7. Pętle for. Przykłady

Wykład 8: klasy cz. 4

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

C-struktury wykład. Dorota Pylak

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

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

Programowanie proceduralne w języku C++ Pętle, tablice

Podstawy programowania w języku C++ Zadania - dziedziczenie i polimorfizm

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

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

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

Przeciążenie (przeładowanie nazw) funkcji

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

Struktury Struktura polami struct struct struct struct

Wstęp do informatyki- wykład 7

Programowanie strukturalne i obiektowe. Funkcje

Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

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

C-struktury wykład. Dorota Pylak

PARADYGMATY PROGRAMOWANIA Wykład 4

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

4. Funkcje. Przykłady

Zmienne, stałe i operatory

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Podstawy programowania. Wykład: 8. Wskaźniki. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

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

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

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

Przekazywanie argumentów wskaźniki

Wstęp do programowania

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

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

Techniki Programowania wskaźniki 2

Szablony funkcji i szablony klas

Język C++ Różnice między C a C++

Wstęp do programowania

Rozdział 4 KLASY, OBIEKTY, METODY

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

TEMAT : KLASY DZIEDZICZENIE

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

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

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

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

Programowanie - wykład 4

Laboratorium nr 10. Temat: Funkcje cz.2.

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Typy wyliczeniowe Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

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

#include <iostream> using namespace std; void ela(int); int main( ); { Funkcja 3. return 0; }

ZASADY PROGRAMOWANIA KOMPUTERÓW

Część 4 życie programu

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 6. Karol Tarnowski A-1 p.

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Informatyka I: Instrukcja 4.2

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

Podstawy Programowania

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

Programowanie w języku C++

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

Projektowanie klas c.d. Projektowanie klas przykład

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

KLASY cz.1. Dorota Pylak

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

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

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

Transkrypt:

Programowanie proceduralne w języku C++ Funkcje Mirosław Głowacki 1 1 Akademia Górniczo-Hutnicza im. Stanisława Staszica w Ktrakowie Wydział Inżynierii Metali i Informatyki Stosowanej Katedra Informatyki Stosowanej i Modelowania Marzec 2017 / Kwiecień 2018 Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 1 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 2 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 3 / 50

Pojęcie funkcji w języku C++ Dotychczas mieliśmy do czynienia z napisanym w języku C++ kodem programu zawartym w jednej tylko funkcji o nazwie main. Jest to obowiązkowa funkcja każdego takiego programu. Wykonanie programu zaczyna się od tej funkcji niezależnie od zastosowanego paradygmatu: imperatywnego czy obiektowo zorientowanego. W ogólnym przypadku funkcja jest fragmentem kodu programu: któremu nadano nazwę, dla którego określono listę parametrów formalnych (może być pusta) i który można wykonać poprzez podanie jego nazwy oraz listy parametrów. Dane przekazywane do funkcji w miejsce parametów - czyli argumenty funkcji - są to konkretne wartości parametrów. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 4 / 50

Budowa funkcji w języku C++ Ogólny schemat funkcji języka C++ jest następujący: typzwr nazwafun ( typpar1 nazwapar1,..., typparn nazwaparn ) {... // fragmentkodu return wartzwr; } Typ wartości zwracanej typzwr jest obowiązkowy poza przypadkiem gdy funkcja nic nie zwraca. Wtedy w miejsce typzwr należy użyć słowa void oraz usunąć instrukcję return Typ zmiennej wartzwr powinien być zgodny z typem typzwr. Chociaż lista parametrów może być pusta, to nawiasy ją ograniczające są obowiązkowe Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 5 / 50

Przykład definicji funkcji Funkcja, która posiada na liście jeden tylko parametr typu zmiennoprzecinkowego i zwraca jego kwadrat wygląda następująco: double kwadrat(double var){ return var*var; } Analogiczna funkcja zdefiniowana dla typu całkowitoliczbowego zwracająca kwadrat parametru wygląda następująco: int kwadrat(int var){ return var*var; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 6 / 50

Typ wartości zwracanej Przy obecnym zawansowaniu wykładu można stwierdzić, że typem wartości zwracanej musi być typ wbudowany jak (int, char,...) lub typu void. Jeśli typem zwracanym nie jest void, to funcję nazywamy funkcją rezultatową. Jeśli jest to void, to funkcja w ogóle nie zwraca żadnej wartości - taką funkcję nazywamy funkcją bezrezultatową. void wypisz(double var){ cout << "Kwadrat parametru = " << var*var << endl;} Kompilator C++ dopuszcza brak jakiegokolwiek specyfikatora typu zwracanej wartości - domniemywany jest wtedy typ int. Nie należy jednak z tej możliwości korzystać. Typ wartości zwracanej zwany jest też po prostu typem funkcji. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 7 / 50

Lista parametrów formalnych Lista parametrów formalnych jest ujętym w okrągłe nawiasy ciągiem oddzielonych przecinkami deklaracji pojedynczych parametrów funkcji w postaci: (typ1 nazwa1, typ2 nazwa2,..., typn nazwan) Nie wolno stosować deklaracji zbiorczych: (typ nazwa1, nazwa2) Zamiast tego należy napisać: (typ nazwa1, typ nazwa2) Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 8 / 50

Lista parametrów formalnych Lista parametrów może być pusta, jednak obejmujących ją nawiasów nie można pominąć. W takim przypadku zalecane choć niekonieczne jest jawne zaznaczenie tego faktu wewnątrz nawiasów słowem kluczowym void. int fun(void); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 9 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 10 / 50

Deklaracje i definicje funkcji Zarówno definicja jak i deklaracja dostarcza kompilatorowi informacji o funkcji: jaki jest jej typ zwracany, jaka jest liczba parametrów, jaki jest typ parametrów itd. W ten sposób, za każdym razem, gdy w dalszej części tekstu programu pojawia się użycie tej funkcji, kompilator może sprawdzić: o którą z funkcji o tej samej nazwie chodzi (może być wiele funkcji o tej samej nazwie); czy wywołanie funkcji jest prawidłowe: czy liczba i typ argumentów odpowiada liczbie i typom parametrów, czy typ wartości zwracanej przez funkcje jest w danym miejscu programu akceptowalny, itd. W razie niezgodności kompilacja zostanie przerwana. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 11 / 50

Deklaracje i definicje funkcji Dlaczego definicja lub deklaracja i co to w ogóle jest deklaracja funkcji oraz do czego się przydaje? Wyobraźmy sobie następującą sytuację: void mojapierwsza(int mojint) { mojadruga(mojint); } void mojadruga(int twojint) { mojapierwsza(twojint); } W jakiej kolejności zdefiniować te funkcje? Jeśli zdefiniujemy je tak jak wyżej, to w linii drugiej kompilacja zostanie przerwana, bo nieznana jest w niej jeszcze funkcja mojadruga. Zamiana funkcji miejscami nic nie zmienia. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 12 / 50

Deklaracje i definicje funkcji I tu z pomocą przychodzi deklaracja funkcji. Uzupełnijmy nasz kod programu o jedną linię - dekrarację funkcji mojadruga : void mojadruga(int); void mojapierwsza(int mojint) { mojadruga(mojint); } void mojadruga(int twojint) { mojapierwsza(twojint); } Tym razem kod skompiluje się poprawnie. Do tego wystarczy prototyp funkcji podany w deklaracji. Zauważmy w deklaracji (linia 1) brak nazwy argumentu - jest to dopuszczalne - konieczny jest jego typ. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 13 / 50

Deklaracje i definicje funkcji Deklaracja ma formę nagłówka funkcji, po którym następuje średnik zamiast ciała (treści) funkcji. Na przykład poprawnymi deklaracjami funkcji są string funstr(char c1, char c2, bool); void fun2(int, double); static int funstat(int i, float f); Deklaracje stanowią podstawę prototypu funkcji i zawierają informacje o: nazwie, typie zwracanym, typie i liczbie parametrów Jest to wszystko, czego potrzebuje kompilator, aby sprawdzić formalną prawidłowość ich użycia. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 14 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 15 / 50

Używanie funkcji Mając zdefiniowanych szereg różnych funkcji można się nimi do woli posługiwać. Funkcje mogą być wywoływane praktycznie z dowolnego miejsca innych funkcji. Sposób użycia jest bardzo prosty - należy podać jej nazwę i listę argumentów. nazwafun(arg1,..., argn); Jeśli funkcja deklaruje konkretny typ zwracany typzwr to rezultat może (ale nie musi) zostać przypisany zmiennej: nazwazmiennej = nazwafun(arg1,..., argn); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 16 / 50

Przykład użycia funkcji Stwórzmy funkcję sumującą liczby z pewnego zakresu: int suma(int from, int to){ int suma = 0; for (int i = from; i <= to; i++) suma += i; return suma; } Przykład użycia tej funkcji: int main(){ int min, max; cout << "Podaj zakres liczb: "; cin >> min >> max; cout << "Suma liczb od " << min << " do " << max << " wynosi " << suma(min, max) << endl; return 0; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 17 / 50

Wywołanie funkcji Wywołanie funkcji ma postać nazwy tej funkcji z podaną w nawiasach okrągłych listą oddzielonych przecinkami argumentów. Liczba argumentów wywołania musi być dokładnie taka jak liczba parametrów w deklaracji i definicji funkcji. Nawet jeśli funkcja jest bezparametrowa, nawiasy musimy podać. Rolę argumentów mogą pełnić dowolne wyrażenia, których wartość jest typu zgodnego z zadeklarowanym typem odpowiedniego parametru funkcji. int main(){ int nsr = 7; cout << "Suma = " << suma(nsr-3, 2*(nSr+3)) << endl; return 0; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 18 / 50

Wywołanie funkcji Typ argumentu nie musi być identyczny z typem parametru: wywołanie będzie prawidłowe, jeśli wartość argumentu można niejawnie przekształcić na wartość zadeklarowanego typu parametru. Jeśli przy takiej konwersji może być tracona informacja (konwersja zawężająca), to zazwyczaj podczas kompilacji otrzymamy ostrzeżenia. Jeśli funkcja zwraca rezultat, to ostatnią wykonywaną instrukcją musi być zawsze instrukcja return zwracająca: wartość typu, jaki został zadeklarowany jako typ funkcji, albo typu, który może być niejawnie przekształcony do typu funkcji. double fun(int x){return x*x;} int main(){ double arg = 3.; cout << fun(arg) << endl; return 0;} Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 19 / 50

Wywołanie funkcji Proces wywoływania możemy sobie wyobrażać tak: 1 Obliczane są wartości argumentów, po czym dokonywane są konwersje potrzebne do przekształcenia tych wartości w wartości typu odpowiedniego parametru funkcji 2 Tak uzyskane wartości kopiowane są na stos programu. 3 Jeśli argumentem była zmienna, to na stos kładziona jest kopia jej wartości - funkcja uzyskuje wtedy dostęp do tej kopii. 4 Sterowanie przechodzi do funkcji: kopie wartości argumentów na stosie są utożsamiane ze zmiennymi lokalnymi odpowiadającymi poszczególnym parametrom funkcji. 5 Zmienne lokalne (definiowane w funkcji) umieszczane są również na stosie. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 20 / 50

Wywołanie funkcji 6 Po zakończeniu wykonywania funkcji część stosu ze zmiennymi lokalnymi (również tymi odpowiadającymi parametrom funkcji), jest usuwana, tak aby stan stosu odpowiadał temu sprzed wywołania. 7 Jeśli funkcja jest rezultatowa, to wynik jest zwracany do funkcji wywołującej poprzez stos lub inną metodą. Wyjątek w przedstawionej procedurze stanowią zmienne definiowane z modyfikatorem static. Takie zmienne tworzone są raz: podczas pierwszego wywołania. Przy kolejnych wywołaniach funkcja ma dostęp do tej samej zmiennej statycznej - istnieje ona aż do zakończenia programu. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 21 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 22 / 50

Parametry domyślne funkcji W C++ istnieje możliwość definiowania funkcji o domyślnych (domniemanych) wartościach parametrów. Wywołując taką funkcję nie trzeba podawać wszystkich parametrów - dla niektórych przyjęta zostanie wartość domyślna w razie ich pominięcia. Aby skorzystać z tej możliwości, definiujemy funkcję, określając wartości domyślne dla parametrów funkcji bezpośrednio w nagłówku. Muszą to być końcowe parametry - jeśli któryś z parametrów ma wartość domyślną, to wszystkie parametry występujące na liście parametrów po nim też muszą mieć przypisane wartości domyślne. Wartości domyślne można przypisać tylko raz - jeśli zrobimy to w deklaracji, to nie powtarzamy tego ani w definicji, ani w innych ewentualnych deklaracjach. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 23 / 50

Parametry domyślne funkcji Przykładowo, albo: void poletrojkata(double a = 1., double h = 1.){ cout << "Pole trojkata = " << a * h / 2. << endl; } albo void poletrojkata(double = 1., double = 1.); void poletrojkata(double a, double h){ cout << "Pole trojkata = " << a * h / 2. << endl; } ale nie: void poletrojkata(double = 1., double = 1.); void poletrojkata(double a = 1., double h = 1.){ cout << "Pole trojkata = " << a * h / 2. << endl; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 24 / 50

Parametry domyślne funkcji A teraz zobaczmy jak działa idea parametrów domyślnych - program: void poletrojkata(double a = 1., double h = 1.){ cout << "Pole trojkata = " << a * h / 2. << endl; } int main(){ poletrojkata(); poletrojkata(3.7); poletrojkata(3.1, 4.25); return 0; } powoduje strumień wyjściowy: Pole trojkata = 0.5 Pole trojkata = 1.85 Pole trojkata = 6.5875 Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 25 / 50

Parametry domyślne funkcji Jeśli zmienimy kod programu: void poletrojkata(double a, double h){ cout << "Pole trojkata = " << a * h / 2. << endl; } int main(){ poletrojkata(1., 1.); poletrojkata(3.7, 1.); poletrojkata(3.1, 4.25); return 0; } to strumień wyjściowy będzie identyczny: Pole trojkata = 0.5 Pole trojkata = 1.85 Pole trojkata = 6.5875 Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 26 / 50

Parametry domyślne funkcji Parametry funkcji zadeklarowane jako obowiązkowe można przedeklarować tak, aby miały wartości domyślne - deklaracja: void kolor(int rd, int gr, int bl, int alf = 255); może zostać uzupełniona następną deklaracją (lub definicją): void kolor(int rd, int gr, int bl = 0, int alf); Każdy parametr domyślny może być w ten sposób deklarowany tylko raz i wszystkie parametry domyślne muszą kończyć listę. void kolor(int rd = 0, int gr, int bl, int alf); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 27 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 28 / 50

Odnośniki (referencje) Referencja w swym działaniu przypomina wskaźniki - zawiera adres istniejącej uprzednio zmiennej. Różnica polega jednak na tym, że do referencji można przypisać adres tylko raz, a jej dalsze używanie niczym się nie różni od używania zwykłej zmiennej. Przypisanie referencji adresu jest obowiązkowe - referencje muszą być inicjalizowane. TypDanych & referencja = innazmienna; Można się pokusić o stwierdzenie, że: Referencja jest inną nazwą danej zmiennej. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 29 / 50

Odnośniki (referencje) Operacje jakie wykona się na referencji, zostaną odzwierciedlone na zmiennej zwykłej, z której pobrano adres. #include <iostream> using namespace std; int main(){ double dbl = 41.66; double &refdbl = dbl; refdbl = 1.345; cout << "dbl wynosi " << dbl << endl; return 0; } Wynikiem działania programu jest strumień wyjściowy: dbl wynosi 1.345 Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 30 / 50

Parametry odnośnikowe Odnośniki mogą być parametrami i wartościami zwracanymi przez funkcje. Co to znaczy, jeśli parametr funkcji jest zadeklarowany jako odnośnik? Popatrzmy na funkcję: void funvar(int varint){ varint = varint + 2;} void funref(int& refint){ refint = refint + 2;} int main(){ int fi = 0; funvar(fi); int si = 0; funref(si); cout << "fi = " << fi << " si = " << si << endl; return 0; } Wynikiem działania tej funkcji jest strumień wyjściowy: fi = 0 si = 2 Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 31 / 50

Praca z parametrami odnośnikowymi Instrukcja: void funref(int& refint); oznacza, że argument typu int zostanie przesłany do funkcji przez odniesienie (referencję). Jeśli wywołamy tę funkcję podając jako argument pewną zmienną typu int, to w czasie wykonania funkcji nazwa parametru refint będzie inną nazwą dokładnie tej samej zmiennej. A więc nie będzie kopiowania wartości na stos - zmienna lokalna w funkcji w ogóle nie będzie tworzona. Nazwa refint będzie odnosić się do oryginału zmiennej będącej argumentem wywołania i funkcja będzie pracować na tym oryginale. Stąd też zmiany refint wewnątrz funkcji funref powodują zmiany zmiennej si w funkcji main. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 32 / 50

Argumenty a parametry odnośnikowe Mając powyższe na uwadze nie uda się kompilacja kodu programu: 1. void funref(int& refint){ 2. refint = refint + 2;} 3. int main(){ 4. funref(1); 5. int mi = 12; funref(3 * mi); 6. double md; funref(md); 7. return 0; } ze względu na brak możliwości zdefiniowania referencji do: literału (linia 4) wyrażenia (linia 5) czy zmiennej innego typu (linia 6) Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 33 / 50

Odnośnikowa wartość zwracana Odniesienie może nie tylko być parametrem, ale i wartością zwracaną przez funkcję. Następująca deklaracja: int& fun(int); oznacza, że funkcja zwraca pewną zmienną przez odniesienie (referencję). Stąd też wyrażenie fun(3) jest inną nazwą pewnej istniejącej zmiennej, która została podana w funkcji w instrukcji return. Zmienna taka musi istnieć po zakończeniu pracy funkcji. Czyli wywołanie funkcji - fun(int) - można potraktować jako wynik działania tej funkcji. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 34 / 50

Odnośnikowa wartość zwracana Wynika stąd ważny wniosek - jeśli wartością zwracaną jest odniesienie, to instrukcja return takiej funkcji nie może zwracać: literału wyrażenia zmiennej lokalnej, bo przestaje ona istnieć po zakończeniu funkcji. int& funref(int& refint){ int rint; refint = refint + 2; return 0; return 2*refInt+3; return rint; return refint; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 35 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 36 / 50

Wskaźniki Na początek musimy zdefiniować pojęcie wskaźnika do zmiennej. O ile zmienna jest w stanie przechowywać wartości danego typu, o tyle wskaźnik przechowuje: adres obszaru pamięci, gdzie dopiero jest zapisana wartość, informację o typie zmiennej zapisanej w tym obszarze. double zmdbl; double *wskdbl; // zmienna typu double // wskaźnik typu double Nowopowstały wskaźnik nie odwołuje się do żadnego konkretnego adresu Wymaga zatem inicjalizacji lub podstawienia z wykorzystaniem operatora pobrania adresu & double zmdbl = 125.52; // inicjalizacja zmiennej double *wskdbl = &zmdbl; // inicjalizacja wskaźnika Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 37 / 50

Wskaźniki Pobranie wartości spod adresu przypisanego wskażnikowi następuje przy użyciu operatora wyłuskania * cout << "Wartosc: " << *wskdbl << endl; Bez użycia operatora wyłuskania, zostanie wyświetlona wartość zmiennej wskaźnikowej wskdbl czyli adres zmiennej zmdbl Bardzo ważne jest aby nie korzystać ze wskaźnika, który nie wskazuje na żadną zmienną. Prowadzi to zawsze do błędów i niesie ze sobą nieprzewidziane konsekwencje. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 38 / 50

Przykład użycia wskaźnika Przypadki użycia wskaźnika: int telefon = 12345345; int *wsk = &telefon; cout << *wsk << endl; cout << wsk << endl; cout << &wsk << endl; // zmienna typu int // przypisanie wskaźnikowi // adresu zmiennej telefon // wyświetlenie wyłuskanej // wartości wskaźnika // (12345345) // wyświetlenie adresu // zmiennej telefon // wyświetlenie adresu // wskaźnika cout << &telefon << endl; // wyświetlenie adresu // zmiennej telefon Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 39 / 50

Wskaźniki jako parametry funkcji Kiedy należy przekazać do funkcji odwołanie do obiektu zezwalające na jego modyfikację wewnątrz funkcji to mamy do wyboru dwie metody: posłużenie się referencją, posłużenie się wskaźnikiem. Pierwszą z metod omówiliśmy już wyczerpująco, a co jeśli chodzi o wskaźniki? Jeśli argument funkcji jest zadeklarowany jako wskaźnik czy też wartość zwracana przez funkcję jest wskaźnikiem, to zachowanie funkcji jest analogiczne do sytuacji, w której były to referencje. Różnica polega na fakcie, że w przeciwieństwie do referencji wskaźniki nie muszą (ale powinny) być inicjalizowane. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 40 / 50

Wskaźniki jako parametry funkcji Popatrzmy na funkcję: int* funpoint(int* wskint){ *wskint = *wskint + 2; return wskint; } int main(){ int x = -7., *p = &x; p = funpoint(p); cout << "*p= " << *p << endl; return 0; } Jak widać jej postać jest podobna do tej, używającej odniesień - składnia jest tylko nieco inna, ze względu na zastosowanie typu wskaźnikowego int* w miejsce typu int&. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 41 / 50

Arytmetyka wskaźników #include <iostream> using namespace std; int main(){ // deklaracja i inicjalizacja tablicy double waga[5] = { 55.3, 747.8, 1001.2, 5.2, 6.4 }; double *wsk = waga; // nazwa tablicy jest wskaźnikiem cout << " wsk = " << wsk << endl; // adres cout << " *wsk = " << *wsk << endl; // 55.3 cout << " wsk[4] = " << wsk[4] << endl; // 6.4 cout << " *(wsk + 3) = " << *(wsk + 3) << endl; // 5.2 wsk += 1; cout << " *wsk = " << *wsk << endl; // 747.8 cout << " *++wsk = " << *++wsk << endl; // 1001.2 cout << " rozmiar wsk = " << sizeof(wsk) << endl; // 4 cout << "rozmiar *wsk = " << sizeof(*wsk) << endl; // 8 return 0; } Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 42 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 43 / 50

Przekazywanie tablic do funkcji Popatrzmy na kod programu: double funsuma(double tbl[], int rozmtab){ double suma = 0.; for(int i = 0; i < rozmtab; i++) suma += tbl[i]; return suma; } int main(){ double tabdbl[10] = {1,2,3,4,5,6,7,8,9,10}; cout << "Suma elementow tablicy " << funsuma(tabdbl, 10) << endl; return 0; } Jak widać do funkcji przekazywana jest tylko nazwa tablicy - jej rozmiar musi być przekazany przy pomocy oddzielnego parametru. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 44 / 50

Przekazywanie tablic do funkcji Innym sposób przekazywania tablic do funkcji przedstawia kod programu, który tylko w niewikim stopniu różni się od poprzedniego: double funsuma(double* tbl, int rozmtab){ double suma = 0.; for(int i = 0; i < rozmtab; i++) suma += tbl[i]; return suma; } Tym razem parametrem funkcji jest wskaźnik, ponieważ nazwa tablicy jest stałym wskaźnikie do jej pierwszego elementu. Wewnątrz funkcji nazwą wskaźnika można się posługiwać tak jak każdą inną nazwą tablicy. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 45 / 50

Spis treści 1 Pojęcie funkcji 2 Deklaracje i definicje funkcji 3 Używanie funkcji 4 Parametry domyślne funkcji 5 Parametry odnośnikowe (referencje) 6 Wskaźniki jako parametry funkcji 7 Przekazywanie tablic do funkcji 8 Przeciążanie funkcji Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 46 / 50

Przeciążanie funkcji Funkcje można w C++ przeciążać (przeładowywać). Oznacza to sytuację, gdy w tym samym zakresie leksykalnym są widoczne różne definicje funkcji o tej samej nazwie. Wszystkie wersje funkcji muszą się wystarczająco różnić - na tyle, aby można było jednoznacznie wybrać jedną z nich na podstawie wywołania. Warunkiem koniecznym, choć niewystarczającym jest, aby funkcje o tej samej nazwie różniły się sygnaturą. Do sygnatury funkcji należy: jej nazwa oraz liczba i typ parametrów nie licząc tych z wartościami domyślnymi. Typ funkcji, czyli typ wartości zwracanej, do sygnatury nie należy. Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 47 / 50

Przeciążanie funkcji Sygnatury nie są jeszcze warunkiem dostatecznym na legalność przeciążenia. Widzimy to na przykładzie funkcji void fun(int i); void fun(int& i); Obie funkcje różnią się sygnaturą, ale wywołanie: int mint; fun(mint); może być traktowane jako wywołanie zarówno pierwszej, jak i drugiej z nich. Natomiast prawidłowe jest przeciążenie: int fun(int i); int fun(int* i); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 48 / 50

Przeciążanie funkcji Argument typu T może być użyty przy wywołaniu funkcji z parametrem typu T, const T i volatile T, więc funkcje przeciążone nie mogą się różnić tylko modyfikatorem typu takiego parametru double fun(int mint); double fun(const int mint); double fun(volatile int mint); Natomiast typy parametrów T*, const T* i volatile T* (i analogicznie T&, const T& i volatile T& ) są wystarczająco różne, gdyż patrząc na wywołanie funkcji kompilator może stwierdzić, czy użyta tam zmienna była ustalona lub ulotna (typu volatile ) czy nie. double fun(int* pint); double fun(const int* pint); double fun(volatile int* pint); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 49 / 50

Przeciążanie funkcji Do tej pory zwracaliśmy uwagę na jedynie typ parametrów funkcji. Wydaje się to oczywiste, ale trzeba zwrócić uwagę na fakt, że kompilator potrafi również rozróżnić sygnatury, gdy: różna jest liczba parametrów, liczba parametrów jest ta sama i są one parami tych samych typów, ale umieszczone są na liście w różnej kolejności Widać to na przykładzie poprawnych i błędnych przeciążeń funkcji: void fun(double d, int i, bool b); void fun(double, int, bool); void fun(double d, int i); void fun(int i, double d); void fun(int it, double dbl); void fun(int* i, double d); Mirosław Głowacki (AGH, UJK) Programowanie w języku C++ 2017/2018 50 / 50