Wywoływanie funkcji przez wskaźniki
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 34 z 61.
Skoro już wiesz, jak zadeklarować wskaźnik na funkcję i przypisać do niego funkcję, następnym krokiem jest faktyczne wywołanie funkcji za pomocą tego wskaźnika.
Składnia jest prosta. Używasz wskaźnika do funkcji tak samo, jak wywołujesz zwykłą funkcję:
int add(int a, int b) {
return a + b;
}
int main() {
int (*operation)(int, int) = add;
int result = operation(5, 3); // Wywołuje add(5, 3)
printf("%d\n", result); // Wynik: 8
return 0;
}Wystarczy wpisać nazwę wskaźnika, a po niej nawiasy zawierające argumenty. C automatycznie dereferencjonuje wskaźnik i wykonuje funkcję, na którą wskazuje.
Możesz też użyć jawnej składni dereferencji z (*operation)(5, 3), ale jest to opcjonalne i rzadziej spotykane. Obie formy dają identyczne wyniki.
Prawdziwa moc ujawnia się, gdy przypisujesz wskaźnik do różnych funkcji:
int subtract(int a, int b) {
return a - b;
}
operation = subtract;
result = operation(5, 3); // Teraz wywołuje subtract(5, 3)
printf("%d\n", result); // Wynik: 2Ta sama zmienna operation wykonuje teraz zupełnie inną logikę. Możliwość zamiany zachowania w czasie działania programu stanowi podstawę polimorfizmu w C.
Wyzwanie
ŁatwyPoćwiczmy wywoływanie funkcji za pomocą wskaźników oraz zmianę wykonywanej funkcji. Zbudujesz prosty kalkulator, który może przełączać się między dodawaniem a odejmowaniem w czasie działania programu.
Napisz program, który:
- Definiuje dwie funkcje:
add: przyjmuje dwa parametry typuinti zwraca ich sumęsubtract: przyjmuje dwa parametry typuinti zwraca różnicę pierwszej liczby i drugiej
- W funkcji
maindeklaruje wskaźnik na funkcję o nazwiecalc, który może wskazywać na funkcje przyjmujące dwa parametry typuinti zwracające wartość typuint - Odczytuje cztery dane wejściowe: dwie liczby całkowite i dwa kody operacji
- Dla każdego kodu operacji:
- Przypisuje odpowiednią funkcję do
calc(1 dla dodawania, 2 dla odejmowania) - Wywołuje funkcję za pomocą wskaźnika, przekazując jej te dwie liczby
- Wyświetla wynik
- Przypisuje odpowiednią funkcję do
Otrzymasz cztery dane wejściowe: pierwszą liczbę, drugą liczbę, pierwszy kod operacji (1 lub 2) oraz drugi kod operacji (1 lub 2).
Wynik powinien zawierać dwa rezultaty w osobnych wierszach: po jednym dla każdej operacji wykonanej na tych samych dwóch liczbach:
15
5W tym przykładzie dla danych wejściowych 10, 5, 1, 2: pierwsza operacja (kod 1) dodaje 10 + 5 = 15, następnie wskaźnik zostaje ponownie przypisany, a druga operacja (kod 2) odejmuje 10 - 5 = 5.
To pokazuje, jak ta sama zmienna wskaźnikowa może wykonywać zupełnie inną logikę dzięki zmianie przypisanej do niej funkcji między wywołaniami.
Spróbuj swoich sił
#include <stdio.h>
// TODO: Zdefiniuj tutaj funkcję add
// TODO: Zdefiniuj tutaj funkcję subtract
int main() {
// Wczytaj dane wejściowe
int num1, num2, op1, op2;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &op1);
scanf("%d", &op2);
// TODO: Zadeklaruj wskaźnik do funkcji o nazwie 'calc', który może wskazywać na
// funkcje przyjmujące dwa parametry typu int i zwracające wartość typu int
// TODO: Dla pierwszego kodu operacji (op1):
// - Przypisz odpowiednią funkcję do calc (1 dla add, 2 dla subtract)
// - Wywołaj funkcję przez wskaźnik i wypisz wynik
// TODO: Dla drugiego kodu operacji (op2):
// - Ponownie przypisz odpowiednią funkcję do calc
// - Wywołaj funkcję przez wskaźnik i wypisz wynik
return 0;
}Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania modularnego
Pliki nagłówkoweZabezpieczenia przed wielokrotnym dołączeniemPliki źródłoweFunkcje statycznePodsumowanie: kalkulator modularny4Enkapsulacja
Koncepcja niejawnych wskaźnikówDefiniowanie niejawnych strukturGettery i setteryWalidacja w setterachPowtórka: tajemnicze pudełko7Wskaźniki do funkcji
Deklarowanie wskaźników do funkcjiWywoływanie funkcji przez wskaźnikiTypedef dla wskaźników do funkcjiPrzekazywanie funkcji jako argumentówPodsumowanie: wybór działania kalkulatora2Obiekty i metody
Struktury jako obiektyWskaźnik „self”Poprawność constWskaźnik czy wartośćMetody pomocniczePodsumowanie: menedżer punktów5Projekt: Proste konto bankowe
Konfiguracja projektuImplementacja konta8Polimorfizm
Wskaźniki do funkcji w strukturachSymulowanie metodKoncepcja interfejsuImplementowanie interfejsówIteracja polimorficznaPodsumowanie: Greeter11Wzorce projektowe w C
Wzorzec SingletonWzorzec fabrykiWzorzec iteratoraPodsumowanie: fabryka loggera3Cykl życia obiektu
Wzorzec konstruktoraWzorzec destruktoraInicjalizacja na stosieKopia głębokaPodsumowanie: klasa opakowująca ciąg znaków6Dziedziczenie przez kompozycję
Osadzanie strukturZasada pierwszego elementuDostęp do elementów klasy nadrzędnejKonwersja w górę hierarchiiPodsumowanie: hierarchia kształtów9Projekt: Rysownik kształtów
Przegląd projektuImplementacja kołaImplementacja prostokątaZastosowanie polimorfizmuKontener kształtówPoćwicz samodzielnie: Kompilator C online