Объявление указателей на функции
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 33 из 61.
До сих пор мы учились имитировать наследование с помощью встраивания структур. Но истинный полиморфизм — когда разные объекты по-разному реагируют на один и тот же вызов — требует кое-чего большего: указателей на функции.
Указатель на функцию — это переменная, которая хранит адрес функции. Точно так же, как обычный указатель хранит адрес данных, указатель на функцию хранит адрес исполняемого кода.
Синтаксис can показаться сложным на первый взгляд. Чтобы объявить function pointer, вы указываете return тип, затем pointer имя в скобках со звёздочкой, за которым следуют типы параметров:
int (*operation)(int, int);Это объявляет переменную с именем operation, которая может указывать на любую функцию, принимающую два параметра типа int и возвращающую int. Скобки вокруг *operation крайне важны — без них вы бы объявили функцию, возвращающую указатель.
Чтобы присвоить функцию этому указателю, просто используйте имя функции (без скобок):
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // Теперь operation указывает на addИмя функции выступает в качестве её адреса. Вы также можете явно использовать &add, но это необязательно — обе формы эквивалентны в C.
Задание
ЛегкоДавайте потренируемся объявлять указатели на функции и присваивать им функции. Вы создадите простую систему математических операций, в которой указатель на функцию может хранить различные арифметические функции.
Напишите программу, которая:
- Определяет две функции:
multiply— принимает два параметра типаintи возвращает их произведениеsubtract— принимает два параметра типаintи возвращает разность первого и второго
- В
mainобъявляет переменную-указатель на функцию с именемoperation, которая может указывать на функции, принимающие два параметра типаintи возвращающиеint - Считывает три входных значения: два целых числа и код операции (1 для multiply, 2 для subtract)
- На основе кода операции присваивает соответствующую функцию вашему указателю
operation - Выводит имя назначенной операции, а затем выводит результат вызова функции через указатель
Вы получите три входных значения: первое число, второе число и код операции (1 или 2).
Ваш вывод должен выглядеть следующим образом:
Operation: multiply
Result: 35Где multiply — это название операции (или subtract, если код равен 2), а 35 — результат вызова функции через ваш указатель (в данном случае 5 × 7).
Помните: чтобы объявить указатель на функцию, вам нужен тип возвращаемого значения, имя указателя в круглых скобках со звездочкой и типы параметров. Чтобы присвоить функцию, используйте только имя функции без круглых скобок.
Попробуйте сами
#include <stdio.h>
// TODO: Определите функцию multiply здесь
// TODO: Определите функцию subtract здесь
int main() {
int num1, num2, code;
// Считать ввод
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &code);
// TODO: Объявите указатель на функцию с именем 'operation', который может указывать на
// функции, принимающие два параметра int и возвращающие int
// TODO: На основе кода операции (1 для multiply, 2 для subtract),
// присвойте соответствующую функцию вашему указателю operation
// TODO: Выведите название операции и результат
// Формат:
// Operation: <name>
// Result: <result>
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик7Указатели на функции
Объявление указателей на функцииВызов указателей на функцииTypedef для указателей на функцииПередача функций в качестве аргументовИтоги: Диспетчеризация калькулятора2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигур