Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
 
Polski Portal COLOBOTa
COLOBOT Polish Portal

Problemy [programowanie] - Funkcje i tablice

bbiidduull - 16-02-2010, 21:07
Temat postu: Funkcje i tablice
Witam. Mógłby mi ktoś wytłumaczyć wyżej wymienione terminy. W ogóle nie umiem z nich korzystać. To co napisali w podręczniku Colobota, to ja tego nie rozumiem. Jeżeli by miał ktoś chęci i czas nauczyć mnie zadając prace domowe :D w którym musiał bym zrobić określony program oczywiście dostosowany do poziomu nauki :D .


P.S. Mam prośbę. Mógłby mi ktoś kto ma sporo zebranych dodatkowych misji podesłać tu na forum? Kiedyś miałem wszystkie opcje dostępne w misjach tzn mogłem wszystko budować a teraz nie wiem jak :( . JAk by miał ktoś wszystkie odblokowane to też bym prosił.

Pozdrawiam i liczę na pomoc.

Berserker - 16-02-2010, 22:56

Tablica to zmienna, w ktorej mozna trzymac wiele informacji jednego typu. Np robimy wyscig w kolko 5 okrazen i chcemy zapisac czas kazdego okrazenia. Oczywiscie zawsze mozna dac
Kod:
float czas1, czas2, czas3, czas4, czas5
Ale za pomoca tablicy mozemy dac:
Kod:
float czas[5]

Tablica czas[] ma 5 elementow. Elementy numeruje sie od 0, wiec mozna wywolac czas[0]...czas[4]. Jak sprobujesz zainicjowac szosty element (czas[5]) to wywali blad.
Tablice moga byc wielowymiarowe. Ladnie to brzmi, w praktyce oznacza to ilosc kwadracikow przy deklaracji tablicy. Mozemy np zrobic 5 wyscigow i w kazdym 5 okrazen, po czym wyliczyc sredni czas. Niby da sie to zrobic za pomoca 5 roznych tablic jednowymiarowych, ale mozemy to zrobic za pomoca jednej tablicy dwuwymiarowej.
Kod:
float czas[5][5]

Jesli chcemy wywolac czas z 2 okrazenia 3 wyscigu:
Kod:
czas[2][1]

W pierwszym kwadraciku wpisujemy nr wyscigu-1, w drugim nr okrazenia-1 i mamy.


Funkcja to skrocenie kilku, kilkunastu lub kilkudziesieciu linijek programu do jednego wyrazu z nawiasem. Mozna powiedziec, ze to jakby stworzone przez siebie nowe polecenie, ale to troche okrojona wersja polecenia. Najlepszy przyklad pokazany jest wlasnie w cwiczeniach. Musisz przejechac 2 kwadraty o boku x. Niby mozna wpisywac ilestam razy
Kod:
for(int i = 0; i < 4; i++) {move(20); turn(90);}
, ale po co, skoro mozna glowny program skrocic do 2 linijek tworzac funkcje z parametrem, ktorym jest bok kwadratu.

bbiidduull - 16-02-2010, 23:57

Jak byś mógł mi wytłumaczyć wszystko o tym. Był bym wdzięczny ;]

Kod:
extern void object::CollectTitanium2()

Berserker - 17-02-2010, 00:18

Kod:
extern

Deklaruje funkcje jako glowna. Po kliknieciu "Start" robot spisuje wszystkie funkcje, po czym zaczyna wykonywac ta oznaczona jako extern.
Kod:
void

Typ wyniku zwracanego przez funkcje. Mozesz np napisac funkcje, ktora liczy ile mrowek jest w zasiegu 40m. Wtedy na koncu funkcji dajesz
Kod:
return jakastamzmienna;

Jesli typ wyniku bedzie inny niz typ funkcji to program sie wykrzaczy.
Kod:
object::

Takie cos daje dostep funkcji do informacji o obiekcie wykonujacym funkcje. Jesli dasz odrazu nazwe funkcji, a w funkcji zechcesz skorzystac z pozycji robota (this.position), to program stwierdzi ze costam, zrobi "WTF?!" i sie skonczy. To samo z innymi informacjami otrzymywanymi za pomoca obiektu this.
Kod:
CollectTitanium2

