Funkcje oraz typy danych w języku C++. Szczegółowa analiza

Cześć!

Dzisiaj zajmiemy się tzw. funkcjami. W matematyce funkcja to coś wykonujące czynność. W programowaniu jest podobnie. Może zanim przejdziemy do głębszego zastanowienia się po co Nam funkcje, zobaczmy na kod. Jak to mawiał Linus Torvalds, talk is cheap. Show me the code. So. Do this.

#include <iostream>

void showHelloWorld()
{

std::cout<<"Witaj, Swiecie!"<<'\n';

}
int main()
{

showHelloWorld();

}

Skompilujmy to. Wychodzi na to, że Nasz kod generuje identyczny wynik, jak w poprzednim tekście. Wywołanie showHelloWorld następuje w mainie. Czyli od pierwszego miejsca wykonywania danych. Tam właśnie zaczyna się wykonywać Nasz program. Co tym razem jest w mainie ? 

 showHelloWorld();

Co to oznacza ?
Odniesienie się do funkcji o takim imieniu. Poszukajmy w Naszym programie czegoś, co tak się nazywa. Znajdujemy takie cudo:

void showHelloWorld()
{

std::cout<<"Witaj, Swiecie!"<<'\n';

}

Co to właściwie oznacza ?
Funkcję. Zaczyna się ona w Naszym przypadku od słowa void. Czyli pusty, bez niczego. To słówko odnosi się do wartości, jaką będzie zwracała funkcja. Void - Pusty. Czyli funkcja nie zwróci nic. Możemy jej jednak użyć do innych celów. Do wielokrotnego użytku. Funkcje, to takie cuda, które mogą być użyte wielokrotnie w Naszym kodzie pisząc w zasadzie jej nazwę. Czyli do maina moglibyśmy dopisać jeszcze jedno showHelloWorld(); W tym przypadku funkcja wywoła się drugi raz i ujrzymy ponownie to samo wypisane 2 razy. 

Drobna modyfikacja
Zmieńmy teraz słówko void w słówko int. Skompilujmy (niektóre kompilatory nie przepuszczą). Na pierwszy rzut oka nic się nie zmieniło. Po uruchomieniu wygląda tak samo. Więc co zrobiliśmy ? Zmieniliśmy typ zwracany na int. Czyli integralny, całkowity. Jest to typ, który w obecnych systemach operacyjnych ma zazwyczaj 4kb. Oczywiście jego wielkość zależy od konkretnego systemu operacyjnego. Zakłada się że powinien zakładać minimum 16 bitów. Nie przejmuj się, jeśli tego nie rozumiesz. To tylko drobne wspomnienie. Ważne jest to, że do inta możesz umieścić dosyć duże liczby.

Dobra Szymon. Mam już tego inta i nic się nie zmieniło. Czyli tymi typami żonglować ? Możesz wpisać tzw. typy zmiennych. Do typów prostych zmiennych zaliczamy:
- int
-char
-float
-double
-bool
To podstawowe typy danych. Char to pojedyńczy znak. Float reprezentuje zmienność przecinkowa w systemie 32 bitowym. Double w systemie 64 bitów. Z kolei bool, to wartość logiczna, oznaczającająca prawdę lub fałsz. I to dosłownie. True, lub false. Ewentualnie 1, lub 0. Coś jak prąd płynie, bądź nie.

Wspomniałem o tym, że void nie zwraca nic. Zatem co będziemy mogli zwracać dzięki int, char, float, double czy nawet bool ?
Właśnie to, czym one są. Dla przykładu w Naszym int showHelloWorld(), możemy zwrócić liczbę. Np. 10. Zróbmy to więc.

int showHelloWorld()
{


std::cout<<"Witaj Swiecie!"<<'\n';

return 10;

}

Nowością jest słówko kluczowe return. Czyli zwróć. Funkcja w tym momencie się kończy i zwraca podaną wartość, temu kto ją wywołał. Return służy również do szybszego zakończenia fukcji. Nie zawsze chcemy, żeby coś się wykonywało w przypadku np. błędów. Lepiej żeby nie załadowała się tekstura w grze, niż żeby program czekał w nieskończoność aż trawka będzie miała odpowiedni kolor.

Rzeczą, która jest bardzo przydatna w funkcjach to tzw. przesyłanie jej argumentów. Jak to robimy ?

int showValue(int value)...
Funkcja otrzymuje zmienną dla siebie. Wypróbujmy jej działanie.
#include <iostream>
int showValue(int value)
{

std::cout<<value<<'\n';

int main()
{

showValue(10);

}

Program wypisze liczbę 10. Teraz spróbujmy innego myku. Zmieńmy wartość zmiennej przesłanej do funkcji.
int showValue(int value)
{

value = 15;
std::cout<<value<<'\n';

}
Wydaje się, że wszystko jest w porządku. Skompilujmy. Działa. Wyświetla 15. Ale spróbujmy coś innego. Chciejmy wyświetlić value w mainie.

#include <iostream>
int showValue(int value)
{
 value = 15;
std::cout<<value<<'\n';

int main()
{
 int value=10;
showValue(value);
 std::cout<<value<<'\n';
}


Co to ? Value się nie zmieniło. Mimo iż przesłaliśmy ją, nie zmieniła się.
Warto w tym momencie wspomnieć o przesyłaniu danych do funkcji. Dane domyślnie są przesyłane przez wartość. Czyli operujemy na ich kopiach. Zmieńmy to! Użyjmy oryginałów. Po co to tracić czas na kopiowanie ?
Do tego celu posłuży Nam tzw. referencja. Dane przesyłane przez nią, mogą być zmieniane. Zróbmy to.
#include <iostream>
int showValue(int &value)
{
 value = 15;
std::cout<<value<<'\n';

int main()
{
 int value=10;
showValue(value);
 std::cout<<value<<'\n';
}

Tak. Ampersand to jedyna zmiana. I już możemy zmieniać wartości w oryginałach, zaoszczędzając czas. Pamiętajmy, że wiąże się to z pewnym ryzykiem. Możemy zmienić ważne dane.

To już wszystko. Na zakończenie dodam kilka ciekawostek.

W wersji standardu c++11, doszły wyrażenia lambda, które są anonimowymi funkcjami, pozwalającymi rozwiązać w prosty sposób niektóre problemy.
Składnia wyrażeń lambda wygląda w następujący sposób:
[]<- Znak, że zaczyna się lambda
()<- Argumenty
->typ <- zwracany typ
{}<- Ciało funkcji, w którym dokonujemy operacji

Zróbmy więc jakąś lambdę, która robi coś konkretnego.
 auto lReturn= [](int a,int b)->bool{return a>b;};
 bool check = lReturn(10,15);
std::cout<<check<<'\n';
Powyższy kod wyświetli 0. Warto wspomnieć, tylko o nowym słówku auto. Auto znaczy automatyczny. Każda lambda jest unikalna. I dlatego mimo iż zwróci bool, nie jest proste ustalenie typu, który zwraca(jest co prawda możliwe przy użyciu tzw. functional, ale to jest zbędne i męczące).
 To byłoby wszystko. Pozdrawiam serdecznie i życze miłego dnia!

Komentarze

Popularne posty z tego bloga

Co dokładnie oznacza std::cout<<"Witaj Swiecie!"<<'\n''; w C++ ?

Klasy, Przestrzenie nazw, Nonlocal, Global i Local. Czy Python ma zmienne prywatne ?

Przeciążanie operatorów w C++