
Prostymi słowami, funkcja to kilka połączonych instrukcji, które mogą zostać wykonane w dowolnym momencie programu. To takie jakby połączenie wielu instrukcji w jedną. Technicznie rzecz ujmując, funkcja to oddzielna część prgoramu(blok programu), do którego można przejść w dowolnym momencie wykonywania programu. Funkcja zwykle służy w jakimś określonym celu. Np. Napiszmy sobie funkcję, wyświetlającą napis:
Funkcja to jakby połączenie kilku instrukcji w jedną. Aby móc użyć funkcji należy ją zadeklarować przed naszym programem, czyli main, tak jak jest to pokazane wcześniej. Ponieważ, program wykonuje się od góry do dołu, to zanim program zacznie wykonywać nasz program(main), to musi wcześniej widzieć te funkcje, dlatego trzeba napisać je przed main. Jeżeli byśmy napisali naszą funkcję wyświetl() po main to program by jej nie widział i zgłosiłby błąd.
Przeanalizujmy program. Uruchamia się i pierwszą instrukcją, jaką widzi jest nasza funkcja wyświetl. Jak już wspomniałem, funkcja to po prostu kilka funkcji połączonych w jedną, czyli instrukcja wyświetl to instrukcje w naszej funkcji(ciele funkcji). Gdy program podczas wykonywania, natrafi na funkcje, to przechodzi do wykonywania instrukcji w tej funkcji. Czyli u nas wyświetli tekst, gdy program wykona wszystkie polecenia w funkcji, to wraca do naszego programu, i kontynuuje wykonywanie programu, czyli dojdzie do system("PAUSE")i dalej już znacie.
Wykonanie funkcji oznacza wykonanie poleceń w tej funkcji. Myślę, że to zrozumiałeś.
Jeżeli robimy w programie funkcję, to musimy ją zadeklarować:
Zawsze, jeżeli coś deklarujemy w C++, zaczynamy od typu, czyli w naszym przypadku typ void(wspomniałem o nim w rozdziale o typach). Dalej podajemy nazwę funkcji i następnie nawias, który otwieramy i zamykamy. Dalej podajemy ciało funkcji, czyli polecenia, które będzie wykonywała funkcja, pomiędzy znakami "{" a "}". Dla przykładu:
Jak widać deklaracja funkcji różni się od deklaracji zmiennej tylko tym, że w funkcji po nazwie piszemy nawias () i ciało funkcji. Funkcja licz typu int.
Argumenty to zmienne, które przekazywane są do funkcji. Deklaruje się je w nawiasie. Spójrzmy na przykład:
Najpierw deklarujemy funkcję licz() i zaczynamy wykonywać program(main), tworzymy dwie zmienne int, podajemy je poprzez strumień cin i wywołujemy naszą funkcję licz. Przekazujemy do niej dwa argumenty, wartość zmiennej licz1 i wartość zmiennej licz2. Ilość i typy przekazywanych argumentów, muszą się zgadzać z definicją funkcji, czyli jeżeli mamy w definicji pierwszy typ int, to musimy przekazywać jako pierwszy, typ int, a drugi także int, więc także musimy przekazywać int. Teraz program po trafieniu na funkcję zaczyna wykonywać instrukcje w funkcji. Argumenty funkcji to zmienne, które są tworzone tylko na czas działania tej funkcji, pierwszy argument(liczba1) przyjmuje wartość zmiennej licz1 z programu, a drugi(liczba2) przyjmuje wartość zmiennej licz2. Na tym polega przekazanie argumentów funkcji, wartość zmiennych z programu głównego, są przekazywane zmiennym w funkcji. Nasza funkcja wyświetla tekst i podaje wynik dodawania liczba1 i liczba2, czyli argumentów tej funkcji. Dla przykładu, jeżeli w programie głównym zmiennej licz1 podamy wartość 2, a zmiennej licz2 podamy 15, to po przekazaniu argumenty w funkcji: liczba1 będzie miała wartość licz1, czyli 2, a liczba2 będzie miała przekazaną wartość z licz2, czyli 15. Mam nadzieję, że zrozumiałeś.
Skoro do funkcji można przekazać jakąś wartość, to funkcja może także wartość zwrócić. Ulepszmy poprzedni program, a funkcja licząca będzie tylko liczyła wartości.
Typ funkcji służy właśnie do określenia, jaką wartość ma zwracać funkcja.
W tym programie do funkcji przekazaliśmy dwa argumenty licz1 i licz2. W funkcji argumenty dodaliśmy do siebie. Instrukcja return służy do przekazywania wartości z funkcji. Jak widać wartość funkcji możemy przypisać do zmiennej dzięki temu, że zwraca ona wartość.
Typ void jest używany w funkcjach, gdy funkcja nie zwraca wartości. Jest to tzw. typ pusty. W takiej funkcji nie musimy pisać return, aczkolwiek napotkanie return w każdej funkcji kończy wykonywanie funkcji i jeżeli to nie typ void zwraca ona wartość, przykład funkcji:
Funkcja sprawdza, czy liczba jest mniejsza niż 0, jeżeli tak to zwraca nam 0, jeżeli nie to zwraca nam liczbę. Gdy liczba będzie mniejsza niż 0, to warunek będzie prawdziwy i funkcja zwróci 0 i już zakończy wykonywanie się funkcji, nie dojdzie do następnego return, return przerywa działanie funkcji i zwraca wartość.
Spójrzmy na pierwszy program w tym rozdziale:
Myślę, że zauważyliście budowę main. Do tej pory o tym nie mówiłem, bo nie znaliśmy funkcji, ale nasz program (main) jest zwykłą funkcją typu int. Spójrzmy na zapis. Main jest funkcją typu int, która ma dwa argumenty, pierwszy typu int, drugi typu char*(wskaźnik do char). W rzeczywistości każdy program jest pewną funkcją w pamięci komputera. Nasz program jest funkcją, którą wywołuje system operacyjny, przekazując parametry. Te dwie wartości pochodzą właśnie z systemu, który przekazał jakieś zmienne do argumentów funkcji main. Main jest funkcją główną, dopóki funkcja działa to mamy uruchomiony nasz program, nasz program kończy się z zakończeniem funkcji main. Zwróćmy uwagę, że main także przekazuje zmienną, typu int, co widać po typie funkcji main. Powiem jeszcze tyle, że to, co przekazujemy z main do systemu, mówi systemowi czy nasz program wykonał się błędnie czy dobrze.
Zmienne możemy przekazywać w normalny sposób, tworząc nowe zmienne jako argumenty. Istnieją także możliwości przekazywania wskaźników i referencji jako parametrów:
a)przekazywanie wskaźnika
Przyjrzyjmy się przekazywaniu wartości w poprzednim przykładzie:
Przyjrzyjmy się programowi, w pamięci nam kilka zmiennych, zadeklarowane w funkcji main, czyli zmienne licz1,licz2 i wynik
oraz dwie zmienne jako argumenty w funkcji licz
Zmienne(argumenty) z funkcji licz zostaną utworzone na czas działania funkcji i wartości tych zmiennych zostaną przekazane ze zmiennych z poprzedniej funkcji. Tylko, po co tworzyć nowe zmienne, skoro chcemy tylko wykorzystać ich wartości? Z pomocą przychodzą nam wskaźniki. Do funkcji możemy przekazać tylko wskaźniki a nie całe zmienne, to zaoszczędzi nam troszkę miejsca w programie. Zasada jest prosta, zamiast zmiennych tworzymy wskaźniki do nich.
Przekazujemy nie wartości, ale adresy zmiennych:
Całość powinna wyglądać tak:
Nie tworzymy zwykłych zmiennych, ale referencje. Jak pamiętamy zmienna referencyjna to zmienna, która się podszywa pod inną:
Na początku lekcji było powiedziane, że każdą funkcję trzeba napisać przed funkcją main, bo kompilator musi znać wszystkie funkcje zanim zacznie wykonywać główną funkcję main. To tylko połowa prawdy, aby móc pisać funkcje po funkcji main, używa się tzw. zapowiedzi funkcji. Oto przykład jednego z poprzednich programów z tej lekcji, tyle, że z zapowiedzią funkcji:
Zapowiedź funkcji, to taka jakby podpowiedź dla funkcji main, jakie funkcja znajduje się pod funkcją main. Deklarację rozpoczynamy tradycyjnie od typu funkcji, następnie nazwa i argumenty w nawiasie. Podczas deklaracji argumentów wystarczy podać same typy, nie musimy podawać nazw, aczkolwiek nie znaczy, że nie możemy, jak ktoś chce podać to żaden problem. Po prostu kompilatorowi na razie wystarczy sam typ argumentu, a nazwa przyda się dopiero, gdy wejdziemy do funkcji, więc w zapowiedzi nie trzeba jej podawać. Zapowiedź najzwyczajniej kończymy średnikiem i nie piszemy ciała funkcji, bo to tylko zapowiedź. Dopiero gdzieś dalej, musimy napisać deklarację funkcji.