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

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.