\b;Funkcje
Mówiąc najprościej, funkcja to instrukcja stworzona przez ciebie.

\b;Funkcja główna
Pewnie już wiesz, jak się tworzy funkcje. Każdy program napisany w CBOT musi mieć funkcję główną, która wygląda tak:
\c;
\s;extern void object::NazwaProgramu()
\s;{
\s;	
\s;	// instrukcje
\s;	
\s;}
\n;
Nic oprócz nazwy nie może być zmieniane w funkcji głównej. Słowo kluczowe \c;\l;extern\u cbot\extern;\n; wyróżnia funkcję główną spośród pozostałych.

\b;Podstawowe użycie
Funkcje pozwalają na podzielenie programu na kilka części. Każda z nich wykonuje określone zadanie. Poniższy program jest przykładem takiego zastosowania:
\c;
\s;extern void object::Remote()
\s;{
\s;	send("order", 1, 100);
\s;	wait(5);
\s;	send("order", 3, 100);
\s;	wait(5);
\s;	send("order", 2, 100);
\s;	wait(5);
\s;	send("order", 4, 100);
\s;	wait(5);
\s;}
\n;
Instrukcje \c;\l;send\u cbot\send;\n; i \c;\l;wait\u cbot\wait;\n; są powtarzane po kilka razy. Byłoby więc dobrze stworzyć funkcję, która wykonuje obie te instrukcje:
\c;
\s;void SendToPost(float op)
\s;{
\s;	send("order", op, 100);
\s;	wait(5);
\s;}
\s;
\s;extern void object::Remote()
\s;{
\s;	SendToPost(1);
\s;	SendToPost(3);
\s;	SendToPost(2);
\s;	SendToPost(4);
\s;}
\n;
Program jest teraz zdecydowanie czytelniejszy. Dzielenie program na kilka funkcji o nazwach, które je opisują, jest dobrą praktyką.

\b;Składnia
\c;
\s;typ Nazwa funkcji(opcjonalne_parametry)
\s;{
\s;	ciało funkcji
\s;}
\n;
Jeśli funkcja nie ma zwracać żadnych danych, \l;typem\u cbot\type; powinien być \l;void\u cbot/void;. Ciało funkcji stanowią instrukcje. Nazwa funkcji musi być stworzona na podstawie reguł tworzenia nazw \l;zmiennych\u cbot\var;.

\t;Parametry
Funkcja może mieć parametry:
\c;
\s;void Przyklad(int a, float x, string s)
\s;{
\s;	message(a);
\s;	message(x);
\s;	message(s);
\s;}
\n;
Funkcja \c;Przyklad\n; otrzyma \l;liczbę całkowitą\u cbot\int; \c;a\n;, \l;liczbę zmiennoprzecinkową\u cbot\float; \c;x\n; i \l;łańcuch znaków\u cbot\string; \c;s\n;. Parametry są "przekazywane wartościami", tzn. wartości zmiennych parametrów w funkcji są kopiami wartości, które zostały do niej przekazane. Jeśli przekażesz funkcji wartość typu \c;\l;int\u cbot\int;\n;, wartość ta zostanie skopiowana do parametru i funkcja będzie mogła na niej operować, nie zmieniając jednocześnie wartości w kodzie, który ją wywołał.

Jeśli przekażesz jako parametr funkcji instancję \l;klasy\u cbot\class; lub \l;tablicę\u cbot\array;, funkcja otrzyma tylko \l;odniesienie\u cbot\pointer; do instancji lub tablicy. Oznacza to, że jeśli zmieniona w funkcji tę instancję lub tablicę, oryginalna instancja lub tablica zostanie również zmieniona.

\t;Wynik
Funkcja może też zwrócić wynik, korzystając z instrukcji \c;\l;return\u cbot\return;\n;. W takiej sytuacji \l;typem\u cbot\type; funkcji nie może być \c;\l;void\u cbot\void;\n;:
\c;
\s;float Srednia(float a, float b)
\s;{
\s;	return (a+b)/2;
\s;}
\s;
\s;extern void object::Test( )
\s;{
\s;	float value;
\s;	value = Srednia(2, 6);
\s;	message(value);  // zwróci 4
\s;}
\n;
Inne przykłady:
\c;
\s;float Pi()
\s;{
\s;	return 3.1415;
\s;}
\s;
\s;string Sign(float a)
\s;{
\s;	if (a > 0)  return "dodatnia";
\s;	if (a < 0)  return "ujemna";
\s;	return "null";
\s;}
\n;

\b;Przeciążanie funkcji
Możesz zadeklarować kilka funkcji o tej samej nazwie, ale innych parametrach: 
\c;
\s;float Pitagoras(float a, float b)
\s;{
\s;	return sqrt((a*a)+(b*b));
\s;}
\s;
\s;float Pitagoras(float a, float b, float c)
\s;{
\s;	return sqrt((a*a)+(b*b)+(c*c));
\s;}
\n;
CBOT wywoła jedną z funkcji w zależności od przekazanych parametrów. Funkcje muszą być odróżnialne, tzn. nie możesz zadeklarować dwóch funkcji o takiej samej nazwie i typach parametrów w tej samej kolejności. Odnosząc się do przykładu: zadeklarowanie funkcji \c;int Pythagoras(float b, float a)\n; wywoła błąd. Zwróć uwagę, że typ wyniku, jaki zwraca funkcja, nie ma znaczenia.

\b;Funkcje publiczne
Można też zadeklarować funkcję \l;publiczną\u cbot\public;, która będzie dostępna dla wszystkich robotów.

\b;object::
Deklaracja funkcji w przestrzeni nazw \l;object\u cbot\object; daje jej dostęp do \l;wskaźnika\u cbot\pointer; \c;\l;this\u cbot\this;\n;. Innymi słowy, funkcja ma wtedy dostęp do wszystkich właściwości robota, na którym jest uruchomiona.
\c;
\s;void object::Przyklad()
\s;{
\s;	message(this.category);
\s;}
\n;

\b;Parametry domyślne
Ostatnie parametry funkcji mogą mieć wartości domyślne, które można pominąć podczas jej wywoływania.
\c;
\s;float Dodaj(float a = 0.0, float b = 0.0)
\s;{
\s;	return a + b;
\s;}
\s;
\s;// Gdzieś w głównym programie...
\s;Dodaj(); // Zwróci 0.0
\s;Dodaj(2.0); // Zwróci 2.0
\s;Dodaj(2.0, 3.0); // Zwróci 5.0
\s;// ...
\n;

\t;Domyślne parametry i przeciążanie
Funkcje z parametrami domyślnymi również mogą być przeciążone, pod warunkiem, że wywołanie jest jasne. Na przykład, spójrz na poniższy kod:
\c;
\s;float Dodaj(float a = 0.0, float b = 0.0)
\s;{
\s;	return a + b;
\s;}
\s;
\s;string Dodaj(string a = "", string b = "")
\s;{
\s;	return a + b;
\s;}
\s;
\s;// Gdzieś w głównym programie...
\s;Dodaj(); // Błąd kompilacji: niejasne wywołanie
\s;Dodaj(""); // Ok
\s;Dodaj(0.0); // Ok
\s;// ...
\n;
Zwróć uwagę, że w przykładzie powyżej przeciążanie powoduje, że pierwszy parametr jest bezużyteczny, gdyż podczas wywołania funkcji trzeba go podać tak czy inaczej, by rozróżnić obie funkcje.

\t;Zobacz również
\l;Programowanie\u cbot;, \l;typy\u cbot\type; i \l;kategorie\u cbot\category;.
