Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Podstawy programowania PP – WYK3 Wojciech Pieprzyca.

Podobne prezentacje


Prezentacja na temat: "Podstawy programowania PP – WYK3 Wojciech Pieprzyca."— Zapis prezentacji:

1 Podstawy programowania PP – WYK3 Wojciech Pieprzyca

2 Funkcje Funkcja jest częścią programu spełniającą określone zadanie. Cały program zwykle składa się z wielu funkcji (podprogramów). Pozwala to podzielenie programu na wiele mniejszych, niezależnych fragmentów. Funkcja może na wejściu przyjąć dowolną liczbę argumentów. Każda funkcja musi zwrócić na wyjściu jakąś wartość. W szczególności, gdy nie istnieje potrzeba zwracania żadnej konkretnej wartości, zwracana jest tzw. wartość pusta typu void.

3 Definicja funkcji Definicja funkcji polega na określeniu typu zwracanego przez funkcję, jej nazwy oraz listy argumentów. W ramach definicji określa się również działanie funkcji tzw. ciało funkcji. typ nazwa(lista argumentów) { ciało funkcji return typ; } Lista argumentów może być pusta () lub też przyjąć dowolnie wiele wartości: (typ zm1,typ zm2,…, typN zmN) Każdy argument musi mieć określony swój typ i nazwę. Zwracana wartość określana jest po słowie return. Typ zwracanej wartości musi zgadzać się z typem podanym w nagłówku funkcji.

4 Przykłady void funkcja1() Funkcja nie zwracająca żadnej wartości i nie przyjmująca żadnych argumentów. void funkcja2(int x) Funkcja nie zwracającą żadnej wartości i przyjmującą jeden argument wartość x typu całkowitego. int funkcja3(float x) Funkcja zwracająca wartość całkowitą i przyjmująca jako argument wartość x typu rzeczywistego. double funkcja4(int x, char y) Funkcja zwracająca wartość rzeczywistą i przyjmująca jako argumenty wartość x typu całkowitego i wartość y typu znakowego.

5 Przykład funkcji – wzór Herona float Heron (float a, float b, float c) { float p = (a+b+c)/2; return sqrt(p*(p-a)*(p-b)*(p-c)); } Int main() { float a,b,c; cout << Podaj a: ; cin >> a; cout << Podaj b: ; cin >> b; cout << Podaj c: ; cin >> c; cout << Pole trojkata = << Heron(a,b,c); }

6 Uwagi do programu Program oblicza pole trójkąta zgodnie ze wzorem podanym przez Herona. Obliczanie pola odbywa się w funkcji o nazwie Heron. Funkcja ta przyjmuje trzy argumenty, którymi są długości boków trójkąta a,b,c. Wszystkie te wartości są typu rzeczywistego float. Jako typ zwracanej wartości również określono typ rzeczywisty float. Zwrot wartości funkcji następuje poprzez instrukcję return. Wartość ta określana jest poprzez wzór sqrt(p*(p-a)*(p- b)*(p-c)). Funkcja główna w naszym programie zapytuje użytkownika o długości boków a,b,c po czym przekazuje je jako argumenty wejściowe do funkcji Heron. Funkcja Heron z kolei zwraca obliczoną wartość pola trójkąta, która w funkcji main jest wyświetlana na ekranie.

7 Przekazywanie argumentów przez wartość (I) Argumenty do funkcji mogą być przekazywane na dwa sposoby: 1.Przez wartość, 2.Przez referencję. Najpierw omówimy sposób przekazywania zmiennej przez wartość. Przekazywanie przez wartość charakteryzuje się tym, iż do funkcji nie jest przekazywany oryginał podawanej zmiennej, a jedynie kopia jej wartości. Konsekwencją tego faktu jest to, że jakiekolwiek zmiany dokonane na zmiennej w ramach funkcji są ważne tylko do jej zakończenia. Po zakończeniu funkcji, wszelkie odwołania do zmiennej będą wskazywać na oryginalną, niezmienioną wartość.

8 Przekazywanie argumentów przez wartość (II) void zmien(int liczba) { liczba = liczba+5; cout << Liczba w funkcji: << liczba << endl; } int main() { int liczba = 10; cout << Liczba przed wywolaniem funkcji: << liczba << endl; zmien(liczba); cout << Liczba po wywolaniu funkcji: << liczba << endl; } Wynikiem działania programu będzie wyświetlenie wartości 10,15,10. Wynika to z tego, że zmieniona wartość liczby widoczna jest tylko w ramach funkcji zmien.