Nazwa funkcji. Sluzy do nazywania funkcji.
Kod:
(

Nawias otwierajacy. Za nim mozemy ewentualnie umiescic parametry. Fear ich nie uzywa, wiec ty tez nie musisz ;>
Kod:
)

Nawias zamykajacy. Konczy nasza meke z deklarowaniem funkcji

FE4R - 17-02-2010, 01:00

Temat funkcji jest tak obszerny, że aż trudno mi cokolwiek napisać.
Dobrze. Zacznijmy od podstaw.

Funkcja jest to specjalna instrukcja w programie, która ma za zadanie wykonać dane zadanie na parametrze. Brzmi to dziwnie, wiem. Przyjrzyjmy się więc temu, jak wygląda podstawowa funkcja w języku CBOT:
Kod:
Funkcja();

Funkcja to nazwa funkcji, która ma zostać wykonana. W nawiasach umieszczane są parametry funkcji, czyli to, na czym ma ona operować. Jeśli nic w niej nie umieścimy, a chcemy, aby coś ona obliczyła, to tak, jak wysłanie pustej ciężarówki z hurtowni.

Załóżmy, że chcemy stworzyć funkcję, która obliczy nam sinus z danego kąta. Będzie ona wyglądała tak:
Kod:
int kat = 40;
sinus(kat);

Jeśli odpowiednio ją zaprogramujesz, funkcja obliczy Ci sinus z kąta 40 stopni lub któregokolwiek wpiszesz. W/W kod programu to wywołanie funkcji. Trzeba jednak powiedzieć programowi, na jakich zasadach funkcja ma działać, liczyć i jak używać parametru, który wpisaliśmy w nawiasy. Od tego służy definicja funkcji, np.:
Kod:
float sinus(int kat)
{
float a = sin(kat);

return a;
}

Skupmy się na elementach definicji, czyli co te wszystkie nazwy oznaczają. float to oczywiście typ. Typ wyniku funkcji. Jeśli funkcja coś liczy, to musi to oddać użytkownikowi. Tak jak kalkulator po przeliczeniu nie zatrzymuje wyniku dla siebie, tylko go wyświetla.
Instrukcja return a; zwróci sinus z kąta 40 stopni z powrotem do programu, więc trzeba ten typ dostosować do tej instrukcji. Ponieważ sinus z kąta na pewno będzie liczbą po przecinku, lepiej będzie użyć typu float. Gdyby nie był po przecinku, możnaby użyć typu int.
Dalej jest nazwa funkcji, którą wcześniej wywołaliśmy. W nawiasie trzeba umieścić typ parametru, który został wpisany wcześniej. Kąt wpisany jest typu int, więc tutaj też musi być typu int(chyba, że chcesz, aby program przeprowadził niejawną konwersję typów, ale o tym pewnie nie chcesz nawet słyszeć! :D ).

Czyli reasumując: w programie umieszczasz wywołanie funkcji z parametrem, a poniżej jej definicję, w której określasz sposób działania funkcji.

Tutaj masz gotowy kod programu, który zawiera w/w funkcję:
Kod:
extern void object::Liczenie()
{
int kat = 40;
sinus(kat);
}

float sinus(int kat)
{
float a = sin(kat);

return a;
}


