You are on page 1of 1

Funkcje

Kady, kto zaczyna swoj przygod z programowaniem szybko zauwaa, e te same fragmenty kodu s
wykorzystywane w wielu miejscach jednoczenie. Kopiowanie i wklejanie tych fragmentw
bezporednio do programu jest nieefektywne z wielu powodw. Wyobramy sobie chociaby, jak
ciko byoby taki kod zmieni; zmiana zachowania algorytmu wymagaaby zmian wszystkich
wklejonych fragmentw!
Z pomoc przychodzi nam mechanizm funkcji (i metod, jeli mwimy o klasach), ktry pozwala
zarwno na poprawienie czytelnoci kodu jak i elastycznoci wprowadzania do niego zmian.
Rozumienie ich dziaania jest jedn z najbardziej podstawowych umiejtnoci, jakie posiada powinien
programista.
Dziaanie funkcji mona tumaczy na dwa sposoby:
- z niskopoziomowego punktu widzenia s to instrukcje procesora zapisane w pamici, do ktrych
mamy dostp poprzez wskanik na pierwsz z nich; odwoujc si do niego mamy moliwo
wywoania tyche instrukcji w dowolnym miejscu programu;
- z wysokopoziomowego punktu widzenia, funkcje w programowaniu s ekwiwalentem funkcji
matematycznych: dla danych argumentw zwracaj cile okrelone wartoci.
Sprbujmy zagbi si w drugi z tych sposobw. Zaczniemy od prostego przykadu.

f (x) = 2 * x
Nasza funkcja nazywa si f, przyjmuje ona jeden argument, ktry nazwalimy x, warto przez ni
zwracana bdzie zalena od argumentu, a sposb jej obliczania zdefiniowalimy jako pomn dwa
przez x. Oznacza to, e jeeli do funkcji przekaemy warto 5, to wynikiem jej dziaania bdzie
warto 10, jeli za nasz argument bdzie rwny (2 + 1), to warto funkcji bdzie rwna 6 i tak dalej.
Jak wic widzimy, argumentem funkcji moe by rwnie wyraenie lub funkcja.
Dla matematyka x zawsze bdzie po prostu jak liczb. Dla programisty jest to zmienna - a te, jak
wiemy mog reprezentowa rne obiekty, takie jak wartoci zerojedynkowe, ale te na przykad cigi
znakw czy inne, bardziej zoone twory. Dotyczy to rwnie wartoci zwracanej przez funkcj.
Jak wic widzimy koniecznym bdzie dla nas zdefiniowanie typu argumentu przekazywanego do
funkcji, jak rwnie typu zwracanego przez funkcj. Dwa jest sta, ktrej nie przekazujemy jako
argument - jej typ zostanie zdefiniowany automatycznie.
Sprbujmy przeksztaci wyraenie z powyszego przykadu tak, aby byo nieco bardziej zrozumiae
dla kompilatora; uyjemy liczb cakowitych:

int f (int x) = 2 * x
Jestemy ju blisko dziaajcej funkcji. Teraz powinnimy usun znak rwnoci, zamkn instrukcj,
na podstawie ktrej obliczana jest warto (ciao naszej funkcji) w nawiasy klamrowe i doda rednik
na jej kocu:

int f (int x) { 2 * x; }
Musimy pamita o tym, e kompilator nie potrafi myle za nas. Rzadko zdarza si, aby funkcja
skadaa si z jednej instrukcji, co za tym idzie niezbdne jest pokazanie, co jest wartoci zwracan. W
tym celu stosujemy instrukcj return:

int f (int x) { return (2 * x); }


Gdy przekazujemy argument do funkcji, tworzona jest w niej kopia tego argumentu. Wszelkie
zmiany na nim dokonywane nie bd miay znaczenia na zewntrz funkcji. Moemy
zmodyfikowa powyszy kod tak, aby argument by zwikszany w funkcji dwukrotnie, a nastpnie
zwracany:

int f (int x) {
x = x + x;
return x;
}
Z punktu widzenia uytkownika funkcji, jej zachowanie nie zmienio si w aden sposb.
Bardzo wan kwesti jest odpowiednie nazewnictwo funkcji i jej argumentw. Nazwy typu f
czy funkcja nie mwi nam nic o jej dziaaniu a x - o tym, do czego posuy argument. Dla
czytelnoci kodu zmiemy prototyp naszej funkcji:

int dwukrotnosc (int liczbaDoPodwojenia);


Moe si to wydawa zbdne dla tak prostej funkcji, jednak warto wyrabia u siebie dobre nawyki.
Wspomniaem o prototypie funkcji. Na wikipedii moemy znale dobr jego definicj:
Tradycyjnie prototyp oznacza funkcj, ktra nie posiada ciaa, a jedynie informuje kompilator o
postaci parametrw oraz zwracanej wartoci. Pena tre funkcji znajduje si w dalszej czci kodu,
podczas gdy deklaracje funkcji umieszcza si zazwyczaj w plikach nagwkowych, co ma na celu
wyodrbnienie interfejsu programu.
Parametry to inna nazwa argumentw funkcji. Funkcje mog przyjmowa ich wiele, wszystkie
podajemy w licie argumentw. Warto zwracana z kolei jest zawsze tylko jedna.
Stwrzmy funkcj zwracajc rnic dwch liczb typu float:

float roznica (float odjemna, float odjemnik) {


float wynik = odjemna odjemnik;
}

return wynik;
Oczywistym jest, e odejmowanie nie jest przemienne podobnie argumenty funkcji nie s
przemienne, podajemy je zawsze w cisej kolejnoci. Jeli wic pierwszym argumentem jest liczba
cakowita, a kolejnym rzeczywista, to musimy odpowiednio poda takie wanie liczby.
Do funkcji moemy przekaza zmienne dowolnego typu, ale rwnie moemy nie przekaza adnej
wtedy jest to funkcja przyjmujca typ void, czyli funkcja bezparametrowa. Funkcja moe rwnie
zwraca typ void tak funkcj nazywamy procedur. O ile typ zwracany musi zawsze zosta podany,
o tyle lista argumentw moe by pusta, tak wic poprawn deklaracj bezparametrowej procedury
bdzie:

void procedura ();


Przekazujc do funkcji wskanik jako argument moemy dziaa na zmiennej, ktra kryje si pod tym
wskanikiem. Nie bdzie tworzona jej kopia, zostanie utworzona natomiast kopia przekazanego
wskanika.
Do funkcji moemy przekaza tablic, albo raczej wskanik na jej pierwszy element (oznacza to, e nie
zostanie ona skopiowana, a wic bdziemy mogli zmienia wartoci jej elementw).
Wewntrz funkcji operator rozmiaru sizeof() nie bdzie w stanie okreli, jak dua jest przekazywana
tablica, wic przyda nam si przekazanie jej rozmiaru.
Stwrzmy funkcj, ktra zwrci maksymalny element podanej tablicy:

int znajdzMaksymalnyElement (int* tablica, int rozmiar) {


int maks = tablica[0];
for (int i = 0; i < rozmiar; i++) {
if (tablica[i] > maks)
maks = tablica[i];
}
return maks;
}

CIG DALSZY WKRTCE...

You might also like