9 Przekazywanie argumentów przez referencję (I) W przypadku przekazywanie argumentu przez referencję do funkcji nie trafia sama wartość argumentu, tylko adres komórki pamięci w której ta wartość się znajduję. Wszelkie odwołania w ramach funkcji odnosić się zatem będą do oryginalnej zawartości zmiennej. Należy zatem zauważyć, że w przypadku przekazywania argumentów przez referencje, wszelkie zmiany dokonywane na zmiennych będą widoczne także po zakończeniu funkcji. Przekazywanie argumentów przez referencję uzyskuje się poprzedzając w nagłówku funkcji nazwy zmiennych znakiem ampersand (&). Samo wywołanie takiej funkcji pozostaje bez zmian.

10 Przekazywanie argumentów przez referencję (II) void zmien(int &liczba) { liczba = liczba+5; cout << Liczba w funkcji: << liczba << endl; } int main() { int liczba = 10; cout << Liczba przed wywolaniem funkcji: << liczba << endl; zmien(liczba); cout << Liczba po wywolaniu funkcji: << liczba << endl; } Wynikiem działania programu będzie wyświetlenie wartości 10,15,15. Bierze się to stąd iż operacje w funkcji były wykonywane na oryginalnej zawartości zmiennej liczba.

11 Funkcję operujące na tekście (1) Pod pojęciem tekstu rozumiemy w tym przypadku ciąg znaków nazywany także łańcuchem tekstowym. Tekst przechowywany jest w postaci tablicy znaków. Przykład deklaracji takiej tablicy znajduje się poniżej: char tekst[20]; W tej tablicy możemy zapisać do 20 znaków. Do zapisu może posłużyć nam funkcja strcpy kopiująca podany tekst do miejsca docelowego np. strcpy(tekst,Przykladowy krotki tekst); Każda litera tekstu zapisana jest w osobnej komórce tablicy. Oznacza to, że do pierwszej litery możemy odwołać się pisząc tekst[0]. Należy pamiętać o tym, że tablice w C++ są numerowane od 0, a więc indeksy dla tablicy 20 elementowej rozpoczynają się od 0 a kończą na 19.

12 Funkcję operujące na tekście (2) Możliwa jest także inicjalizacja (przypisanie tekstu) do tablicy znakowej już w trakcie jej deklaracji np. char tekst[20] = Super tekst; Także bez podawania wielkości tablicy takie przypisanie będzie poprawne, wówczas rozmiar tablicy zostanie dostosowany do rozmiaru podanego tekstu np. char tekst[] = Super tekst; W tym przypadku tekst składa się z 11 znaków i taki też będzie rozmiar tablicy. Do łączenia tekstów (tzw. konkatenacja) służy funkcja strcat. Składnia: strcat(tekst1, tekst2); Przykład: tekst = strcat(kot,w butach);

13 Funkcję operujące na tekście (3) Długość łańcucha tekstowego można sprawdzić za pomocą funkcji strlen(napis). Przykład: char tekst[20] = WSIiZ; cout << strlen(tekst); Powyższy przykład wyświetli liczbę 5 oznaczającą długość podanego tekstu WSIiZ. Brany jest zatem pod uwagę nie rozmiar samej tablicy w której przechowywany jest tekst, ale efektywna długość samego ciągu znaków. Kolejna funkcja to strcmp(tekst1,tekst2). Sprawdza ona czy podane dwa teksty są identyczne. Jeżeli tak to zwraca wartość 0, w przeciwnym razie wartość różną od 0. Przykład: if (strcmp(tekst,ala)==0) cout << Zmienna tekst to ala;

14 Funkcję operujące na tekście (4) Funkcja strstr(tekst1,tekst2) poszukuje ciągu znaków tekst2 w tekst1. Jeżeli tekst zostanie znaleziony to funkcja zwróci wskaźnik do pierwszego wystąpienia tekstu, jeżeli tekst nie zostanie odnaleziony to funkcja zwróci 0. Przykład: if (strstr(tekst,ala)!=0) cout << Zmienna tekst zawiera napis ala; Ponieważ funkcja wczytującą dane z klawiatury do zmiennej (cin) potrafi operować tylko na pojedynczym wyrazie (bez spacji) to wprowadzono dodatkową funkcję gets (get string – czyli pobierz ciąg znaków). Funkcja ta ma postać: gets(zmienna) i powoduje zapis do zmiennej całego tekstu wpisanego z klawiatury. Przykład: cout << Podaj imie i nazwisko; gets(dane); cout << dane;