To był przykład funkcji liczącej, lecz mogą być też funkcje, które nic nie liczą, tylko są 'zbiorem instrukcji', dzięki którym można skrócić program. Funkcja, która nic nie liczy ma tym pusty, czyli typ void.
Załóżmy, że masz taki oto program:
Kod:
extern void object::Program1()
{
grab();
drop(Behind);
grab(EnergyCell);
drop();
grab(Behind);
drop(EnergyCell);

wait(1);

grab();
drop(Behind);
grab(EnergyCell);
drop();
grab(Behind);
drop(EnergyCell);

Strrrrasznie długi. Więc go skróćmy. Zauważ, że 2 fragmenty się powtarzają.
Stwórzmy więc coś takiego:
Kod:
extern void object::Program2()
{
Zamiana();
wait(1);
Zamiana();
}

void object::Zamiana()
{
grab();
drop(Behind);
grab(EnergyCell);
drop();
grab(Behind);
drop(EnergyCell);
}

Teraz zamiast tylu linijek, umieszczasz tylko nazwę funkcji, którą program ma wykonać. Typ void oznacza, że nawias parametru jest pusty(Zamiana();).

Przejdzmy jednak do twojego ostatniego pytania.
Program składa się z przynajmniej jednej funkcji(głównej) lub większej liczby funkcji pobocznych(przedstawionych wyżej).
Funkcja główna powinna zawierać najważniejsze instrukcje programu oraz wywołania innych funkcji, jeśli takowe napisałeś.
Aby program wiedział, która funkcja jest główna, oznacza się ją słowem extern na początku. Tylko jedna funkcja w programie może być funkcją extern. Wszystkie inne to funkcje poboczne i ich definicje trzeba zapisywać poniżej, natomiast samo wywołanie umieścić w funkcji głównej.

Funkcja główna jest typu void, gdyż nie ma żadnego wyniku(tylko w języku CBOT).
Nie zwraca ona żadnej liczby do innej funkcji, bo to ona jest główna i najważniejsza.
W języku C++ funkcja główna to funkcja main typu int, gdyż program należy kończyć instrukcją return (0);.

Ale na Twoje szczęście w Colobocie tak nie jest, więc się nie przejmuj. :)
Następny typ, object jest umieszczany profilaktycznie. Umieszcza się go wszędzie, gdzie funkcja może mieć styczność z obiektami i informacjami o nich, np:
Kod:
item = radar(AlienAnt); lub if(energyCell.energyLevel < 0.3)


Te dwa dwukropki to wyższa szkoła jazdy. Jest to 'znak dwu-bitowy', o ile się nie mylę symbolizujący polecenie inline(występujące jedynie w językach C), sugerujące wywołanie funkcji głównej w jednej linii, w celu zmniejszenia pamięci zajmowanej przez funkcję. Ale nie jestem do końca pewien, bo było to dla mnie niezrozumiałe.

Po dwukropku jest nazwa funkcji, a dalej nawiasy, które muszą tam występować puste!(Parametry, ale funkcja główna jest void, więc nie można tam nic wpisać).

Jeśli będziesz miał jeszcze jakieś niejasności, to polecam się na przyszłość.

PS.
@Berserker:
Cytat:
Nawias zamykajacy. Konczy nasza meke z deklarowaniem funkcji

Też się chciałem do czegoś przyczepić, więc się przyczepię ^_^.
W języku CBOT nie występują deklaracje funkcji, tylko definicje i wywołania.

bbiidduull - 17-02-2010, 01:17

yyyyy :D dzięki! Prawie wszystko zrozumiałem ale..

Kod:
float sinus(int kat)
{
float a = sin(kat);

return a;
}


czyli jak dobrze zrozumiałem zwróci mi liczbę float (zmiennoprzecinkową) a mogę wpisać int ( całkowitą) tak ?

adiblol - 17-02-2010, 01:23

@up: tak. Argumenty mogą być innego typu niż wartość zwracana.
Berserker - 17-02-2010, 10:24

Cytat:
Następny typ, object jest umieszczany profilaktycznie. Umieszcza się go wszędzie, gdzie funkcja może mieć styczność z obiektami i informacjami o nich, np:

Jesli dobrze zrozumialem, object:: wstawiamy w kazdej funkcji, w ktorej zamierzamy korzystac ze zmiennych typu object? O_O

adiblol - 17-02-2010, 12:29

To jest bardziej skompilowane i wkracza w klasy. Możesz przyjąć, że przy każdej funkcji, która odwołuje się do własnego robota, np. this.lifeTime czy po prostu lifeTime.
bbiidduull - 17-02-2010, 16:37

Dzięki wszystkim za pomoc. A pomógł by ktoś z ostatnim pytaniem z P.S. ? :D
Olamagato - 25-06-2011, 16:13

object:: dodaje się do funkcji po to aby zrobić z niej metodę klasy object. Klasa ta jest już niejawnie zdefiniowana w Colobocie (nie ma jednak jej źródła poza helpem do kilku pól (takich jak load czy energyLevel) i normalnie nie powinno dać się jej rozszerzać o nowe metody. Tym właśnie różni się c-bot od C++ oraz Javy, że tu jest to możliwe. Inne klasy muszą mieć metody zdefiniowane normalnie - tak jak w Javie (wewnątrz ciała klasy).
Apus - 26-06-2011, 11:22

@up Brawo, odkopałeś póltoraroczny temat. :->

Powered by phpBB modified by Przemo & WRIM © 2003 phpBB Group