Обобщенное сравнение
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 52 из 61.
Универсальные функции, такие как qsort и bsearch в стандартной библиотеке C, нуждаются в способе сравнения элементов, не зная их типов. Решением является функция сравнения — функция, которую вы пишете и которую универсальный алгоритм вызывает всякий раз, когда ему нужно сравнить два элемента.
Стандартная сигнатура для функций сравнения:
int compare(const void* a, const void* b);Оба параметра имеют тип const void*, поскольку универсальная функция не знает, какой тип вы сортируете. Возвращаемое значение следует определенному соглашению:
| Возвращаемое значение | Значение |
|---|---|
| Отрицательное | a идет перед b |
| Ноль | a равно b |
| Положительное | a идет после b |
Внутри вашей функции сравнения вы приводите указатели void* к фактическому типу и сравниваете значения. Вот как сравнивать целые числа:
int compare_ints(const void* a, const void* b) {
int val_a = *(const int*)a;
int val_b = *(const int*)b;
return val_a - val_b;
}Прием с вычитанием хорошо работает для целых чисел: если a меньше, результат отрицательный; если равны — ноль; если больше — положительный. Эту функцию теперь можно передать в qsort для сортировки массива целых чисел по возрастанию.
Задание
ЛегкоНапишите функцию compare_ints, которая сравнивает два целых числа, следуя стандартному соглашению о функциях сравнения, используемому в универсальных алгоритмах, таких как qsort.
Ваша функция должна сравнить два значения и вернуть результат, указывающий на их порядок.
Соглашение о возвращаемом значении:
- Верните отрицательное значение, если первое целое число стоит перед вторым (первое < второго)
- Верните ноль, если оба целых числа равны
- Верните положительное значение, если первое целое число стоит после второго (первое > второго)
Параметры:
a(int): Первое целое число для сравненияb(int): Второе целое число для сравнения
Возвращает: Целое число, указывающее на порядок: отрицательное, если a < b, ноль, если a == b, положительное, если a > b.
Подсказка: Прием с вычитанием из урока позволяет получить элегантное решение в одну строку.
Шпаргалка
Функции сравнения позволяют универсальным алгоритмам, таким как qsort и bsearch, сравнивать элементы, не зная их типов.
Стандартная сигнатура для функций сравнения:
int compare(const void* a, const void* b);Параметры имеют тип const void*, потому что универсальная функция не знает тип сортируемых данных.
Соглашение о возвращаемом значении:
| Возвращаемое значение | Значение |
|---|---|
| Отрицательное | a идет перед b |
| Ноль | a равно b |
| Положительное | a идет после b |
Внутри функции сравнения приведите указатели void* к фактическому типу и сравните значения:
int compare_ints(const void* a, const void* b) {
int val_a = *(const int*)a;
int val_b = *(const int*)b;
return val_a - val_b;
}Прием с вычитанием работает для целых чисел: если a меньше, результат будет отрицательным; если равны — ноль; если больше — положительным.
Попробуйте сами
int compare_ints(int a, int b) {
// Напишите код здесь
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик7Указатели на функции
Объявление указателей на функцииВызов указателей на функцииTypedef для указателей на функцииПередача функций в качестве аргументовИтоги: Диспетчеризация калькулятора10Обобщенные контейнеры
Повторение: указатели voidОбобщенная оберткаОбобщенный обмен (Swap)Обобщенное сравнениеПовторение: обобщенный массив2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга