Loading...
Kurs c++

LEKCJA 10 Funkcje, po co ich używać? Jak je konstruować, w czym pomagają? | poziom 3

Kurs C++

Czym jest funkcja?

Prawdopodobnie nie wiesz, ale funkcji używasz nieświadomie w każdym programie.
Zwróć uwagę na pierwsze linijki kodu w twoich dotychczasowych programach, a w szczególności int main()”. Jest to nic innego jak funkcja. Można ją określić mianem funkcji głównej, ponieważ jest ona uruchamiana automatycznie po starcie programu.(Jeśli pisałeś kiedyś strony WWW, to odpowiada ona plikowi index.html)
Pozostałe funkcje są czymś w rodzaju podprogramu. Wykonują określoną rzecz i zwracają nam wynik.

Na przykład: jeśli chcemy policzyć, jaką powierzchnię łącznie zajmuje kilka figur; dwa różne koła i trzy trójkąty. Zamiast wykonywać pięć osobnych obliczeń dla każdej figury, możemy stworzyć dwie funkcje pole_kolo () i pole_trojkat (), które po otrzymaniu wymiarów liczą i zwracają nam gotowy wynik, a naszym zadaniem w głównym programie jest tylko dodanie tych wartości (a i do tego na upartego można zrobić osobną funkcję :D)

Po co korzystać z funkcji w C++?

Używanie funkcji ma kilka zalet. Po pierwsze raz napisanego kodu możemy używać dowolną ilość razy, omijając metodę kopiuj/wklej, która powoduje podwojenie kodu.
Po drugie zyskujemy na przejrzystości kodu, która nabiera znaczenia wraz z objętością programu.
Po trzecie daje nam to przywilej korzystania z tzw. zmiennych lokalnych i globalnych, do których wrócimy za chwilę.

Budowa, wywołanie i argumenty funkcji.

Szkielet funkcji wygląda następująco:

int przykladowa_funkcja(int argument)
{
        //zestaw instrukcji
    return 1; // zwracana wartość

}

 

Jak widzimy powyżej, najpierw następuje określenie typu funkcji, a konkretniej typu wartości, jaką funkcja zwróci w miejscu return“. Po tym jest miejsce na nazwę funkcji, a następnie na argumenty. W tym miejscu musimy zdecydować, jakie dane podamy funkcji. Wróćmy do przykładu z figurami. Chcąc policzyć pole koła będziemy musieli podać naszej funkcji jego promień. Będzie wyglądało to następująco:

float pole_kola(float r)
{
    float pole= 3.14*r*r;
    return pole;
}



int main()
{
    float t = 3;
    cout<<pole_kola(t);
    return 0;
}

 

 

W momencie budowania funkcji posługujemy się symbolami (zmiennymi), zupełnie jak we wzorach matematycznych. Dopiero w momencie wywołania funkcji w programie podamy konkretne “r” i dostaniemy pole od niego zależne. Zauważ, że funkcja zwraca zmienną pole, która ma typ zgodny z typem funkcji. Również “r” musi mieć odpowiedni typ. Jeśli w funkcji zadeklarujesz typ float, nie możesz pod żadnym pozorem podstawić w to miejsce np wartości int.
Pamiętaj również, że nie musisz ograniczać się tylko do jednego argumentu, możesz używać ich do woli. Pamiętaj tylko o zachowaniu typów i przecinkach pomiędzy nimi.

Kiedy należy stosować funkcje?

Odpowiedź jest prosta. Kiedy tylko jest to możliwe. Oczywiście bez przesady w stylu:

int func(int a, int b)
{
    int wynik = a + b;
    return wynik;
}

 

Kiedy można zapisać to w linijce kodu, wszystko z głową.
Ostatnią rzeczą, jaką powinieneś wiedzieć jest możliwość wywołania jednej funkcji w drugiej:

float pole_kola(float r)
{
    float pole= 3.14*r*r;
    return pole;
}

float suma_pol()
{
    float suma;
    float pole1 = pole_kola(3);
    float pole2 = pole_kola(4);
    float pole3 = pole_kola(1);
    suma = pole1 + pole2 + pole3;
    return suma;
}


int main()
{

    cout<<suma_pol();
    return 0;
}

 

