Autor: Dondu
Kurs języka C: Spis treści
Funkcje są podstawą języka C!
Są to wydzielone części programu, które wykonują zadane czynności i/lub przetwarzając podane im dane tzw. argumenty. Funkcje po zakończeniu działania mogą (lecz nie muszą) zwracać jakieś dane.
Nawiązując do innych języków funkcje są odpowiednikami podprogramów, czy procedur.
Innymi słowy, to pracownicy specjaliści do określonych małych lub większych zadań. Zaletą funkcji jest możliwość umieszczenia w niej określonej często wykorzystywanej części kodu, a następnie wywoływanie (uruchamianie) funkcji w wielu różnych miejscach programu.
Z punktu widzenia programisty prawie każdy program należy dzielić na mniejsze zadania realizowane w postaci funkcji. W ten sposób program staje się krótki i przejrzysty.
Funkcje są bardzo elastyczne czyli można je definiować i używać na wiele sposobów.
Zanim przejdziemy do przykładów musisz poznać sporo istotnych rzeczy.
Definiowanie funkcji
Aby funkcję "powołać do życia" należy ją zdefiniować w ten sposób:
typ NazwaFunkcji (argumenty) {
... jakiś kod do wykonania
}
... jakiś kod do wykonania
}
gdzie:
typ
Określa typ danej jaką zwraca funkcja po jej wykonaniu. Typ danej może być dowolnym typem danych opisanych szczegółowo w temacie: Typy danych
NazwaFunkcji()
Dowolna nazwa jaką sobie wymyślisz jednakże podlegająca takim samym zasadom jak nazwy zmiennych, o których możesz się dowiedzieć w temacie: Zmienne - nazwy i deklaracja
Do nazwy funkcji należy dodać nawiasy (zwykłe) otwierający i zamykający.
W nawiasach tych wpisujemy:
argumenty
To dane przekazywane do funkcji przez program ją wywołujący (nadrzędny). Więcej na ten temat w dalszej części artykułu.
{ }
Nawiasy określające początek i koniec funkcji, czyli blok kodu z którego składa się funkcja. Zasady dotyczące bloków kodu poznasz na przykładzie: Zmienne lokalne blokowe
Oprócz powyższych poznać musisz jeszcze dwa słowa kluczowe void oraz return.
void (ang. pustka, próżnia, pozbawiony czegoś)
To słowo kluczowe oznaczające brak wartości lub po prostu nic. W przypadku funkcji słowo to stosuje się jako:
- typ funkcji - oznacza wtedy że funkcja nie zwraca żadnej wartości,
- argument funkcji - oznacza, że funkcja nie ma żadnych argumentów.
return;
return JakasDana;
Return służy do:
- przerwania wykonywania funkcji,
- przerwania wykonywania funkcji i zwrócenia danej, o typie określonym w czasie definiowania funkcji (typ).
Jeżeli w funkcji nie ma słowa return, to po dojściu do końca funkcji następuje wyjście z niej tak jakby wykonano return bez podania zwracanej danej.
Przejdźmy więc do meritum tematu. Zaczniemy jednakże od specyficznej funkcji, którą jest funkcja main() ponieważ będzie nam potrzebna w każdym przykładzie:
main()
To funkcja, od której wywołania (uruchomienia) zaczyna się wykonywanie napisanego programu.
W trakcie kompilowania, kompilator szuka funkcji main() i przygotowuje kod wynikowy w taki sposób, by od realizacja programu rozpoczęła się od tej funkcji. Jeżeli nie zdefiniujesz funkcji main(), to kompilator pokażę błąd kompilacji i przerwie ją.
Ponieważ funkcja main() jest wyjątkiem podlega więc szczególnym zasadom i powinna być zawsze definiowana w następujący sposób:
- musi być typu int,
- nie może mieć argumentów,
- musi kończyć się zwróceniem zera.
Prawidłowo napisana definicja funkcji main() wygląda tak:
Przykład 1 (w kompilatorze)
int main(void){ return 0; }
W kompilatorze CManiak znajdziesz ten przykład. Skompiluj w wersji takiej jak jest, by sprawdzić jakie kompilator pokaże komunikaty.
Teraz zdefiniujemy sobie różne funkcje, którym wyznaczymy jakieś zadania do zrealizowania. Aby zobaczyć rezultaty posługiwać się będziemy funkcją drukowania printf().
Funkcja bez argumentów i bez zwracania danej
Przykładem będzie wywołanie funkcji w celu wydrukowania napisu w niej zawartego.
Przykład 2 (w kompilatorze)
void pokaz(void){ printf("a ten drugi."); } int main(void) { printf("Ten napis jest pierwszy, \n"); pokaz(); return 0; }
Program rozpocznie się od wykonania funkcji main( ), która najpierw wydrukuje napis pierwszy, a później wywoła funkcję pokaz( ), która wydrukuje napis drugi.
Zauważ, że w przypadku funkcji pokaz( ) jako typ oraz argument podaliśmy void, czyli:
- funkcja nie będzie niczego zwracać,
- nie przekazujemy funkcji żadnych danych.
Skompiluj powyższy przykład w kompilatorze CManiak i zobacz rezultaty w zakładce Terminal.
Funkcja z argumentem, ale bez zwracania danej
Teraz przekażemy funkcji jakąś daną, którą będzie miała wydrukować. Do zapamiętania danej w funkcji pokaz( ) użyjemy zmiennej, którą nazwiemy liczba. Przyjmijmy, że dana ta będzie typu char.
Przykład 3 (w kompilatorze)
void pokaz(char liczba){ printf("%d", liczba); } int main(void) { printf("Ilość krów w oborze = "); pokaz(5); return 0; //zakończ wykonywanie programu }
I ponownie kompilujemy w CManiak'u i oglądamy rezultat w zakładce Terminal.
Funkcja bez argumentów, ale zwracająca daną
Czas na funkcję, która zwróci nam jakąś wartość. Na razie funkcji nie podamy żadnego argumentu.
Przykład 4 (w kompilatorze)
//definiujemy funkcję podaj_liczbe() która: // - będzie zwracała liczbę typu char // - nie wymaga podania żadnych argumentów char podaj_liczbe(void){ return 53; //zakończ wykonywanie funkcji zwracając liczbę 53 } //program zaczyna się od funkcji main() int main(void) { //wydrukuj liczbę którą zwróci funkcja printf("%d", podaj_liczbe() ); return 0; //zakończ wykonywanie programu }
Funkcja z argumentami i zwracająca daną
Teraz zbudujemy funkcję z dwoma argumentami (jeden typu char, drugi typu int) oraz oczekiwać będziemy, że funkcja zwróci liczbę typu int.
Przykład 5 (w kompilatorze)
//definiujemy funkcję oblicz() typu int //z dwoma argumentami typu char oraz int int oblicz(char zm1, int zm2){ return zm1 * zm2; //zwróć wynik mnożenia argumentów } //program zaczyna się od funkcji main() int main(void) { //pokaż napis printf("zm1 * zm2 = %d", oblicz(123, 456) ); return 0; //zakończ wykonywanie programu }
Przykłady z życia wzięte
Aby poćwiczyć wykorzystanie funkcji zdefiniujemy funkcję, która będzie odpowiedzialna za obliczanie wyniku funkcji kwadratowej (matematyka) dla podanych liczb jako argumentów wywołania funkcji.
W języku C nie ma operatora arytmetycznego podnoszącego liczbę do kwadratu, więc po prostu pomnożymy x przez siebie, czyli:
Nasza funkcja wymagać będzie podania argumentów: x, a, b oraz c zwracając wynik obliczenia czyli y.
Abyśmy mogli wypróbować w kompilatorze jak liczy nasza funkcja na liczbach zmiennoprzecinkowych, wszystkie zmienne oraz funkcja będą typu double.
Przykład 6 (w kompilatorze)
double FunkcjaKwadratowa(double x, double a, double b, double c ) { double y; y = a*x*x + b*x + c; return y; //zwróć wynik } int main(void) { printf("y = %f \n", FunkcjaKwadratowa(102, 0.5, 10, 100) ); return 0; }
W kompilatorze CManiak czeka na ciebie przykład wraz z komentarzami. Wypróbuj jak działa powyższy przykład i wstawiaj swoje liczby. Pamiętaj, że przecinek oddziela argumenty, a kropka oddziela część całkowitą liczby od części ułamkowej.
Drugi przykład z życia wzięty to liczenie silni danej liczby naturalnej.
W algorytmie wykorzystamy pętlę for(...) { ... }.
Przykład 7 (w kompilatorze)
//definiujemy funkcję silnia() typu int (liczby całkowite) //z jednym argumentem n typu int int silnia(int n) { int k; //zmienna pomocnicza int wynik=1; //zmienna przechowująca wynik liczenia silnii //pętla licząca silnię for(k=1; k<=n; k++){ wynik = wynik * k; } return wynik; //zwróć wynik } //program zaczyna się od funkcji main() int main(void) { printf("silnia = %d \n", silnia(5) ); //pokaż silnię dla liczby 5 return 0; //zakończ wykonywanie programu }
I znowu zaglądając do tego przykładu w CManiak'u możesz poćwiczyć rozumienie tego przykładu użycia funkcji w języku C.
Sukces vs niepowodzenie
Pisząc swoje programy powinieneś używać pewnego standardu określania, czy działanie funkcji zostało zakończone sukcesem czy niepowodzeniem.
Chodzi o takie funkcje które nie zwracają wyniku jako takiego, ale wykonują jakieś czynności i chcą powiadomić program który je wywołał, że wykonały zadanie z sukcesem lub niepowodzeniem.
Sukces powinieneś definiować jako 1, a niepowodzenie jako 0.
Najprościej zrozumieć to jest poprzez przykład.
Przykład 8 (w kompilatorze)
//definiujemy funkcję CzyWiekszaOdTysiaca() typu char //z jednym argumentem liczba typu double char CzyWiekszaOdTysiaca(double liczba) { //sprawdzamy czy liczba jest większa od tysiąca if(liczba > 1000){ return 1; //sukces (bo jest większa od 1000) }else{ return 0; //niepowodzenie } } //program zaczyna się od funkcji main() int main(void) { //sprawdź liczbę printf("%d", CzyWiekszaOdTysiaca(999) ); return 0; //zakończ wykonywanie programu }
Takie podejście definiowania sukcesu i niepowodzenia pozwala na łatwe wykorzystanie podczas sprawdzania warunków instrukcjami warunkowymi.
I znowu skorzystamy z CManiaka by zobaczyć jak to ułatwia pisanie kodu. Wykorzystamy funkcję CzyWiekszaOdTysiaca() zdefiniowaną w poprzednim przykładzie, ale wynik jej działania wykorzystamy tak:
Przykład 9 (w kompilatorze)
//program zaczyna się od funkcji main() int main(void) { int a; //deklaracja zmiennej, którą będziemy sprawdzać //zaczniemy dla a=997 a skończymy na a=1010 //zwiększając a o jeden za każdym krokiem pętli for() for(a=997; a<=1010; a++){ //sprawdzamy czy a jest większe od 1000 wywołując //funkcję i podając jako argument zmienną a if( CzyWiekszaOdTysiaca(a) ){ //gdy jest sukces printf("%d jest większe od 1000 - sukces!!!\n", a); }else{ //gdy jest niepowodzenie printf("%d jest mniejsze bądź równe 1000 - niepowidzenie \n", a); } } return 0; //zakończ wykonywanie programu }
Podsumowanie
Funkcje są bardzo elastycznymi fragmentami programu, które mogą spełniać przeróżne zachcianki programisty. Bardzo ważne jest by opanować pisanie funkcji do perfekcji, bo znacząco ułatwi Ci to dzielenie programu na spójne fragmenty, a później składanie z nich całego programu. W ten sposób programy stają się krótkie, czytelne i co najważniejsze łatwo i szybko można je modyfikować.
Co więcej, dobrze napisane funkcje można często wykorzystywać w innych programach, co znacząco przyspiesz ich pisanie.
Jeżeli czegoś nie rozumiesz, śmiało zadawaj pytania w komentarzach.
Kurs języka C: Tips & Tricks - Spis treści
Kurs języka C: Spis treści
33
Nie rozumiem przykładu nr4. Tyle pisania żeby otrzymać liczbę którą i tak założyliśmy że zostanie zwrócona? Nie wystarczyło napisać by wyświetlić liczbę 53?
OdpowiedzUsuń#include
int main(void)
{
printf("A nie można było tak:\n \n");
printf("Tu wpisuję liczbę 53.");
return 0;
}
Przykład nr 4 zatytułowany jest: Funkcja bez argumentów, ale zwracająca daną
OdpowiedzUsuńi opisany co chcemy osiągnąć.
Celem tego przykładu jest pokazanie jak wywołać funkcję, która zwróci jakąś wartość. Pokazałem najprostszy przykład, ale przecież w funkcji mogą być skomplikowane obliczenia i wile linijek kodu. Będzie taki przykład w dalszej części tego artykułu, gdy go już skończę :-)