13 Metodyka i Techniki Programowania C: Funkcje dr inż. Jarosław Bułat 2013.01.12 Jeżeli uświadomisz sobie, że system operacyjny Windows czy Linux to ...
10 downloads
20 Views
52KB Size
13
Metodyka i Techniki Programowania C: Funkcje dr inż. Jarosław Bułat
2013.01.12
Jeżeli uświadomisz sobie, że system operacyjny Windows czy Linux to też program na pewno dojdziesz do wniosku że nie został cały napisany wewnątrz bloku programu (funkcji) main()... Program składający się ze 100 linii czasami warto podzielić na części żeby był bardziej czytelny albo żeby go było łatwiej rozwijać w przyszłość. Takie części to właśnie funkcje.
Funkcje Poniżej znajduje się fragment kodu ilustrujący wykorzystanie funkcji. W tym przypadku została utworzona funkcja dodająca dwie zmienne całkowito-liczbowe. int suma( int x, int y ) { int wynik; wynik = x+y;
// deklaracja i definicja funkcji
return wynik; } int main( void ) { int y = 4; int x = 7; int z = suma( y, x ); // wywołanie funkcji printf( "suma=%d, druga suma=%d\n", z, suma(3,y) ); // printf() to też jest funkcja :) return 0; }
Program wystartuje zawsze z funkcji main(...), chociaż deklaracja funkcji suma(...) jest ,,wyżej''. Utworzona funkcja jest typu int (jako wynik zwraca takiego typu liczbę) oraz ma dwa argumenty typu int – czyli można jej przekazać dwie całkowito-liczbowe wartości. Zauważ, że funkcję można wywołać wiele razy, z różnych miejsc w kodzie. Można jej przekazać wartości liczbowe lub zmienne. Pamiętaj: przekazywanie argumentów w języku C/C++ odbywa się zawsze przez kopię. Oznacza to, że zmienna x w funkcji mian(...) i zmienna x w funkcji suma(...) to zupełnie dwie różne zmienne – zbieżność nazw jest celowa ale nie ma absolutnie żadnego znaczenia na wynik działania programu. Nie spodziewaj się też ,,zobaczyć'' zmiennej z w funkcji suma(...) ona istnieje tylko w obrębie funkcji main(...). Zmodyfikuj powyższy program tak, aby dodawał do siebie 3 liczby rzeczywiste.
Przekazywanie argumentów Implikacja przekazywania argumentów funkcji przez kopię jest przedstawiona na poniższym fragmencie kodu: int inc( int );
// deklaracja funkcji
int main(void) { int y = 4; inc( y ); printf( "4++=%d !@#$%%\n", y ); return 0; } int inc( int x ) { return ++x;
// definicja funkcji
} Funkcja zwiększa wartość argumentu ale robi to lokalnie więc w funkcji main(...) nie widać rezultatów. Dzieje się tak dlatego ponieważ funkcja inc(...) tak naprawdę zwiększa o jeden kopię zmiennej y a nie zmienną y.
Dodatkowo warto zauważyć, że nie odebrałem (tak jak w poprzednim kodzie) wartości zwracanej przez funkcję. W języku C/C++ można tak zrobić, wtedy wartość przekazywana przez funkcję zostaje ,,zapomniana'' – nie jest wpisana do żadnej zmiennej. Wywołanie funkcji przynoszące efekt inkrementacji powinno wyglądać następująco: y = inc( y ); Wtedy rezultat (argument zwiększony o 1) trafia z powrotem do zmiennej y. Zauważ, że w powyższym przykładzie definicja i deklaracja funkcji została rozdzielona. Umożliwia to zdefiniowanie funkcji poniżej pierwszego jej wywołania. W deklaracji i definicji należy podać takie same typu dla argumentów i wartości. W deklaracji nie trzeba podawać nazw zmiennych – wystarczą same typy. Modyfikacja powyższego programu pozwalająca ,,zmodyfikować'' argument. void inc( int* );
// deklaracja funkcji niezwracającej żadnej wartości (void)
int main(void) { int y = 4; inc( &y ); // przekazanie wskaźnika do zmiennej printf( "4++=%d\n", y ); return 0; } void inc( int *x ) // definicja funkcji niezwracającej żadnej wartości (void) { (*x)++;
} Powyżej do funkcji przekazywany jest wskaźnik a dokładnie kopia wskaźnika. Funkcja modyfikuje zmienną spod tego wskaźnika więc w tym przypadku modyfikuje bezpośrednio zmienną y z funkcji main(...). Jest to sposób na umożliwienie modyfikacji zmiennej spoza funkcji. Zauważ, że ten sposób był używane do wczytywania danych ze standardowego wejścia za pomocą funkcji scanf(...). Dodatkowo ta technika pozwala na obejście drugiego ograniczenia – instrukcja return pozwala zwrócić tylko jedną wartość. Używając wskaźników w argumentach możemy przekazać z funkcji rezultat składający się z wielu zmiennych. Uzupełnij poniższy kod mnożący dwie liczby zespolone. Mnożenie wykonaj za pomocą funkcji, którą zaprojektujesz, zadeklarujesz i zdefiniujesz. int main(void) { int x1r=1, x1i=2; int x2r=2, x2i=7; int x3r, x3i; // uzupełnij printf( "(%d+i%d)*(%d+i%d)=(%d+i%d)\n", x1r, x1i, x2r, x2i, x3r, x3i ); } Wykonaj to samo zadanie, tylko przekaż wynik za pomocą zmiennych globalnych. Zmienna globalna to zmienna ,,widoczna'' dla wszystkich funkcji zadeklarowanych poniżej tej zmiennej. Zmienne te są deklarowane na zewnątrz funkcji – zazwyczaj zaraz po bloku dyrektyw #include<...>. Utwórz strukturę do reprezentacji funkcji zespolonych, użyj ich do powyższego kodu do przekazywania przez argumenty liczb zespolonych.