Prowadzący: mgr inż. Elżbieta Majka

18
Zachodniopomorskie Centrum Edukacyjne Prowadzący: mgr inż. Elżbieta Majka Semestr 2

description

Programowanie strukturalne i obiektowe. Semestr 2. Prowadzący: mgr inż. Elżbieta Majka. Funkcja. Każda funkcja posiada trzy własności: zwraca dane (lub nie( void ) jeśli tego nie chcemy); posiada swoją nazwę; - PowerPoint PPT Presentation

Transcript of Prowadzący: mgr inż. Elżbieta Majka

Page 1: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Prowadzący: mgr inż. Elżbieta Majka

Semestr 2

Page 2: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Funkcja

Każda funkcja posiada trzy własności:

• zwraca dane (lub nie(void) jeśli tego nie chcemy);

• posiada swoją nazwę;

• może posiadać dowolną ilość parametrów

wejściowych (lub może nie mieć żadnego(void),

jeśli tego nie chcemy).

Jedynym wyjątkiem co do wartości zwracanego

typu jest brak możliwości zwrócenia danych

w postaci tablicy!

Page 3: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Ogólna budowa funkcji

zwracany_typ_danych nazwa_funkcji(parametry_funkcji){  //blok funkcji → co funkcja będzie robiła  return(wartosc_zwracana);}

Wszystkie zadeklarowane zmienne wewnątrz funkcji lub w parametrach funkcji są widoczne tylko i wyłącznie w obrębie funkcji(zmienne funkcji są dla niej prywatne). Ich modyfikacja nie wpływa na wartości zmiennych poza obrębem funkcji. Parametry funkcji możesz traktować jak zwykłe zmienne wewnątrz funkcji, które różnią się tylko tym, że mają przypisaną wartość podaną podczas wywołania funkcji.

Page 4: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Co ważnego powinniśmy wiedzieć o funkcjach• Każda funkcja musi mieć unikatową nazwę w obrębie całego

programu (są odstępstwa ale o tym później);• Parametry funkcji oddzielone są przecinkami;• Słowo kluczowe void informuje kompilator, że funkcja nie

zwraca żadnych danych.• Słowo kluczowe void użyte w miejscu definiowania

parametrów funkcji informuje kompilator, że funkcja nie przyjmuje żadnych parametrów;

• Parametrom funkcji można przypisywać domyślne wartości, które zostaną użyte wtedy gdy podczas jej wywołania parametr nie zostanie uzupełniony;

• Funkcja może zwracać wszystkie dopuszczalne typy – liczby całkowite, zmiennoprzecinkowe, wskaźniki, struktury i obiekty;

• Za pomocą parametrów możemy przekazywać również tablice.

Page 5: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Deklaracja i wywoływanie funkcji

FunkcjaFunkcja

int x=9,y=6,wynik;

wynik = suma(x,y);

Prototyp funkcjiPrototyp funkcji

int Funkcja1(int, char);

Funkcja2(int, char);

void Funkcja3(int, char);

int Funkcja4(void);

int Funkcja5();

typ_zwracanej_wartości nazwa_funkcji(lista argumentów formalnych);

int f1(int a, char b);

Argumenty aktualne

Pisząc deklarację funkcji możemy dodatkowo pisać nazwy dla parametrów. Są one jednak ignorowane przez kompilator i pełnią tylko i wyłącznie rolę informacyjną dla użytkownika. Zamiast bloku głównego na końcu deklaracji funkcji jest średnik.

Page 6: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Funkcje - powtórzenie

FunkcjaFunkcja

#include<iostream.h>

int suma(int,int);//prototyp

void main(){

int x=9,y=6,wynik;

wynik = suma(x,y);

cout<<wynik;

}

//definicja funkcji

int suma(int a,int b){

int w = a+b;

return w;

}

FunkcjaFunkcja

#include<iostream.h>

//definicja funkcji jest

jej //prototypem

int suma(int a,int b){

int w = a+b;

return w;

}

void main(){

int x=9,y=6,wynik;

wynik = suma(x,y);

cout<<wynik;

}

Page 7: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Funkcje – przekazywanie argumentów

• Przez wartość:int x=2,y=3;

int suma(int,int); … int w = suma(x,y);

• Przez adres:int x=2,y=3;

int suma(int *,int); … int w = suma(&x,y);

Page 8: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Funkcje – przekazywanie argumentów

• Przez referencjęint x=2,y=3;int &z=a;

int suma(int &,int); … int w = suma(z,y);

• Argumenty tablicoweint x=2,y[5];int suma(int, int *); //int suma (int, int

[]); … int w = suma(z,y);