15 Funkcje rekurencyjne (1) Rekurencja dotyczy przypadków, gdy funkcja wywołuje samą siebie ze swego wnętrza. Oczywiście takie cykliczne wywołanie musi mieć swój koniec, dlatego każda funkcja rekurencyjna posiada warunek zakończenia, kiedy to nie wywołuje się funkcji, a zwraca jakąś konkretną wartość. Przykładem zastosowania funkcji rekurencyjnej może być obliczanie silni. Silnia to iloczyn kolejnych liczb naturalnych od 1 do n, gdzie n to wartość dla której chcemy obliczyć silnię: 0! = 0 1! = 1 n! = n*(n-1)!

16 Funkcje rekurencyjne (2) Funkcja obliczająca silnię wygląda następująco: int silnia(int n) { if (n==1) return 1; return n*silnia(n-1); } Jak widzimy, wewnątrz funkcji wywołuje ona samą siebie. Różni się jedynie argument przekazywany do funkcji, który za każdym wywołaniem pomniejszany jest o jeden (n-1). Warunkiem kończącym ciąg wywołań funkcji jest wartość n=1 (co zajdzie wówczas, gdy do funkcji zostanie przekazana wartość 1).

17 Funkcje rekurencyjne (3) Przeanalizujmy ciąg wywołań dla obliczenia wartości 5!. Pierwotne wywołanie silnia(5) silnia(1) = 1 silnia(n) = n*silnia(n-1), dla n>1 a zatem: silnia(5) = 5*silnia(4) = 5*4*silnia(3) = 5*4*3*silnia(2) = = 5*4*3*2*silnia(1) = 5*4*3*2*1 = 120

18 Tablice (1) Tablica jest ciągiem danych złożonym z elementów tego samego typu. Kolejne elementy tablicy zajmują kolejne komórki w pamięci operacyjnej. Elementy tablicy numerowane są od zera (0) !!! Deklaracja typu tablicowego: typ nazwa[liczba_elementow]; Przykłady deklaracji: int liczby[5]; char znaki[10]; float tab[12];

19 Tablice (2) Sama deklaracja tablicy danych nie przyporządkowuje jej żadnych konkretnych wartości, a jedynie rezerwuje odpowiednio wielki obszar pamięci operacyjnej na te dane. Tablice mogą być tworzone z następujących elem. : typów podstawowych (int, float, double, char, itp.), typów wyliczeniowych, wskaźników, innych tablic, klas obiektów,

20 Tablice (3) Tablica zadeklarowana jako: int liczby[5]; składa się z 5 elementów zawierających wartości typu całkowitego tj. int. Do poszczególnych elementów możemy odnieść się przy użyciu indeksów: liczby[0] – pierwszy element tablicy, liczby[1] – drugi element tablicy, liczby[2] – trzeci element tablicy, liczby[3] – czwarty element tablicy, liczby[4] – piąty element tablicy. Jak widzimy, dla tablicy pięcioelementowej, pierwszy element tablicy ma indeks 0, a ostatni indeks 4.

21 Tablice (4) Wartości poszczególnym elementom tablicy możemy nadać poprzez zwykły operator przypisania: liczby[0] = 10; liczby[1] = 13; liczby[2] = 7; liczby[3] = 13; liczby[4] = 2; W szczególności już w czasie deklaracji typu tablicowego możemy dokonać jednoczesnego przypisania danych do tablicy: Int liczby[5] = {10, 13, 7, 13, 2}

22 Tablice (5) Operacje tablicowe wykonywane są często z użyciem pętli for. Wynika to z tego, że zazwyczaj znana jest liczba elementów tablicy, a zatem pętla for doskonale nadaje się do tego typu zadań. Przykład wyświetlający 10 elementów tablicy liczbowej: int tab[10] = {2,4,6,8,11,13,15,17,19,21}; for (int i=0; i<10; i++) cout << Element << i << = << tab[i] << endl;