Myślę, że tego przykładu nie trzeba omawiać. Analogicznie można zagłębiać się w to jeszcze dalej i w wywołanej funkcji, wywołać funkcję, która powoła następną i tak do nieskończoności.

Czym są zmienne lokalne i globalne?

Zmienne lokalne są znacznie częściej używane i wyróżnia je ograniczona żywotność.
Załóżmy następującą sytuację:

int global;

void funkcja_1()
{
    int lokal = 1;
    cout<<lokal;
}


void funkcja_2()
{
    int lokal = 2;
    cout<<lokal;

}

int main()
{
    int global2;

    funkcja_1();
    funkcja_2();
    return 0;
}

 

W podanym przykładnie zmienna lokalna o nazwie int lokal jest powołana do życia w treści funkcji, co za tym idzie nie zajmuje nam pamięci od samego początku, bo istnieje tylko od momentu wywołania funkcji i w momencie jej zakończenia jest usuwana.
Daje nam to kilka korzyści; oszczędność pamięci oraz brak kolizji ze względu na nazewnictwo. Zauważ, że w powyższym przykładzie mamy dwie funkcje ze zmiennymi o nazwie lokal, a co jest najlepsze nie są to te same zmienne, bo ich żywotność jest tylko lokalna,

  • najpierw wywołujemy pierwszą funkcję,
  • w jej zakresie tworzy się zmienna,
  • funkcja kończy działanie,
  • usuwamy zmienną,
  • wywołujemy drugą funkcję,
  • w jej zakresie tworzy się zmienna, która aktualnie nie istnieje,
  • funkcja kończy działanie,
  • usuwamy zmienną.

Mam nadzieje, jest to dla ciebie zrozumiałe, jeśli masz wątpliwości, najlepszym sposobem jest praktyka. Wypróbuj różne warianty na własnym programie i gwarantuje, że zrozumiesz zależności.

Przejdźmy do zmiennych globalnych. W powyższym przykładnie oprócz zmiennej int lokal, mamy też int global i int global2.
Skupmy się na tej pierwszej. Jak zapewne zauważyłeś jest ona położona w nieco innym miejscy niż pozostałe. Zdefiniowanie jej w tym miejscu (nad resztą funkcji) daje każdej funkcji dostęp do jej wartości, a co za tym idzie w każdej funkcji zmienna global będzie samą zmienną. Jeśli w jednej funkcji ustawię global= 3, to w drugiej funkcji wypisanie zmiennej global da rezultat 3;

int global;

void funkcja_1()
{
    global = 3;
    cout<<global;
}


void funkcja_2()
{
    cout<<global;

}

int main()
{
    int global2;

    funkcja_1();
    funkcja_2();
    return 0;
}

Przy tej okazji należy powiedzieć coś o zasięgu zmiennych. Po to w przykładnie występuje zmienna global2. Zauważ, że nie jest ona zmienną całkowicie globalną, ale jako zmienna lokalna w głównej funkcji istnieje od momentu jej zadeklarowania do końca programu, czy to znaczy, że inne funkcje mają do niej dostęp?
I tak i nie. Nie możemy dostać się do niej bezpośrednio, ale możemy przekazać ją jako argument.

int global;

void funkcja_1(int x)// funkcja dostaje kopię zmiennej global2 i zapisuje ją do x
{
    global = x;      // zapisuje x do zmiennej globalnej do której mam dostęp
    cout<<global;
}


void funkcja_2()
{
    cout<<global;

}

int main()
{
    int global2 = 5;

    funkcja_1(global2);
    funkcja_2();
    cout<<global2;
    return 0;
}

UWAGA Funkcja_1 dostaje dostęp do kopii zmiennej global2. Może jej używać ale nie może jej modyfikować, dlatego nie możemy zmiennej global2 nazwać w pełni globalną.

To już koniec Kursu podstaw C++. Mam nadzieją, że udało mi zaszczepić w tobie duszę programisty.
Pamiętaj, że nic nie zastąpi praktyki. Przedstawione w kursie podstawy zawierają wszystkie niezbędne konstrukcje, które umożliwią ci budowanie złożonych programów.

Powodzenia 😀

 
 

Spodobał Ci się ten kurs? Sprawdź pozostałe

LEKCJA 10 Funkcje, po co ich używać? Jak je konstruować, w czym pomagają? | poziom 3
Rate this post