Page 9: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Biblioteki

Page 10: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Poznajemy dyrektywę #include na nowoWraz z rozwojem każdego programu kodu przybywa, a poruszanie się po nim staje się coraz bardziej uciążliwe ze względu na jego długość. Staramy się grupować tematycznie większość funkcji w programie, jednak i to niewiele daje, gdy przychodzi pracować z kodem, który ma co najmniej 1000 wierszy. Z pomocą przychodzi tu dyrektywa #include.

Język C++ to zbiór logicznych zasad umożliwiających programowanie. Same zasady umożliwiają zarządzać danymi, jednak nie są one wystarczające do tego, aby wykorzystywać w łatwy sposób możliwości sprzętowe komputera. Ponieważ język C++ umożliwia łatwe organizowanie danych, to oczywistym też jest, że równie potrzebnym elementem jest interfejs, umożliwiający prezentację danych oraz interfejs reagujący na wszystkie urządzenia, jakie posiadamy w komputerze (np. mysz, klawiaturę, kartę graficzną, kartę sieciową itd.).

Zadaniem dyrektywy #include jest umożliwienie łatwego wykorzystywania zasobów sprzętowych komputera, poprzez dołączanie plików nagłówkowych bibliotek, które są odpowiedzialne za komunikację z różnymi urządzeniami. Innymi słowy za każdym razem, gdy korzystamy z dyrektywy #include, dołączamy do swojego programu interfejs umożliwiający łatwy dostęp do wybranych zasobów komputera. Za pomocą tego polecenia można w łatwy sposób pisać serwery TCP/UDP, używać OpenGL'a, czy też innych modułów umożliwiających łatwy dostęp do sprzętowych zasobów komputera.

Oprócz dołączania istniejących bibliotek, dyrektywa pozwala dołączać własne biblioteki. Dzięki tej własności możemy zorganizować swój kod źródłowy lepiej, a wszelkie modyfikacje kodu staną się szybsze i łatwiejsze.

Page 11: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Ustawianie ścieżki do pliku nagłówkowego1. Do tej pory gdy chcieliśmy dołączyć bibliotekę do programu,

stosowaliśmy tylko i wyłącznie zapis

#include <ścieżka do pliku>.

Użycie ostrych nawiasów <...> informuje kompilator, aby przeszukiwał domyślne ścieżki, w których znajdują się pliki nagłówkowe.

Jeśli kompilator nie odnajdzie żądanego pliku nagłówkowego, kompilator zwróci błąd informując, że pliku o podanej nazwie nie znaleziono.

2. Drugą metodą na dołączanie plików nagłówkowych jest wykorzystanie zapisu 

#include "ścieżka do pliku".

Zapis z użyciem podwójnych apostrofów informuje kompilator, że plik nagłówkowy ma być poszukiwany tylko i wyłącznie względem aktualnego katalogu, w którym znajduje się nasz projekt.

Page 12: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Rozszerzenia plików i ich znaczenie

Pliki *.h (dla C) i *.hpp (dla C++), są nazywane plikami nagłówkowymi (ang. header files).Każdy plik nagłówkowy powinien zawierać tylko i wyłącznie interfejs. Przez słowo interfejs rozumiemy:•deklaracje typów•deklaracje funkcji•deklaracje struktur•deklaracje klas•deklarację ewentualnych zmiennych globalnych

Dodatkowo dołączamy do niego niezbędne pliki nagłówkowe, jakie będą wykorzystywane przez daną bibliotekę. W pliku nagłówkowym nie umieszczamy natomiast bloków funkcji. Można powiedzieć po prostu, że w pliku nagłówkowym umieszczamy wszystko oprócz bloków funkcji.

