Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DSD_Spiskovye_struktury_dannykh_na_baze_massivo...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
3 Мб
Скачать
☆

5.4Пример 2

Программа этого примера содержательно не отличается от программы примера 1, но имеет отличия в способе вызова функций.

Отличие состоит в технике вызова функций сравнения, являющихся параметрами других функций. С этой целью вводится динамический массив в динамической памяти из 4‑х нетипизированных указателей на функции. Обращение к этому массиву выполняется с помощью нетипизированного указателя PtrArrPtrFunc, который преобразуется к типу указателя на массив указателей на функции. В качестве параметра функций BubbleSortList и FindElSortList используется представленный соответствующим образом нетипизированный указатель, который приводится к типу указателя на функцию сравнения уже внутри функций BubbleSortList и FindElSortList.

Раздел описаний программы из примера 1 дополняется рядом новых описаний.

Собственно текст программы приобретает следующий вид:

const SizeArrH = 4; /*начальное значение верхней границы массива указателей

на элементы списка*/

const CountFunc = 4; /*количество функций сравнения*/

const Delta = 10; /*приращение размера массива указателей*/

const PosCnt = -1; /*индекс служебного элемента в массиве,

содержащего количество элементов списка*/

const PosSize= -2; /*индекс служебного элемента в массиве,

содержащего текущий размер массива*/

const Up = +1; /*сортировка по возрастанию*/

const Down = -1; /*сортировка по убыванию*/

typedef

struct ElmList

{

char Name[30];

int Age;

char Address[30];

} TElmList;

typedef

int (*TPFuncCompFieldOfTwoElmList) ( void*, void* ); /*тип указателя на

функцию*/

typedef

int (*TPFuncCompFieldElmListAndKey) (void*, char*); /*тип указателя на

функцию*/

// Объявление переменных

void* PtrArrPtrFunc; /*указатель на начало массива указателей на функции*/

void* PtrDnArPtr; /*бестиповый указатель на начало динамического массива указателей на элементы списка*/

int DirSort; /*направление сортировки списка*/

/*--Сравнение соответствующих полей двух элементов записи--*/

int CompTwoElmOnName (void* Elm1, void* Elm2)

{

/*тело функции*/

} /*CompTwoElmOnName*/

int CompTwoElmOnAddress (void* Elm1, void* Elm2)

{

/*тело функции*/

} /*CompTwoElmOnAddress*/

/*--Сравнение поля элемента записи и ключа--*/

int CompNameAndKey (void* Elm, char* KeyName)

{

/*тело функции*/

} /*CompNameAndKey*/

int CompAddrAndKey (void* Elm, char* KeyAddr)

{

/*тело функции*/

} /*CompAddrAndKey*/

//------- расширение массива указателей ----- //

void ExpendArrPtr (void* &PtrArPtr)

/*увеличение размера массива указателей*/

/*PtrArPtr содержит адрес указателя на первый элемент списка*/

{

/*тело функции см. пример 1*/

} /*ExpendArrPtr*/

//--------- Вывод списка в ListView ------------//

void PrintListInListView(void* PtrArrPtr,System::Windows::Forms::ListView * listView)

{

/*тело функции см. пример 1*/

} /* PrintListInListView */

/// -------- Добавление элемента в конец списка ---///

void AddElEndList(void* PtrArrPtr, void* NewP)

{

/*тело функции см. пример 1*/

} /*AddElEndList*/

void BubbleSortList (void* PtrArrPtr, void* PFuncComp, int Direct)

/*Сортировка "пузырьком"*/

{

/*тело функции см. пример 1*/

Вызов функции выполняется следующим образом

if (((TPFuncCompFieldOfTwoElmList)PFunComp) ( …,… )==Direct)

. . .

} /*BubbleSortList*/

///------------ Быстрый поиск -------------------///

void FindElList(void* PtrArrPtr, char *Key, void* PFuncCmp, int Direct, int &PosFndEl, bool &FindOK)

{

/*тело функции см. пример 1*/

Вызов функции выполняется следующим образом

if (((TPFuncCompFieldElmListAndKey)PFuncCmp ) (…, …) ==0)

. . .

if (((TPFuncCompFieldElmListAndKey)PFuncCmp ) (…,…)==Direct)

. . .

} /*FindElList*/

///--------- Удаление элемента из списка -----------///

void DelElList (void* PtrArrPtr, int PosDelEl)