23 Tablice (6) Przykład wyświetlający 10 elementów tablicy liczbowej w odwrotnej kolejności: int tab[10] = {2,4,6,8,11,13,15,17,19,21}; for (int i=9 i>=0; i--) cout << Element << i << = << tab[i] << endl; Przykład wyświetlający co drugi element tablicy liczbowej: int tab[10] = {2,4,6,8,11,13,15,17,19,21}; for (int i=0; i<10; i=i+2) cout << Element << i << = << tab[i] << endl;

24 Tablice (7) Tak jak wspomnieliśmy na początku, elementy tablicy umieszczone są jako kolejne komórki pamięci. Rozmiar tych komórek jest uzależniony od typu danych umieszczonych w tablicy. Przykładowo rozmiar jednego elementu typu całkowitego int wynosi 4 bajty. 10 elementowa tablica liczb zajmować będzie zatem 40 bajtów. Przy założeniu, że komórki zajmować będą miejsce w pamięci od adresu x, ich rozmieszczenie będzie następujące: adres x – pierwsza komórka z elementem tab[0] x+4 – druga komórka z elementem tab[1] x+8 – trzecia komórka z elementem tab[2] … x+36 – dziesiątą komórka z elementem tab[9] Podobnie byłoby w przypadku innych typów danych, należałoby jedynie zmienić rozmiar komórek.

25 Tablice (8) Poniższy program wyświetla adresy kolejnych komórek pamięci w których umieszczono elementy tablicy zawierającej 10 liczb całkowitych. int tab[10] = {2,4,6,8,11,13,15,17,19,21}; for (int i=0; i<10; i++) cout << Element << i << = << (long)&tab[i] << endl; Adres elementu wyznaczany jest za pomocą operatora &. Ponieważ domyślnie zwracana jest liczba w notacji szesnastkowej (heksadecymalnej) dodatkowo dokonujemy konwersji na typ long.

26 Tablice wielowymiarowe (1) Tablice wielowymiarowe w przypadku dwóch wymiarów można porównać do macierzy elementów, które znamy z matematyki albo do współrzędnych dwuwymiarowego układu kartezjańskiego XY. Tablica trójwymiarowa z kolei może być utożsamiona np. z punktem w przestrzeni 3D o współrzędnych (x,y,z). Tablice o więcej niż 3 wymiarach są raczej rzadkością, gdyż korzystanie z nich jest kłopotliwe. Deklaracja tablicy wielowymiarowej ma następującą składnię: typ nazwa[rozmiar_wymiaru_1][rozmiar_wymiaru_2]…[rozmiar_wymiaru_N]; Przykładowo: int tab[2][3] – macierz liczb 2x3, int tab[2][2][2] – trójwymiarowa przestrzeń liczbowa o rozmiarach 2x2x2.

27 Tablice wielowymiarowe (2) Dwuwymiarowa tablica liczb 2x3 (macierz 2x3) x11 x12 x13 x24 x25 x26 Do poszczególnych elementów możemy odwołać się w następujący sposób: tab[0][0] tab[0][1] tab[0][2] tab[1][0] tab[1][1] tab[1][2] Jak widać, pierwszy indeks wskazuje na wiersz w którym znajduje się dany element, a drugi indeks na kolumnę.

28 Tablice wielowymiarowe (3) Przykładowy program będzie wyświetlał zawartość tablicy dwuwymiarowej o rozmiarze 2x3. Wykorzystamy w tym celu zagnieżdżoną pętlę for. Pierwsza z pętli for operująca indeksem i porusza się po wszystkich wierszach (i=0,1). Druga pętla for wykorzystująca indeks j porusza się po wszystkich kolumnach (j=0,1,2). int tab[2][3] = { {1,2,3},{4,5,6} }; for (int i=0; i<2; i++) for (int j=0; j<3; i++) cout << Element [ << i << ][ << j << = << tab[i][j] << endl;

29 Tablice znakowe Tablice znakowe jak wskazuje sama nazwa przechowują ciągi znaków. Tablica znakowa o z góry zadeklarowanym rozmiarze nie zawsze ma wypełnione wszystkie komórki. Koniec tekstu (ciągu znaków) oznaczany jest w tablicy za pomocą wartości NULL. char tekst[20]; W tej tablicy możemy zapisać do 20 znaków. Każda litera tekstu zapisana jest w osobnej komórce tablicy. Oznacza to, że do pierwszej litery możemy odwołać się pisząc tekst[0].


Pobierz ppt "Podstawy programowania PP – WYK3 Wojciech Pieprzyca."

Podobne prezentacje


Reklamy Google