Page 13: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Rozszerzenia plików i ich znaczenie

Pliki *.c i *.cpp nazywamy plikami źródłowymi. Jak nietrudno domyślić się, *.c oznacza standard użytego języka C, natomiast *.cpp standard użytego języka C++. W plikach z takim rozszerzeniem umieszczamy tylko i wyłącznie definicje funkcji, czyli nazwę funkcji razem z jej ciałem (czyli blokiem funkcji).

Page 14: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Budowa pliku nagłówkowego *.h *.hpp

• Istnieje co najmniej kilka wersji budowy plików nagłówkowych dla języka C i C++. Niektóre z nich nie działają jednak pod wszystkimi kompilatorami

#ifndef nazwaPliku_hpp#define nazwaPliku_hpp/*  tutaj piszesz cały interfejs*/#endif

Page 15: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Budowa pliku nagłówkowego *.h *.hpp

• Opis dyrektyw preprocesora

Page 16: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Budowa pliku nagłówkowego *.h *.hpp

Zaprezentowany przykład czytamy następująco:• #ifndef dowolna_nazwa // jeśli nie istnieje dowolna_nazwa,

wykonuj blok

• #define dowolna_nazwa //utwórz zmienną o nazwie dowolna_nazwa

• #endif //koniec bloku warunkowego

Wykorzystując instrukcje preprocesora zabezpieczamy bibliotekę przed wielokrotnym dołączaniem tego samego kodu do własnego programu. Jeśli go nie użyjemy, a dołączymy tą samą bibliotekę co najmniej dwukrotnie w programie (nawet w różnych plikach), otrzymamy błąd kompilacji nawet jeśli wszystko będzie poprawnie napisane. Nazwy zmiennych, które definiujemy za pomocą preprocesora muszą być unikatowe podczas kompilacji projektu dla każdego używanego pliku, tak więc w każdym pliku musi się znajdować inna nazwa zmiennej preprocesora. Najpopularniejszą metodą zapewnienia sobie unikatowych nazw zmiennych, jest używanie nazwy pliku dla zmiennej preprocesora. Nie jest to jednak obowiązek i mamy tu praktycznie pełną dowolność. Nazwy zmiennych preprocesora mają takie same kryteria dla nazewnictwa jak zmienne języka C++.

Page 17: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Budowa pliku źródłowego *.c *.cpp

Plik źródłowy ma bardzo prostą budowę. Jedyne co musimy zrobić to dołączyć plik nagłówkowy pliku, który opisuje interfejs jaki znajduje się w tym pliku.#include "nazwaPliku.hpp"/*tutaj piszesz definicje funkcji*/Jeśli będziemy kompilowali plik *.cpp i nie będzie w nim żadnych błędów, otrzymamy następujący błąd kompilacji:[Linker error] undefined reference to `WinMain@16‘ ld returned 1 exit statusKomunikat ten informuje, że w programie nie ma 'ciała' programu, czyli głównej funkcji programu. Ponieważ pliki, które utworzyliśmy nie mają być programem, tylko źródłem dołączanym do programu, który będzie zawierał funkcję main(), wskazane jest aby ten plik nie zawierał funkcji o którą 'doczepił się' kompilator. Dołączając natomiast plik nagłówkowy (*.hpp) do programu głównego za pomocą dyrektywy #include, uzyskamy w pełni sprawny kod, który się kompiluje (pod warunkiem, że nie ma w nim innych błędów).

Page 18: Prowadzący: mgr inż. Elżbieta Majka

Zachodniopomorskie Centrum Edukacyjne

Szybki przykład

//Plik: main.cpp#include <iostream>#include <conio.h>#include "nazwaPliku.hpp"using namespace std;int main(){  cout<<"Wynik dodawania to: "<<dodajLiczby(10,15)<<endl;  getch();  return(0);}

-------------------------------------------------------------------

//Plik: nazwaPliku.hpp#ifndef nazwaPliku_hpp#define nazwaPliku_hpp

int dodajLiczby(int a,int b);

#endif

//Plik: nazwaPliku.cpp#include "nazwaPliku.hpp"

int dodajLiczby(int a,int b){  return(a+b);}