■ : -• (Syjli! ■ ,! 1. :rS- II);
Dołączenie nagłówków
• Deklaracja funkcji
Deklaracja zmiennych
Wywołanie funkcji, która jest zdefiniowana później, ale wcześniej pojawiła się jej deklaracja
J* ___
“"Definicja funkcji
PsnuHyśMictlaczaTO) “ipgip Koad M>Wp««lMub] - pg=_r«.dlBy^e(fc|_HaorCytIX<yal-»vCZ*4)}&Ck<f]>;
OanełtyawieelicżitZł • pt......... " ' *' ’
>aiu.Ky9;-lsClBcco[2ł * p<
Stworzenie nowej funkcji w C jest bardzo proste. Tak naprawdę cały czas tworzymy przecież funkcje. Do tej pory stworzyliśmy funkcję main, oraz za pomocą makra, funkcję obsługi przerwania. Byty to funkcję standardowe. Teraz rozwiniemy temat na tyle, aby móc utworzyć funkcją o dowolnej nazwie, dowolnych parametrach i dowolnej zwracanej wartości.
Na obrazku w tej ramce pokazałem z czego składa się definicja funkcji. Przykładowa funkcja zaczerpnięta / tworzonego aktualnie programu ma za zadanie wyświetlić podaną liczbą w kodzie hek-sadecymalnym. Nie skupiamy się teraz na tym, jak ona działa, ważne jest to, jak została zapisana. Funkcja składa się z informacji dla kompilatora, jaką wartość zwraca. Często, zamiast mówić opisowo. że funkcja zwraca wartość typu (przykładowo) int, mówimy prosto, że funkcja jest typu int.
W naszym przypadku używamy void. Jest to bardzo specyficzny typ wartości, ktpry... nie istnieje. W ten sposób informujemy kompilator, że funkcja nie zwraca wartości. Jeśli pisałeś progTamy w BASCOM-ie, może zakrzykniesz teraz - to już znamy - tylko do lej pory funkcję niezwracającą danych nazywaliśmy procedurą (SUB). Znakomicie, jeśli zauważasz analogię. Teraz jednak zarówno procedury, jak i funkcję tworzy się tak samo. Różnica w zapisie polega tylko na poinformowaniu kompilatora, żc nie chcemy zwracać żadnej wartości.
Następnie pojawia sic nazwa funkcji. Jest to identyfikator, więc nic może zaczynać się od cyfry. Poza tym może zawierać wszystkie litery alfabetu, jednak bez polskich „ogonków". Dodatkowo można wykorzystać znak podkreślenia. Przypominam, że rozmiar liter ma znaczenie. Z tego identyfikatora będziemy korzystać w cełu wywołania funkcji.
Zaraz za identyfikatorem, w nawiasach, umieszczamy wymagane przez funkcję parametry. Jeśli potrzebujemy więcej niż jednego parametru, oddzielamy je przecinkami. Kolejno podajemy typ zmiennej, następnie jej nazwę. Ważne jest, że parametry te będą dostępne tylko i wyłącznie dla tworzonej funkcji. Uważaj - aby nie nadać parametrowi nazwy jakiejś zmiennej globalnej. Przeciwnie do BASCOM-a, tutaj nie tylko nie jest to wymagane, ale wręcz niewskazane.
Między nawiasami klamrowymi umieszczamy ciało funkcji, czyli po prostu opis jej działania. Możemy wykorzystać teraz wszelkie funkcje standardowe, wywołać inną własną funkcję, a nawet -funkcja może wywołać samą siebie... Tak czy inaczej - ciało funkcji pisaliśmy już kilka razy, tak więc nie jest to już niczym nowym.
Parametry w C przesyłane są poprzez wartość. Oznacza to. że funkcja nic ma dostępu do zmiennych na poziomie funkcji wywołującej. Można więc z przesłanych danych korzystać do woli. Jak do zwykłej zmiennej możesz wpisać tutaj na przykład wynik cząstkowy jakiegoś obliczenia... Na pewno nic zmieni to wartości zmiennej w funkcji wywołuj ąccj.
Gdy mamy już utworzoną własną funkcję, potrzebujemy jeszcze możliwości jej wywołania. Okazuje się, że jest to bardzo intuicyjne. Nie ma różnicy pomiędzy sposobem wywoływania własnej funkcji a jednej z funkcji standartowej, z jakich korzystaliśmy do tej pory. Tak więc wywołanie naszej funkcji przebiegnie
Wys wiet!flex (wartość);
Wartość w nawiasach może być różnego typu. Może być to zmienna, może być wartość stała, może być całe wyrażenie... Co bardzo ciekawe, można tutaj także wywołać inną funkcję. Załóżmy czysto teoretycznie, że chcemy wyświetlić wartość jakiejś „zmiennej” umieszczonej w pamięci programu. Jak pokazywałem wcześniej, w tym celu konieczne jest wykorzystanie makra pgm_read. Przykład takiego działania przedstawia poniższy pseudokod (działający przykład udostępniam na stronie internetowej):
Wys«ietlHex(pgm_read_word {Łę<_Stala)) ;
W ten sposób podaliśmy jako parametr naszej funkcji wynik działania innej funkcji. Istnienie takiej możliwości sprawia, że możemy oszczędzić na zmiennych tymczasowych. Inaczej konieczne byłoby utworzenie dodatkowej zmiennej, wpisanie do niej wyniku działania funkcji odczytu z pamięci
d HyjidetlBoatuU.ciSj;
programu i dopiero przesłanie tej zmiennej do wyświetlania.
Z drugiej strony, w bardzo złożonych przypadkach, rozwiązanie zc zmienną tymczasową może znacznie uprościć zapis. Pamiętaj wtedy, że przedstawiona przed chwilą możliwość jest tylko możliwością. C nie zmusza nikogo do pisania w taki, a nic inny sposób.
Powinno pojawić się, już nawet wcześniej, pytanie: „No dobrze... ale czy funkcję można wywołać ot tak sobie: zawsze i w dowolnym miejscu?”. Odpowiedź jest bardziej niż oczywista: „Niestety, nie można”. Zanim funkcja zostanie wywołana, musi być zdeklarowana. Deklaracja (unkcji to powiadomienie kompilatora o tym, że dana funkcja istnieje oraz o tym. jakie przyjmuje parametry. Od strony „kuchennej” deklaracja to nic innego jak powtórzona nazwa funkcji, razem z jej typem oraz informacją o parametrach. Deklaracja jednak w odróżnieniu od definicji nie zawiera ciała funkcji. Zamiast tego, zaraz za nawiasem z parametrami, umieszczamy znak średnika. Jest to konieczne, aby kompilator wiedział o co chodzi i nie szukał początku ciała funkcji.
Uważaj teraz. Okazuje się, że zdefiniowanie funkcji oznacza także jej zdeklarowanie. Sprawa jest prostsza, niż wynikałoby ze skomplikowania poprzedniego zdania. Oznacza to tylko tyle, że jeśli definiujesz funkcję (przypominam - stworzysz pełny opis razem z opisem działania) przed miejscem jej wywołania, nie jest konieczne umieszczanie nigdzie jej deklaracji. Dlatego też często funkcję main umieszcza się na końcu. Dzięki temu unikamy wpisywania dodatkowych linijek kodu, Jednak nie zawsze umieszczanie definicji ponad miejscem wywołania jest wygodne. Czasami może okazać się nawet niemożliwe. Deklarację w takim przypadku umieszcza się najczęściej zaraz za lub zaraz przed zmiennymi globalnymi. Ogólniej - już po dołączeniu wszystkich plików nagłówkowych, ale jeszcze przed definicją jakiejkolwiek funkcji.
Ogólnie ilustruje to poniższy obrazek (pseudo-kod):
Upiec 2005 Elektronika dla Wszystkich