Указатели на функции и их модификаторы
Использование имени функции в выражении без списка аргументов означает вычисление ее адреса. Функция не может передаваться в качестве параметра, но ее адрес может передаваться. Приводимый ниже пример показывает как используются функции сравнения строк в функции сортировки, что может давать совершенно разные конечные результаты сортировки.
Пример
Функция выполняет сортировку строк.
void sort(char *v[], long n, int (* comp)(const char *, const char *))
{
int gap, i, j;
char *temp;
for(gap = n/2; gap > 0; gap /=2)
for(i = gap; i < n; i++)
for(j = i-gap; j >= 0; j -= gap)
{
if((*comp)(v[j], v[j + gap]) <= 0)
break;
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}
В качестве функции сравнения строк на вход sort() можно передавать, например, библиотечную функцию strcmp() или функцию пользователя инвертирующую результаты работы strcmp(), или функцию, представленную ниже:
#include <string.h>
int comp1 (const char *s1, const char *s2)
{
if(strlen(s1) >= strlen(s2))
return -1;
else
return 0;
}
Как и обычные указатели на данные, указaтeлu на функцию могут иметь тип nеаг, faг или hugе. Указатель типа near занимает в памяти два байта, указатели far и hugе - четыре байта. Тип указателя на функцию, устанавливаемый по умолчанию, зависит от модели памяти. В моделях памяти TINY, SМALL и СОМРАСТ по умолчанию указатель на функцию имеет тип near и задает только смещение до точки входа в функцию относительно значения в cегмeнтнoм регистре CS. При прямом или косвенном вызове функции через near-указатель иcпользуется машинная команда "близкогo" прямогo или косвенного вызова процедуры, которая связана с установкой новогo значения только в регистре IP.
Для моделей памяти MEDIUM, LARGE и HUGE по умолчанию указатель на функцию занимаer 4 байта и включаeт как смещение, так и сегмент адреса точки входа в функцию. При прямом или косвенном вызовe функции через far-указатель на функцию используется машинная команда "далекогo" прямогo или косвенногo вызова процедуры, которая связана как с установкой нового значения в регистре IP, так и с изменением значения сегментногo регистра CS. В модели памяти HUGE при входе в функцию дополнительно устанавливается значение регистра DS, соответствующее ceгмeнтy данных функции. Прямая адресация при вызовe процедуры соответcтвyeт вызовy функции через указате.ль-константу. Косвeнный вызов используется при вызовe функции по указателю-переменной.
Принятый по умолчанию формат указателя на функцию можeт быть отменен явным заданием типа функции с использованием ключевых слов near, far или huge.
Пример
iпt far function (int, int); /* npoтoтип функции */
………………………………….
int fаr function( int, int) /* определение функции */
{ Тело функции}
Синтаксис языка С требуeт совпадения модификаторов типа функции как в прототипе, так и в определении функции. Компилятор всегда тpaктyeт первую часть определения как тип возвращаемогo функцией значения, а следующее слово - как модификатор. Пoэтoму, например,
char fаг * far str_func(void);
является прототипом far-функции, возвращающей значение указателя типа char far *. Сама функция является fаr-функцией. Приводимое ниже описание определяет указательfunc_ptr на far-функцию (можно сказать и fаr-указатель на функцию), принимающую два аргумента типа int и возвращающую значение типа char far *:
char far * far(* func_ptr)(int, int);
Дата добавления: 2016-05-26; просмотров: 1519;