Jason. Cała informatyka w jednym miejscu!

Stoimy teraz przed jednym z najważniejszych tematów mieszczących się w zakresie wiedzy podstawowej z dziedziny programowania. Mianowicie, programowanie funkcji. Funkcja w języku C# jest Wam znana już tak naprawdę od odpalenia pierwszego programu "ever", tylko część z Was może o tym nie wiedzieć :D. Dlatego teraz przyjrzymy się samym niezbędnym do opisania detalom wymaganym do rozumienia funkcji.

FUNKCJA W JĘZYKU C# TO TEMAT OBOWIĄZKOWY!

Wiem, wiem. Powtarzam się, ale nikt nie napisał, że programowanie jest nauką łatwą, lekką i przyjemną ;). Podzielimy sobie wszystkie istotne informacje na podpunkty. Pierwszą rzeczą jest definicja. Należy bezsprzecznie rozumieć pojęcie funkcji, do czego ona służy oraz z jakich części się składa. Zachęcam do przejrzenia sobie treści na temat funkcji bardziej ogólnie.

DEFINICJA FUNKCJI

Funkcja to podprogram dysponujący odrębną serią instrukcji, która przeważnie jest oddzielona od całej reszty niemającej nic wspólnego z danym zadaniem (przynajmniej tak powinno się separować kod). Pozwala to nie tylko posegregować kod źródłowy, ale także uczynić go wykonywanym wielokrotnie, gdyż funkcje można wywoływać (niżej pokazano jak się to robi). Funkcja w języku C# (tak jak w każdym innym języku) może przyjmować parametry formalne, czyli zmienne lokalne występujące jedynie w jej obrębie.

FUNKCJA VS. METODA

Pozwolę się jeszcze zatrzymać przy terminach "funkcja" oraz "metoda". Czasami może być potrzebna wiedza dotycząca rozróżniania ich między sobą. Funkcją określa się podprogram, który nie jest zależny od jakiejkolwiek innej budowy (np. klasy). Występuje po prostu na zewnątrz i nie wymaga przedostawania się do niej za pomocą operatora kropki. Przeciwieństwem tej sytuacji jest metoda, która jest częścią czegoś innego (przynależy do czegoś innego).

W C# można to traktować z przymrużeniem oka, gdyż tutaj nie da się zdefiniować funkcji na zewnątrz jakiegokolwiek innego kodu. Jaki stąd wniosek? Że każda funkcja bez wyjątku staje się z automatu metodą z powodu przebywania w klasie :D. C# to język zorientowany głównie na obiekty (choć pozwala pisać w innych paradygmatach, to sposób proceduralny znany z języka C nie jest możliwy), więc nie ma siły, żeby zdefiniować metodę na zewnątrz któregokolwiek innego bytu np. klasy, interfejsu, struktury.

WYGLĄD W KODZIE

Aby iść dalej z teorią, musicie wpierw zapoznać się z budową funkcji jak ona wygląda w kodzie źródłowym. Generalnie funkcja w języku C# składa się z własnego bloku instrukcji, a nad nim "wisi" nagłówek informujący o jej nazwie, typie zwracanej wartości oraz o ewentualnej serii parametrów formalnych (wszystkie szczegóły są zawarte w dalszych akapitach). Tak może wyglądać najprostsza ze wszystkich funkcji:

void DoSomething()
{
	// instrukcje
}

Najpierw streszczę każdy z elementów, a potem na każdy z nich poświęcę akapit. Pierwszym elementem jest typ wartości jaki funkcja ma ewentualnie zwrócić. Bez względu na to, czy funkcja zwraca czy nie, zawsze go podajemy i nie ma od tego zwolnienia. Dalej piszemy nazwę funkcji, czyli przy pomocy jakiej etykiety będzie można się nią posłużyć celem jej wywołania w dowolnym miejscu w kodzie. A na samym końcu, jeszcze zanim utworzymy blok instrukcji przy pomocy klamerek, dodajemy parę nawiasów okrągłych będącą miejscówką dla parametrów formalnych. Tak samo jak w przypadku typu, nawet jeśli nie będzie przyjmować żadnych, to i tak nawiasy mają się tam znaleźć!

Teraz jeszcze raz to samo, tylko ze szczegółami.

TYP ZWRACANEJ WARTOŚCI

Funkcja w języku C# charakteryzuje się możliwością zwracania wartości odpowiedniego typu. Chodzi o typ danych jaki funkcja reprezentuje w momencie zwrócenia wartości. Może to być "int" i wtedy mamy obowiązek zagwarantować zwrócenie liczby całkowitej dla każdej ścieżki programu (np. kiedy jest instrukcja warunkowa albo inna instrukcja tworząca rozgałęzienie, to zwrot wartości ma być zrealizowany na każdy przypadek). Umieszczając typ łańcucha znaków "string", jesteśmy zobligowani do zwrócenia niczego innego jak właśnie łańcucha znaków. I tak dalej...

Funkcja może, ale nie musi zwracać wartości. Natomiast nadal musimy ściśle określać w jej nagłówku jaki to ma być typ! Kiedy nie zwraca żadnej wartości, to wówczas nadajemy typ "void", czyli oznaczenie zwracania takiego typu, który nic nie zwraca. Brzmi może absurdalnie, jednak nie zapominajcie że kontaktujecie się z maszyną, a dla niej wszystko (dosłownie) jest zerojedynkowe :D.

Tak ma wyglądać nagłówek, kiedy funkcja zwraca liczbę całkowitą "int":

int DoSomething()
{
	return 20;
}

