Funkcje, czyli metody

Spis treści Poprzednia strona: Tablice Następna strona: Coś dla matematyków

I przyszła kryska na matyska. Do dziś nie wiem co to jest kryska i kim był matysek… ale tak się mówi. Metody to najważniejszy element programowania. Kto nie rozumie metod niech zapomni o tym całym programowaniu i niech zajmie się czymś bardziej pożytecznym, np. uprawą bulw kolokazji. To właśnie w metodach jest kod, który piszemy aby go wykonać. Czy metody to funkcje? I tak, i nie. Mogą być funkcjami (znanymi nam z matematyki), bo dla pewnych argumentów mogą zwracać wartość. Mogą, ale nie muszą. Metoda nie musi zwracać żadnej wartości. Może też „zwracać” więcej niż jedną wartość. Wartością tą nie musi być liczba, ale może nią być obiekt dowolnej klasy. Podobnie argumentem przekazanym do funkcji może być obiekt dowolnej klasy. Co to znaczy „przekazanym”? Skąd, dokąd i przez kogo? W tym rozdziale postaramy się odpowiedzieć na te i podobne pytania.

Oto jest przykład metody:

int idź(int i, bool nie, char[] grzesz, More więcej)
{
    int k = tutaj(45, i);
    return k + 7;
}

Jest to metoda o nazwie idź. Przyjmuje ona 4 parametry (tzw. argumenty formalne) o nazwach: i, nie, grzesz, więcej. Metoda ta zwraca wartość typu int, tzn. zawiera co najmniej jedno słowo kluczowe return po którym występuje wyrażenie o typie int, czyli o tym samym typie, co typ zwracanej wartości (lub o typie niejawnie „konwertowalnym” na ten typ). W ciele metody (czyli między nawiasem klamrowym lewym { a nawiasem klamrowym prawym }) mamy dwie instrukcje: definicję zmiennej lokalnej z jej inicjalizacją (przypisaniem) i zwrócenie wartości. Instrukcja przypisania przypisuje zmiennej k wartość innej funkcji (prawdopodobnie typu int) o nazwie tutaj i o argumentach (tzw. argumentach aktualnych): 45 oraz i – oba typu int. Wartości argumentów aktualnych zostaną przypisane (z ewentualną niejawną konwersją) do argumentów formalnych metody tutaj() przed jej wywołaniem, a wartość wyrażenia po return wewnątrz metody tutaj() (metoda ta zwraca wartość, więc gdzieś w jej wnętrzu musi być return – tak naprawdę, to musi być return na każdej ścieżce wykonania w metodzie, ale o tym później) po wykonaniu metody tutaj() zostanie przypisana (z ewentualną niejawną konwersją) do zmiennej k.

Przykład

Wiemy, że liczba typu int zajmuje 4 bajty pamięci – wystarczy wykonać sizeof(int). A co jeśli chcemy przechować dwie takie liczby razem w jednej zmiennej typu long? Powinny się zmieścić, bo sizeof(long) wynosi 8. Ale jak to zrobić? Przeczuwamy nosem, że ma to coś wspólnego z operatorami bitowymi i z rzutowaniem. W takim celu tworzymy metody konwertujące. Jedna będzie pakować dwie liczby int do jednej liczby long, a druga wydostanie te dwa int-y z powrotem.

long Pack(int i1, int i2)
{
    return (long)((ulong)i1 << 32 | (uint)i2);
}

void Unpack(long u, out int i1, out int i2)
{
    i1 = (int)((ulong)u >> 32);
    i2 = (int)((ulong)u & uint.MaxValue);
}

Nie wystarczy napisać metodę. Trzeba jej jeszcze użyć. Na przykład tak:

long a = Pack(-16, 283);
int x, y;
Unpack(a, out x, out y);
Console.Write("x = {0}, y = {1}", x, y);

Wywołujemy metodę Pack przez podanie parametrów -16 oraz 283, które w metodzie podstawiane są pod zmienne i1 oraz i2. Metoda Pack zwraca wartość typu long, którą przypisujemy do zmiennej a. Czy metoda może zwracać więcej niż jedną wartość? I tak, i nie. Można w tym celu użyć parametrów out. Przykładem takiej metody, która „zwraca” dwie wartości jest Unpack. Użyłem słowa zwraca w cudzysłowie gdyż ściśle rzecz biorąc metoda ta nic nie zwraca – stąd w definicji void przed jej nazwą i kompletny brak słowa kluczowego return w ciele metody.

Spis treści Poprzednia strona: Tablice Następna strona: Coś dla matematyków

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *