Указатели на функции и их модификаторы


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

Пример

Функция выполняет сортировку строк.

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; просмотров: 1511;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.008 сек.