Ważna sprawa! Kiedy oznaczacie że funkcja ma zwracać jakąś wartość, to ponosicie odpowiedzialność za faktyczne zaprogramowanie zwrotu wartości przy pomocy instrukcji "return". Jeżeli funkcja jest typu "void", nadal możecie skorzystać z tego słowa, aby zatrzymać dalsze wykonywanie funkcji (zresztą zatrzymuje nawet przy zwróceniu wartości), natomiast wtedy nie piszecie żadnej wartości.

PARAMETRY FORMALNE I AKTUALNE

Funkcja w języku C# ma prawo posiadać własny zestaw parametrów formalnych. Parametr to nic innego jak zmienna lokalna występująca wyłącznie w obrębie bloku funkcji (nawiasy klamrowe). Umieszczamy ich tyle ile chcemy, wewnątrz nawiasów okrągłych:

void DoSomething(typ a, typ b, ... , typ n)

Najważniejsze na początek jest to, w jaki sposób zapisywać parametry żeby kompilator zaakceptował ten stan rzeczy. Otóż piszemy najpierw typ danych jaki ma dany parametr reprezentować, potem jego nazwę. Czyli dokładnie tak, jak to jest przy zmiennych na zewnątrz funkcji. Kiedy mamy ochotę na więcej, oddzielamy je przecinkiem i potem znowu typ z etykietką :):

void DoSomething(int i, float f, string s)

Dla Waszej wiadomości. Parametr formalny, czyli parametr występujący w nagłówku funkcji. Parametr aktualny, wartość wprowadzana w miejsce parametru formalnego podczas wywoływania funkcji. To tak na przyszłość ;).

WYWOŁYWANIE FUNKCJI

Kolejna rzecz bez której nie mogę Was puścić :D, to odpowiedź na pytanie w jaki sposób wywołuje się funkcje. Wystarczy podać jej nazwę w dowolnym miejscu w kodzie, a zaraz po niej parę nawiasów okrągłych wewnątrz których podajemy tyle parametrów, ile potrzebuje. Tuż po zamknięciu nawiasu dajemy średnik jako sygnał zakończenia instrukcji. Najprostsze wywołanie wygląda tak:

DoSomething();

Tak może wyglądać wywołanie kiedy funkcja w języku C# wymaga dwóch parametrów typu "int" i "string":

DoSomething(36, "Łańcuch");

A w sytuacji gdy funkcja zwraca wartość, zwykle definiuje się zmienną i podstawia się do niej wywołanie funkcji (przy czym nie jest to obowiązek):

int result = DoSomething();

To są wszystkie podstawowe "wersje" wywołań funkcji jakie możecie spotkać na swojej informatycznej drodze. Stąd wynika, że jeśli widzieliście taką instrukcję:

Console.WriteLine("Tekst");

to doświadczony człowiek rozumiałby to jako wywołanie metody o nazwie "WriteLine", która należy do klasy "Console" (o klasach w rozumieniu obiektowym więcej w kolejnym artykule). Tak należałoby powiedzieć.

KONWENCJE NAZEWNICZE

Jakieś rady na temat konwencji nazewniczych jakimi powinna się trzymać każda funkcja w języku C#? Brak spacji i zaczynania nazwy od cyfry, czyli podstawy "klejące się" z podstawami dotyczącymi nazywania zmiennych. Co do nazwy, to najlepiej trzymać się konwencji "PascalCase", czyli każde rozpoczynające się słowo pisane jest wielką literą w ramach "oznaczenia" spacji.

Pamiętajcie, że "co język, to składnia" i w Pythonie na przykład, obowiązuje już zupełnie inny zalecany sposób nazewnictwa wyglądający tak:

def my_original_function():

Także zanim rzucicie się w wir kodowania, upewnijcie się, że stosujecie się do ogólnie przyjętych zasad panujących w danym języku wysokiego poziomu, nie polecam być oryginalnym ;).

CZY TO "MAIN", KTÓRE WIDZIAŁEM(-AM) WCZEŚNIEJ, NIE JEST PRZYPADKIEM FUNKCJĄ?

No właśnie! To miałem na myśli pisząc o pierwszym przez Was kompilowanym programie. Obowiązkowa funkcja "Main" będąca punktem startowym każdej aplikacji jest pierwszą jaką zawsze każdy z nas widzi na oczy, bez względu na to czy program jaki piszemy jest pierwszy, czy osiemsetny :D:

static void Main(string[] args)
{
	
}

Będziecie widzieć przeważnie dwie wersje tej funkcji: posiadająca parametr "args" albo nieposiadająca żadnych parametrów. Obie są poprawne, a co takiego daje nam tablica "args", zapraszam do materiału na temat uruchamiania pierwszego programu, tam jest wszystko napisane.

CO Z MODYFIKATORAMI DOSTĘPU?

Ostatnie sprostowanie. Niektórzy mogą zastanawiać się czemu nie napisałem nic o modyfikatorach dostępu. Faktycznie, on też powinien być umieszczony i to nawet przed typem zwracanej wartości, jednak nie chciałem wszystkiego ujawniać na fest. Nie widzicie jaki kolos się zrobił z tego artykułu :D? Gdyby ktoś jednak potrzebował przykładu...

private void DoSomething()
{
	// instrukcje
}
Funkcja w języku C#

Funkcja w języku C# to w dużym skrócie podprogram, który pozwala na wielokrotne wykonywanie tego samego bloku instrukcji, a także oddzielenia od siebie kodu źródłowego dotyczącego konkretnego zadania od całej reszty.


Znowu artykuł wyszedł długi, może dla niektórych nawet za długi. Mam jednak nadzieję, że to Was nie zniechęci do posiłkowania się tą treścią teraz i w przyszłości. W każdym razie dziękuję za przeczytanie i przygotowujcie się na kolejne wyzwania, bo to jest wszystko nadal pikuś w porównaniu do nadchodzących tematów :O!

PODOBNE ARTYKUŁY