Zdarza się czasem, że potrzebujemy wykorzystać kilka funkcji w naszym programie. Jednym ze sposobów jest zaimplementowanie wielu różnych funkcji przy pomocy instrukcji sterujących (if, switch). Jednak wtedy rozmiar kodu może się drastycznie zwiększyć, tudzież czytelność kodu może zmaleć. Co wtedy robić? Z pomocą przychodzą wskaźniki. Z początku bardzo nie lubiłem wskaźników w C++, jednak pomału przyzwyczajam się do nich, mało tego, uważam, że są bardzo całkiem proste w użyciu! Tak, tak, dobrze przeczytałeś. Nie są trudne, ważne, by załapać ideę wskaźników, a potem to już pójdzie po maśle ;)
No ale wróćmy do tematu. Wskaźnik na funkcję. Jak można się domyślić, jest to po prostu liczba, która wskazuje adres w pamięci, gdzie zaczyna się nasza szukana funkcja. No dobrze, ale jak to wykorzystać? Są dwa sposoby. Pierwszy polega na napisaniu dodatkowej funkcji. Jeśli nasza funkcja posiada jeden argument (zakładamy, że argumenty i wartości zwracane przez funkcję są typu
double
- naturalnie, może to być dowolny typ):
double funkcja(double (*wskaznik_na_funkcje)(double), double x)
{
double wynik;
wynik = (*wskaznik_na_funkcje) (x);
return (wynik);
}
Początek deklaracji nie powinien dziwić - typ zwracany przez naszą funkcję pomocniczą i jej nazwa. Pierwszym parametrem jest wskaźnik na naszą funkcję, wraz z listą parametrów, jakie potrzebuje ta funkcja (w naszym wypadku jest to jeden parametr). Pierwsze
double
to oczywiście wartość zwracana przez funkcję. Drugim parametrem jest wartość liczbowa, która będzie potem parametrem wskazywanej funkcji.
W ciele funkcji deklarujemy sobie dodatkową zmienną, w której przechowamy wynik. I najważniejsze w tym wszystkim:
wynik = (*wskaznik_na_funkcje) (x);
. Te nawiasy są jak najbardziej potrzebne, w przeciwnym wypadku kompilator będzie to interpretować jako wskaźnik na liczbę. I teraz najważniejsze - wykorzystanie:
double a, b;
a = funkcja(sin, 1.74);
b = funkcja(cos, 1.74);
cout << a << "\n";
cout << b << "\n";
Innym sposobem jest wykorzystanie bezpośrednie tego wskaźnika, a mianowicie: deklarujemy najpierw zmienną wskaźnikową wraz z parametrami:
double (*func)(double);
A następnie musimy przypisać temu wskaźnikowi adres naszej funkcji:
func = sin;
a = func(1.74);
func = cos;
b = func(1.74);
Wykorzystanie, jak widać, jest również proste.
Można także skorzystać z tablicy wskaźników na funkcje.
Deklaracja tablicy wygląda tak:
double (*funkcje[4])(double);
Chyba nie trzeba tego tłumaczyć... Następnie przydzielamy odpowiednie wartości, np:
funkcje[0] = sin;
funkcje[1] = cos;
funkcje[2] = tan;
funkcje[3] = ctg;
(funkcję
ctg
zdefiniowałem jako:
pow(tan(x), -1.0)
)
I na koniec wykorzystanie:
for (int i = 0; i < 4; i ++)
cout << funkcje[i](3.1415 / 4.0) << "\n";
Prawda, że ładniej to wygląda? ;)