Typedef для указателей на функции
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 35 из 61.
Как вы уже видели, объявления указателей на функции бывает трудно читать. Когда вам нужно использовать один и тот же тип указателя на функцию в нескольких местах, синтаксис становится повторяющимся и подверженным ошибкам. Здесь на помощь приходит typedef.
Ключевое слово typedef позволяет создать alias для любого типа, включая указатели на function. Вместо того чтобы каждый раз писать полное объявление, вы определяете тип один раз и используете alias во всём своём коде.
Вот как преобразовать объявление указателя на function в typedef:
// Без typedef (грязно):
int (*operation)(int, int);
// С typedef (чисто):
typedef int (*Operation)(int, int);
Operation op; // Намного чище!Синтаксис повторяет объявление обычного указателя на function, но с typedef в начале. Выбранное тобой имя (здесь — Operation) становится новым типом, который представляет собой «указатель на function, принимающую два значения типа int и возвращающую значение типа int».
Теперь вы можете использовать этот тип где угодно:
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
Operation op1 = add;
Operation op2 = multiply;
printf("%d\n", op1(3, 4)); // Вывод: 7
printf("%d\n", op2(3, 4)); // Вывод: 12
return 0;
}Этот подход особенно ценен при передаче указателей на function в качестве parameters или их хранении в структурах: с такими ситуациями вы будете часто сталкиваться по мере продвижения к полиморфизму.
Задание
ЛегкоДавайте потренируемся использовать typedef, чтобы создать clean alias для типа указателя на comparison function. Вы объявите тип, представляющий function, сравнивающую два целых числа, а затем используете его для объявления переменных и вызова различных comparison functions.
Напишите программу, которая:
- Создаёт
typedefс именемComparatorдля типа указателя на function, которая:- Принимает два параметра
int - Возвращает
int(negative, если first меньше, zero, если значения равны, positive, если first больше)
- Принимает два параметра
- Определяет две comparison functions:
ascending: возвращает значение, указывающее ascending порядок (first - second)descending: возвращает значение, указывающее descending порядок (second - first)
- В
mainобъявляет переменнуюComparator(используя свой typedef, а не необработанный синтаксис указателя на function) - Считывает три входных значения: два целых числа и код порядка (1 для ascending, 2 для descending)
- Присваивает appropriate function переменной
Comparatorна основе кода порядка - Вызывает comparator с двумя числами и выводит result, а затем сообщение, указывающее, какое значение должно идти first
Вы получите три входных значения: first number, second number и order code (1 или 2).
В вашем выводе должен отображаться результат сравнения, а затем указываться, какое number идёт first, на основе знака result:
Result: -5
First: 3В этом примере с input 3, 8, 1 (ascending order): comparison возвращает 3 - 8 = -5 (negative означает, что first number идёт first в ascending order), поэтому мы выводим First: 3.
Для строки "First":
- Если result negative или zero, выведите first input number
- Если result positive, выведите second input number
Ключевая практика здесь — использовать ваш Comparator typedef для clean объявления переменной вместо записи полного синтаксиса указателя на function.
Попробуйте сами
#include <stdio.h>
// TODO: Создайте typedef с именем 'Comparator' для типа указателя на функцию
// который принимает два параметра int и возвращает int
// TODO: Определите функцию сравнения 'ascending'
// Должна возвращать (first - second)
// TODO: Определите функцию сравнения 'descending'
// Должна возвращать (second - first)
int main() {
// Читаем ввод
int num1, num2, orderCode;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &orderCode);
// TODO: Объявите переменную Comparator, используя ваш typedef
// TODO: Присвойте соответствующую функцию на основе orderCode
// (1 для ascending, 2 для descending)
// TODO: Вызовите компаратор и сохраните результат
int result;
// Выводим результат
printf("Result: %d\n", result);
// TODO: Выведите, какое число идёт первым на основе результата
// Если result отрицательный или равен нулю, напечатайте первое число
// Если result положительный, напечатайте второе число
printf("First: %d\n", /* ваша логика здесь */ 0);
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик7Указатели на функции
Объявление указателей на функцииВызов указателей на функцииTypedef для указателей на функцииПередача функций в качестве аргументовИтоги: Диспетчеризация калькулятора2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C