{

/*тело функции см. пример 1*/

} /*DelElList*/

//// ------Кнопка Создать список -------------///

void Form1::btn_Create_Click(System::Object * sender, System::EventArgs * e)

{

// Создание массива указателей

PtrDynArrPtr=CreateArrPtr(PosCnt , PosSize, SizeArrH);

/*выделение места для массива указателей на процедуры. Нулевой элемент массива используется для хранения размера массива*/

PtrArrPtrFunc = new void* [CountFunc+1];

((int**)PtrArrPtrFunc) [0]= CountFunc;

//формирование массива указателей на функции

((void**)PtrArrPtrFunc) [1]= CompTwoElmOnName;

((void**)PtrArrPtrFunc) [2]= CompTwoElmOnAddress;

((void**)PtrArrPtrFunc) [3]= CompNameAndKey;

((void**)PtrArrPtrFunc) [4]= CompAddrAndKey;

} /* btn_Create_Click */

//-----Кнопка - Добавление нового элемента ----//

void Form1::btnAdd_Click(System::Object * sender, System::EventArgs * e)

{

void* NPtrElm =new TElmList; //выделение места для нового элемента списка

//заполнение полей нового элемента списка

((TElmList*)NPtrElm) ->Age=Convert::ToInt32(textBoxAge->Text);

strcpy(((TElmList*)NPtrElm) ->Name,SystemStringToChar(textBoxName->Text));

strcpy(((TElmList*)NPtrElm) ->Address,SystemStringToChar(textBoxAdres->Text));

if ( ((int*)PtrDynArrPtr)[PosSize]==((int*)PtrDynArrPtr)[PosCnt] )

{

//количество элементов списка совпадает с размером массива

ExpendArrPtr (PtrDynArrPtr); // расширение массива указателей

}

AddElEndList(PtrDynArrPtr, NPtrElm);

PrintListInListView(PtrDynArrPtr, listView);

} /* btnAdd_Click */

// --- РАБОТА С ПОЛЕМ Name --- //

// --- Кнопка – сортировка списка по полю Name --- //

void Form1::buttonSortName_Click(System::Object * sender, System::EventArgs * e)

{

DirSort = Up; /*Down*/ /*Установка направления сортировки*/

//сортировка по полю Name

BubbleSortList (PtrDynArrPtr, ((void**) PtrArrPtrFunc) [1], DirSort);

//вывод списка после сортировки в ListView

PrintListInListView(PtrDynArrPtr, listView1);

} /*buttonSortName_Click*/

// --- Кнопка - удаление элемента для списка, отсортированного по полю Name //

void Form1::btnDelName_Click(System::Object * sender, System::EventArgs * e)

{

// в textBox1 вводится имя для удаления

char * Key=SystemStringToChar(textBox1->Text);

int PosDel;

bool FindOK;

FindElList (PtrDynArrPtr, Key, ((void**) PtrArrPtrFunc) [3] , DirSort, PosDel, FindOK);

if (FindOK == false) { return; }

DelElList (PtrDynArrPtr, PosDel);

PrintListInListView(PtrDynArrPtr, listView1);

} /* btnDel_Click */

// --- РАБОТА С ПОЛЕМ Address --- //

// --- Кнопка – сортировка списка по полю Address --- //

void Form1::buttonSortAddress_Click(System::Object * sender, System::EventArgs * e)

{

DirSort = Up; /*Down*/ /*Установка направления сортировки*/

//сортировка по полю Address

BubbleSortList (PtrDynArrPtr, ((void**) PtrArrPtrFunc) [2], DirSort);

//вывод списка после сортировки в ListView

PrintListInListView(PtrDynArrPtr, listView1);

} /* buttonSortAddress_Click */

// --- Кнопка - удаление элемента для списка, отсортированного по полю Address //

void Form1::btnDelAddress_Click(System::Object * sender, System::EventArgs * e)

{

// в textBox1 вводится адрес для удаления

char * Key=SystemStringToChar(textBox1->Text);

int PosDel;

bool FindOK;

FindElList (PtrDynArrPtr, Key, ((void**) PtrArrPtrFunc) [4] , DirSort, PosDel, FindOK);

if (FindOK == false) { return; }

DelElList (PtrDynArrPtr, PosDel);

PrintListInListView(PtrDynArrPtr, listView1);

} /* btnDelAddress_Click */