- •Содержание
- •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Приложения
2.1.17 Функция удаления списка с усечением файла
Функция устанавливает заголовок списка дыр в значение пусто и устанавливает начальный объем и содержание массива указателей на элементы списка – действия аналогичные инициализации списка, и усекает оставшуюся часть файла.
void DelListAndTruncFile (char *FileName, TFile &f, int &Start_Hole,
int &Start_list, int &SizeAr, int &CntElmList, int SizeArH)
{
/*В файле зарезервированы 16 + (SizeArrH+1)*4 байт*/
/*Условно первые 16-ть байт это четыре записи с номерами №0, №1, №2 и №3, а последующие (SizeArrH+1)*4 байт это пространство для массива указателей на элементы списка*/
/*Запись №0 (4 байта) - заголовок списка дыр*/
/*Запись №1 (4 байта) – указатель на массив указателей на элементы
списка*/
/*Запись №2 (4 байта) – текущий размер массива указателей на
элементы списка*/
/*Запись №3 (4 байта) – реальное количество элементов списка*/
TElmArrPtrFile PtrElmLst; /*указатель на элемент списка*/
/*Открытие файла для записи – все прежнее его содержимое удаляется*/
f = fopen(FileName, "wb");
/*Формируется запись файла №0 */
fseek (f, 0, SEEK_SET);
Start_Hole = -2; /*признак пустого списка дыр*/
fwrite (&Start_Hole, sizeof (Start_Hole),1 , f);
/*Формируется запись файла №1*/
Start_list = 16; /*позиция 1-го байта массива указателей на элементы
списка*/
fwrite (&Start_list, sizeof (Start_list), 1, f);
/*Формируется запись файла №3*/
fwrite (&SizeAr, sizeof (SizeAr),1, f);
/*Формируется запись файла №3*/
CntElmList = 0; /*начальное количество элементов списка*/
fwrite (&CntElmList, sizeof (CntElmList), 1, f);
/*Формируются начальные значения элементов массива указа-
телей на элементы списка объемом в SizeArrH+1*/
PtrElmLst = -1;
for (int J = 0; J <= SizeArH; J++)
{
fwrite (&PtrElmLst, sizeof (PtrElmLst), 1, f);
}
fclose(f);
/*Открытие файла для чтения и записи*/
f = fopen(FileName, "r+b");
} /*DelListAndTruncFile*/
2.1.18 Пример программы обработки отсортированного списка на базе массивов указателей
Ниже приводится тело программы обработки отсортированного списка, использующей приведенные выше типы, переменные и функции работы со списками в бинарных (нетипизированных) файлах на базе массивов указателей.
Для удобства чтения текста примера приведем определенные выше типы и переменные.
const SizeArH = 4; /*верхний индекс массива указателей*/
const Delta = 3; /*приращение - величина, на которую
увеличивается размер массива указателей*/
typedef struct ElmList
{
char Name[30];
int Age;
char Address[30];
} TRecListFile; /*Тип для элемента списка*/
typedef int TElmArrPtrFile; /*Тип для указателя – элемента массива
указателей*/
typedef FILE* TFile; /*Тип для файлового указателя*/
//Объявление переменных:
TFile FList; /*Файловый указатель*/
int StartArrPtrElmList; /*Пзиция первого байта массива
указателей – Старт списка*/
int HeadHole; /*Позиция начала списка дыр*/
int SizeArr; /*Текущий размер массива указателей –
верхний индекс массива указателей*/
int CntElmLst; /*Количество элементов списка*/
Примечание. Данные об элементе списка вводятся в компонент textbox. Свойство Text данного компонента содержит строку ввода и имеет тип System::String*, а строковое поле элемента списка объявлено как массив символов (например, char [30]). Для перевода значения типа System::String* в char* воспользуемся дополнительной функцией char* SystemStringToChar(System::String * string)
char* SystemStringToChar(System::String * string)
{
return (char*) (void*) System:: Runtime:: InteropServices:: Marshal:: StringToHGlobalAnsi(string);
}
Кнопка – создание списка. Массив динамический, создание списка состоит в создании и инициализации файла, который должен в результате содержать 4 записи – заголовок списка дыр, указатель на начало массива указателей, начальный размер массива и начальное количество элементов массива – 0. Кроме того файл должен содержать массив указателей первоначального размера со значениями указателей - -1.
// ------ Создать список -------------//
void Form1::button1_Click(System::Object * sender, System::EventArgs * e)
{
char * fName;
/*Вывод на экран окошка для выбора файла*/
saveFileDialog1->ShowDialog();
if (saveFileDialog1->FileName=="") /*если пользователь не задал имя
для нового файла, то выход*/
{return;}
/*Запись выбранного имени файла в переменную типа char* */
fName=SystemStringToChar(saveFileDialog1->FileName);
/*Попытка инициализации файла*/
if (!initFile(fName, FList))
{
/*Если результат функции init - false - не удалось открыть файл*/
MessageBox(NULL, "Не удалось создать файл", "Результат
создания файла", MB_OK);
return;
}
/*Открытие файла для чтения и записи*/
/*При этом устанавливаются значения всех глобальных пере-
менных из заголовочных записей файла*/
if (OpenFileList(fName, FList, HeadHole, StartArrPtrElmList, SizeArr,
CntElmLst))
{
/*При удачном открытии файла список выводится на экран*/
PrintListInListView(FList, StartArrPtrElmList,CntElmLst, listView1);
}
else
{
/*Функция открытия файла вернула значение false –
произошла ошибка при открытии файла*/
/*Вывод сообщения на экран*/
MessageBox(NULL, "Не удалось открытьть файл", "Результат
открытия файла", MB_OK);
}
};
Если файл со списком уже существует, то при открытии файла инициализация не выполняется.
//----Открыть файл-----//
void Form1::buttonOpen_Click(System::Object * sender, System::EventArgs* e)
{
char * fName;
openFileDialog1->ShowDialog();
if (openFileDialog1->FileName=="")
{return;}
fName = SystemStringToChar(openFileDialog1->FileName);
if (OpenFileList(fName, FList, HeadHole, StartArrPtrElmList, SizeArr,
CntElmLst))
{
PrintListInListView(FList, StartArrPtrElmList, CntElmLst, listView1);
}
else
{
MessageBox(NULL, "Не удалось открытьть файл", "Результат
открытия файла", MB_OK);
}
};
Занесение нового элемента списка осуществляется по нажатию кнопки Добавить на главной форме. Для ввода полей нового элемента создана дополнительная форма FAdd, которая содержит компоненты textBox для ввода и кнопку Добавить для подтверждения окончания ввода информации о новом элементе.
Рисунок 2.6 - Дополнительная форма для ввода информации о новом элементе.
Для кнопки Добавить на дополнительной форме необходимо установить свойству DialogResult значение OK для того чтобы по окончании ввода информации можно было проанализировать – чем закончился диалог с пользователем – нажатием кнопки Добавить или нажатием кнопки Выход.
Рисунок 2.7 - Установка свойства DialogResult для кнопки Добавить
// --- Добавить новый элемент ----///
void Form1::button3_Click(System::Object * sender, System::EventArgs * e)
{
/*Создание формы для ввода информации о новом элементе*/
AddForm *FAdd = new AddForm();
/*Вызов формы для ввода информации о новом элементе*/
if (FAdd->ShowDialog() == DialogResult::OK) /*На форме ввода
пользователь нажал кнопку Добавить*/
{
TRecListFile ElListNew; /*Переменная, в которой будет
храниться информация нового элмента*/
/*Заполняем поля нового элемента из компонентов textBox
формы ввода*/
ElListNew.Age = Convert::ToInt32(FAdd->textBoxAge->Text);
strcpy(ElListNew.Name, SystemStringToChar(FAdd-> textBoxName-> Text));
strcpy(ElListNew.Address, SystemStringToChar(FAdd->textBoxAdres-> Text));
/*Поиск позиции для размещения нового элемента в файле*/
/*При этом может измениться значение заголовка списка дыр*/
int PosAdd = NewElem (FList, HeadHole);
/*Записываем новый элемент в файл в найденую позицию*/
fseek(FList, PosAdd, SEEK_SET );
fwrite (&ElListNew, sizeof(ElListNew), 1, FList);
/*Теперь новый элемент в файле, но еще не в списке*/
/*Добавляем новый элемент в отсортированый список*/
AddElmToSortList (FList, StartArrPtrElmList, SizeArr, CntElmLst,
PosAdd, Delta);
/*Вывод списка на экран*/
PrintListInListView(FList, StartArrPtrElmList, CntElmLst, listView1);
}
}
//--- Удалить элемент ----//
void Form1::buttonDel_Click(System::Object * sender, System::EventArgs * e)
{
/*Берем из textbox ключ удаляемого элемента*/
char * Key = SystemStringToChar(textBox1->Text);
/*Удаление элемента из списка*/
DelElmSortList (FList, StartArrPtrElmList, CntElmLst, Key, HeadHole);
/*Вывод списка на экран*/
PrintListInListView(FList, StartArrPtrElmList, CntElmLst, listView1);
}
///------------- Простой поиск-------------///
void Form1::buttonFind_Click(System::Object * sender, System::EventArgs * e)
{
int IndFndEl; /*индекс в массиве указателя на найденный
элемент*/
bool FindOK; /*Результат поиска - true -найден,false-нет
такого элемента*/
TRecListFile FindEl; /*Найденный элемент*/
TElmArrPtrFile PosPtrFindEl; /*Позиция указателя на найденный
элемент в файле*/
char *Key = SystemStringToChar(textBox1->Text); /*Ключ поиска*/
FindOK = FindElSortList2 (FList, StartArrPtrElmList, CntElmLst, Key,
IndFndEl);
if (FindOK)
{
fseek(FList, StartArrPtrElmList + IndFndEl * (sizeof(TElmArrPtrFile)),
SEEK_SET);
fread(&PosPtrFindEl, sizeof(PosPtrFindEl), 1, FList); /*чтение
указателя на искомый элемент*/
fseek(FList, PosPtrFindEl, SEEK_SET);
fread(&FindEl, sizeof(FindEl), 1, FList); /*чтение искомого
элемента*/
/*Подготовка и вывод результата поиска на экран*/
char* findResult = SystemStringToChar(String::Concat(textBox1->
Text,S", адрес: ", FindEl.Address));
MessageBox(NULL, findResult, "Результат поиска", MB_OK);
}
else
{
MessageBox(NULL,"Элемент не найден","Результат поис-
ка",MB_OK);
}
}
/*-------Удалить список-------*/
void Form1::buttonDelList_Click(System::Object *sender, System::EventArgs* e)
{
char * fName;
fName = SystemStringToChar(openFileDialog1->FileName);
DelList (FList, StartArrPtrElmList, CntElmLst, HeadHole);
PrintListInListView(FList, StartArrPtrElmList, CntElmLst, listView1);
/*Удаление списка с усечением, если это необходимо*/
fclose(FList);
DelListAndTruncFile (fName, FList, HeadHole, StartArrPtrElmList, SizeArr,
CntElmLst, SizeArH);
}
