Deklarowanie wskaźników do funkcji
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 33 z 61.
Jak dotąd uczyliśmy się symulować dziedziczenie za pomocą osadzania struktur. Prawdziwy polimorfizm, w którym różne obiekty różnie reagują na to samo wywołanie, wymaga jednak czegoś więcej: wskaźników do funkcji.
Wskaźnik do funkcji to zmienna przechowująca adres funkcji. Podobnie jak zwykły wskaźnik przechowuje adres danych, wskaźnik do funkcji przechowuje adres wykonywalnego kodu.
Składnia może początkowo wydawać się onieśmielająca. Aby zadeklarować wskaźnik na funkcję, określasz typ zwracany, następnie nazwę wskaźnika w nawiasach z gwiazdką, a po niej typy parametrów:
int (*operation)(int, int);Ta deklaruje zmienną o nazwie operation, która może wskazywać na dowolną funkcję przyjmującą dwa parametry typu int i zwracającą int. Nawiasy wokół *operation są kluczowe — bez nich deklarowałbyś funkcję zwracającą wskaźnik.
Aby przypisać funkcję do tego wskaźnika, po prostu użyj nazwy funkcji (bez nawiasów):
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // Teraz operation wskazuje na addNazwa funkcji pełni rolę jej adresu. Możesz też jawnie użyć &add, ale nie jest to konieczne: w języku C obie formy są równoważne.
Wyzwanie
ŁatwyPoćwiczmy deklarowanie wskaźników do funkcji i przypisywanie im funkcji. Utworzysz prosty system operacji matematycznych, w którym wskaźnik do funkcji może przechowywać różne funkcje arytmetyczne.
Napisz program, który:
- Definiuje dwie funkcje:
multiply: przyjmuje dwa parametry typuinti zwraca ich iloczynsubtract: przyjmuje dwa parametry typuinti zwraca różnicę pierwszej liczby i drugiej
- W
maindeklaruje zmienną będącą wskaźnikiem do funkcji o nazwieoperation, która może wskazywać na funkcje przyjmujące dwa parametry typuinti zwracające wartość typuint - Odczytuje trzy dane wejściowe: dwie liczby całkowite i kod operacji (1 oznacza mnożenie, 2 oznacza odejmowanie)
- Na podstawie kodu operacji przypisuje odpowiednią funkcję do wskaźnika
operation - Wyświetla nazwę przypisanej operacji, a następnie wynik wywołania funkcji za pośrednictwem wskaźnika
Otrzymasz trzy dane wejściowe: pierwszą liczbę, drugą liczbę i kod operacji (1 lub 2).
Wyjście powinno wyglądać tak:
Operation: multiply
Result: 35Gdzie multiply to nazwa operacji (lub subtract, jeśli kod wynosi 2), a 35 to wynik wywołania funkcji za pośrednictwem wskaźnika (w tym przypadku 5 × 7).
Pamiętaj: aby zadeklarować wskaźnik do funkcji, potrzebujesz typu zwracanego, nazwy wskaźnika w nawiasach z gwiazdką oraz typów parametrów. Aby przypisać funkcję, użyj samej jej nazwy, bez nawiasów.
Spróbuj swoich sił
#include <stdio.h>
// TODO: Zdefiniuj tutaj funkcję multiply
// TODO: Zdefiniuj tutaj funkcję subtract
int main() {
int num1, num2, code;
// Wczytaj dane wejściowe
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &code);
// TODO: Zadeklaruj wskaźnik do funkcji o nazwie 'operation', który może wskazywać na
// funkcje przyjmujące dwa parametry typu int i zwracające int
// TODO: Na podstawie kodu operacji (1 oznacza mnożenie, 2 oznacza odejmowanie)
// przypisz odpowiednią funkcję do wskaźnika operation
// TODO: Wypisz nazwę operacji i wynik
// Format:
// Operation: <name>
// Result: <result>
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