- •Содержание
- •1 Списковые структуры и динамическая память 10
- •2 Списковые структуры и файлы 79
- •3 Мультисписковые структуры 121
- •4 Указатели на функции 134
- •5 Совместное использование указателей на данные и указателей на функции 141
- •6 Оформление курсового проекта 157
- •Введение
- •1Списковые структуры и динамическая память
- •1.1Представления однонаправленных списков массивами указателей на элементы списка
- •1.1.1Представление однонаправленных списков массивами указателей
- •1.1.2Статические массивы указателей
- •1.1.3Операции со списками в статических массивах указателей
- •1.1.4Статические массивы указателей в динамической памяти
- •1.1.5Операции со списками в статических массивах указателей в динамической памяти
- •1.1.6Динамические массивы указателей
- •1.1.7Динамические массивы типизированных указателей
- •1.1.8Операции со списками в динамических массивах типизированных указателей
- •1.1.9Динамические массивы нетипизированных указателей
- •1.1.10Операции со списками в динамических массивах нетипизированных указателей
- •1.1.11Продолжение. Динамические массивы нетипизированных указателей
- •1.1.12Замечания по оператору &
- •1.1.13Нетипизированые указатели и массивы
- •1.1.14Нетипизированые указатели и память
- •1.1.15Продолжение. Динамические массивы нетипизированных указателей
- •2Списковые структуры и файлы
- •2.1Бестиповые файлы и однонаправленные списки на базе массивов указателей на элементы списка
- •2.1.1Представление однонаправленных списков массивами указателей
- •2.1.2Организация файла с однонаправленным списком на базе массивов указателей на элементы списка
- •2.1.3Статические и динамические массивы указателей
- •2.1.4Организация списка дыр
- •2.1.5Функция инициализации файла со списком
- •2.1.6Функция открытия файла со списком
- •2.1.7Функции корректировки указателя на начало списка, заголовка списка дыр, количества элементов списка и текщего размера массива указателей
- •2.1.8Функция выделения записи для нового элемента списка
- •2.1.9Функция освобождения записи удаляемого элемента списка
- •2.1.10 Функция увеличения размера массива указателей на элементы списка
- •2.1.11 Функция вывода содержимого списка
- •2.1.12 Функция поиска элемента списка
- •2.1.13Функция добавления элемента в неотсортированный список
- •2.1.14Функция добавления элемента в отсортированный список
- •2.1.15Функция удаления элемента из отсортированного списка
- •2.1.16Функция удаления списка
- •2.1.17 Функция удаления списка с усечением файла
- •2.1.18 Пример программы обработки отсортированного списка на базе массивов указателей
- •2.1.19Продолжение. Представление однонаправленных списков массивами указателей
- •2.1.20Функция инициализации файла со списком
- •2.1.21Процедура открытия файла со списком
- •2.1.22Процедура корректировки заголовка списка
- •2.1.23 Процедура увеличения размера массива указателей на элементы списка
- •2.1.24Функция поиска элемента списка или позиции вставки нового элемента методом половинного деления
- •2.1.25Функция вывода списка на экран
- •2.1.26Функция добавления нового элемента в отсортированный список
- •2.1.27Функция удаления элемента из отсортированного списка
- •2.1.28Функция удаления списка с усечением файла
- •3Мультисписковые структуры
- •3.1Назначение мультисписков
- •3.2Мультисписки в динамической памяти
- •3.3Мультисписки в бинарных файлах
- •3.4Сохранение и восстановление мультисписка в динамической памяти
- •4Указатели на функции
- •4.1Понятие указателя на функцию и его объявление
- •4.2Переменная-указатель на функцию как параметр другой функции
- •4.3Условия использования указателей на функции
- •4.4Использование указателей на функцию для вызова функций
- •4.4.1Формат переменных-указателей на функцию и бестиповых указателей
- •4.4.2Преобразование переменной-указателя на функцию к бестиповому указателю на функцию
- •4.4.3Вызов функции через бестиповый указатель на функцию
- •4.4.4Преобразование бестипового указателя к переменной типа указатель на функцию
- •4.5Способы вызова функции через указатель на функцию
- •4.5.1Массивы указателей на функции
- •5Совместное использование указателей на данные и указателей на функции
- •5.1Инвариантные функци
- •5.2Функции сравнения
- •5.3Пример 1
- •5.4Пример 2
- •6Оформление курсового проекта
- •6.1Интерфейс программной системы
- •6.2Взаимодействие с мультисписком
- •6.3Отображение содержимого мультисписка
- •6.4Файл справки
- •6.5Документация по курсовому проекту
- •6.5.1Общие положения
- •6.5.2Курсовой проект/работа
- •6.5.3Пояснительная записка
- •6.5.4Техническое задание
- •6.5.5Реферат
- •6.5.6Содержание
- •6.5.7Введение
- •6.5.8 Постановка задачи
- •6.5.9 Анализ решаемой задачи
- •6.5.10Анализ существующих методов организации динамических структур данных
- •6.5.11 Определение путей и методов решения задачи
- •6.5.12Проектирование программы
- •6.5.13Заключение
- •6.5.14Список использованных источников
- •6.6Приложения
5.2Функции сравнения
Как отмечалось выше основная задача функций сравнения, передаваемых в другие функции в качестве параметра-указателя на функцию, состоит в локализации в себе конкретных имен и типов полей, а также возврате одно из трех целочисленных значений, отражающих результат сравнения. Можно предложить два основных подхода к реализации таких функций, отличающиеся степенью инвариантности по отношению к имени, но не типу, поля.
Суть первого подхода состоит в том, что в функциях сравнения явно используются имена конкретных полей элементов списка. Для организации обработки по полям Name и Address получим следующие четыре функции сравнения:
CompTwoElmOnName;
CompTwoElmOnAddress;
CompNameAndKey;
CompAddrAndKey.
В соответствие со способом представления списка функции CompTwoElmOnName и CompTwoElmOnAddress в качестве своих параметров содержат два бестиповых указателя на сравниваемые элементы списка. В теле конкретной функции нетипизированные указатели приводятся к типу указателя на элемент списка TElmList*. Тексты этих функций имеют следующий вид:
int CompTwoElmOnName (void* Elm1, void* Elm2)
{
//сравнение элементов по полю Name
return (strcmp( ((TElmList*)Elm1)->Name ,((TElmList*)Elm2)->Name ) );
} /*CompTwoElmOnName*/
int CompTwoElmOnAddress (void* Elm1, void* Elm2)
{
//сравнение элементов по полю Address
return (strcmp( ((TElmList*)Elm1)->Address , ((TElmList*)Elm2)->Address ) );
} /*CompTwoElmOnAddress*/
Функции CompNameAndKey и CompAddrAndKey в качестве своих параметров содержат бестиповый указатель на сравниваемый элемент списка и ключ. В теле конкретной функции нетипизированный указатель приводится к типу указателя на элемент списка TElmList*. Тексты этих функций имеют следующий вид:
int CompNameAndKey (void* Elm, char* KeyName)
{
return strcmp(((TElmList*)Elm)->Name, KeyName );
} /*CompNameAndKey*/
int CompAddrAndKey (void* Elm, char* KeyAddr)
{
return strcmp(((TElmList*)Elm)->Address, KeyAddr );
} /*CompAddrAndKey*/
Из описания приведенных функций видна их избыточность. Действительно сравнение по полю Name и по полю Address на самом деле является сравнением по полю типа char*. Поэтому естественным является желание сделать эти функции инвариантными к имени поля элемента списка, что позволит вместо четырех функций использовать только две:
CompTwoElmOnField;
CompFieldAndKey;
Суть второго подхода состоит в том, что в функциях сравнения явно не используются имена конкретных полей элементов списка, а сравнение выполняется над данными определенного типа, например, char*.
При таком подходе возможны два основных решения, отличающиеся видом соответствующих парметров функции:
бестиповые указатели на соответствующие поля элементов списка;
переменые определенного типа, например, char*;
При первом решении получим следующие две функции:
CompTwoElmOnField1;
CompFieldAndKey1;
Функция CompTwoElmOnField1 в качестве своих параметров содержат два бестиповых указателя на сравниваемые поля элементов списка. В теле конкретной функции нетипизированные указатели приводятся к типу сравниваемых значений. Текст этой функции имеет следующий вид:
int CompTwoElmOnField1 (void* Elm1, void* Elm2)
{
return strcmp( (char*)Elm1 , (char*)Elm1 ) ;
} /* CompTwoElmOnField1*/
Функция CompFieldAndKey1 в качестве своих параметров содержат бестиповый указатель на соответствующее поле сравниваемого элемента списка и ключ. В теле конкретной функции нетипизированный указатель приводится к типу сравниваемого значения. Текст этой функции имеет следующий вид:
int CompFieldAndKey1 (void* Elm, char* KeyName)
{
return strcmp( (char*)Elm, KeyName) ;
} /* CompFieldAndKey1*/
При втором решении получим следующие две функции:
CompTwoElmOnField2;
CompFieldAndKey2;
Функция CompTwoElmOnField2 в качестве своих параметров содержит две строковые переменные. Текст этой функции имеет следующий вид:
int CompTwoElmOnField2 (char* Elm1, char* Elm2)
{
return strcmp( Elm1 , Elm2);
} /* CompTwoElmOnField2*/
Функция CompFieldAndKey2 в качестве своих параметров содержит строковую переменную и ключ. Текст этой функции имеет следующий вид:
int CompFieldAndKey2 (char* Elm, char* KeyName)
{
return strcmp(Elm, KeyName);
} /* CompFieldAndKey2*/
Выбор способа представления функций сравнения определяется в зависимости от характера решаемой задачи. Первый способ является самым громоздким при написании программы, но, в общем случае, он позволяет в пределах одной функции выполнять сравнение элементов списка по группе полей этих элементов. Второй способ более экономичен, но в его пределах сравнение возможно по одному полю сравниваемых элементов списка.
В последующих примерах для большей наглядности будут использованы следующие четыре функции сравнения:
CompTwoElmOnName;
CompTwoElmOnAddress;
CompNameAndKey;
CompAddrAndKey.
