Указатели на функции

Язык С
Строк программы, исключая математическое обеспечение Является учебным введением в центральную часть языка “C” Hачинаем. Единственный способ освоить новый язык Оператор FOR Набор полезных программ Подсчет символов Подсчет слов Функции Аргументы - вызов по значению Область действия: внешние переменные Резюме Константы Описания Преобразование типов До 9 и буквы от а до F Операции и выражения присваивания Старшинство и порядок вычисления Операторы и блоки Переключатель Цикл DO - WHILE Оператор CONTINUE Основные сведения Функции, возвращающие нецелые значения Еще об аргументах функций Правила, определяющие область действия Статические переменные Блочная структура Рекурсия Указатели и адреса Указатели и массивы Адресная арифметика Указатели символов и функции Указатели - не целые До 12, а не от 0 до 11. Так как за экономию памяти у нас пока не награждают, такой способ проще, чем подгонка индек-сов Инициализация массивов указателей Указатели на функции Структуры Структуры и функции Указатели на структуры Мы продемонстрируем, как правильно выполнить эту задачу Поля Определение типа Обращение к стандартной библиотеке Форматный вывод - функция PRINTF Форматный ввод - функция SCANF Форматное преобразование в памяти Обработка ошибок - STDERR и EXIT Обращение к системе Низкоуровневый ввод/вывод - операторы READ и WRITE Произвольный доступ - SEEK и LSEEK Пример - распечатка справочников Пример - распределитель памяти Константы Синтаксическая нотация Преобразования Первичные выражения Унарные операции Аддитивные операции Операция присваивания Спецификаторы типа Описание структур и объединений Инициализация TYPEDEF Оператор SWITCH Внешнее определение функции Область действия внешних идентификаторов Неявные описания Явные преобразования указателей Анахронизмы Операторы
439386
знаков
0
таблиц
0
изображений

5.12. Указатели на функции

В языке “с” сами функции не являются переменными, но

имеется возможность определить указатель на функцию, который

можно обрабатывать, передавать другим функциям, помещать в

массивы и т.д. Мы проиллюстрируем это, проведя модификацию

написанной ранее программы сортировки так, чтобы при задании

необязательного аргумента -N она бы сортировала строки ввода

численно, а не лексикографически.

Сортировка часто состоит из трех частей - сравнения, ко-

торое определяет упорядочивание любой пары объектов, перес-

тановки, изменяющей их порядок, и алгоритма сортировки, осу-

ществляющего сравнения и перестановки до тех пор, пока

объекты не расположатся в нужном порядке. Алгоритм сортиров-

ки не зависит от операций сравнения и перестановки, так что,

передавая в него различные функции сравнения и перестановки,

мы можем организовать сортировку по различным критериям.

Именно такой подход используется в нашей новой программе

сортировки.

Как и прежде, лексикографическое сравнение двух строк

осуществляется функцией STRCMP, а перестановка функцией

SWAP; нам нужна еще функция NUMCMP, сравнивающая две строки

на основе численного значения и возвращающая условное указа-

ние того же вида, что и STRCMP. Эти три функции описываются

в MAIN и указатели на них передаются в SORT. В свою очередь

функция SORT обращается к этим функциям через их указатели.

мы урезали обработку ошибок в аргументах с тем, чтобы сосре-

доточиться на главных вопросах.


·     125 -

#DEFINE LINES 100 /* MAX NUMBER OF LINES

TO BE SORTED */

MAIN(ARGC, ARGV) /* SORT INPUT LINES */ INT ARGC;

CHAR *ARGV[];

\(

CHAR LINEPTR[LINES]; / POINTERS TO TEXT LINES */

INT NLINES; /* NUMBER OF INPUT LINES READ */

INT STRCMP(), NUMCMP(); /* COMPARSION FUNCTIONS */

INT SWAP(); /* EXCHANGE FUNCTION */

INT NUMERIC = 0; /* 1 IF NUMERIC SORT */

IF(ARGC>1 && ARGV[1][0] == '-' && ARGV[1][1]=='N')

NUMERIC = 1;

IF(NLINES = READLINES(LINEPTR, LINES)) >= 0) \(

IF (NUMERIC)

SORT(LINEPTR, NLINES, NUMCMP, SWAP);

ELSE

SORT(LINEPTR, NLINES, STRCMP, SWAP);

WRITELINES(LINEPTR, NLINES);

\) ELSE

PRINTF(“INPUT TOO BIG TO SORT\N”);

\)

 

Здесь STRCMP, NIMCMP и SWAP - адреса функций; так как извес-

тно, что это функции, операция & здесь не нужна совершенно

аналогично тому, как она не нужна и перед именем массива.

Передача адресов функций организуется компилятором.

Второй шаг состоит в модификации SORT:

SORT(V, N, COMP, EXCH) /* SORT STRINGS V[0] ... V[N-1] */ CHAR V[]; / INTO INCREASING ORDER */ INT N;

INT (*COMP)(), (*EXCH)();

\(

INT GAP, I, J;

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;

(*EXCH)(&V[J], &V[J+GAP]);

\)

\)

·     126 -

 

Здесь следует обратить определенное внимание на описа-

ния. Описание

INT (*COMP)()

говорит, что COMP является указателем на функцию, которая

возвращает значение типа INT. Первые круглые скобки здесь

необходимы; без них описание

 

INT *COMP()

говорило бы, что COMP является функцией, возвращающей указа-

тель на целые, что, конечно, совершенно другая вещь.

Использование COMP в строке

IF (*COMP)(V[J], V[J+GAP]) <= 0)

полностью согласуется с описанием: COMP - указатель на функ-

цию, *COMP - сама функция, а

 

(*COMP)(V[J], V[J+GAP])

·     обращение к ней. Круглые скобки необходимы для правильного

объединения компонентов.

Мы уже приводили функцию STRCMP, сравнивающую две строки

по первому численному значению:

NUMCMP(S1, S2) /* COMPARE S1 AND S2 NUMERICALLY */ CHAR *S1, *S2;

 \(

DOUBLE ATOF(), V1, V2;

V1 = ATOF(S1);

V2 = ATOF(S2);

IF(V1 < V2)

RETURN(-1);

ELSE IF(V1 > V2)

RETURN(1);

ELSE

RETURN (0);

 \)

 

 

Заключительный шаг состоит в добавлении функции SWAP,

переставляющей два указателя. Это легко сделать, непосредст-

венно используя то, что мы изложили ранее в этой главе.

·    
127 -

SWAP(PX, PY) /* INTERCHANGE *PX AND *PY */

CHAR *PX[], *PY[];

 \(

CHAR *TEMP;

TEMP = *PX;

*PX = *PY;

*PY = TEMP;

 \)

Имеется множество других необязятельных аргументов, ко-

торые могут быть включены в программу сортировки: некоторые

из них составляют интересные упражнения.

Упражнение 5-11.

Модифицируйте SORT таким образом, чтобы она работала с

меткой -R, указывающей на сортировку в обратном (убывающем)

порядке. Конечно, -R должна работать с -N.

Упражнение 5-12.

Добавьте необязательный аргумент -F, объединяющий вместе

прописные и строчные буквы, так чтобы различие регистров не

учитывалось во время сортировки: данные из верхнего и нижне-

го регистров сортируются вместе, так что буква 'а' прописное

и 'а' строчное оказываются соседними , а не разделенными це-

лым алфавитом.

Упражнение 5-13.

Добавьте необязательный аргумент -D (“словарное упорядо-

чивание”), при наличии которого сравниваются только буквы,

числа и пробелы. Позаботьтесь о том, чтобы эта функция рабо-

тала и вместе с -F.

Упражнение 5-14.

Добавьте возможность обработки полей, так чтобы можно

было сортировать поля внутри строк. Каждое поле должно сор-

тироваться в соответствии с независимым набором необязатель-

ных аргументов. (предметный указатель этой книги сортировал-

ся с помощью аргументов -DF для категории указателя и с -N

для номеров страниц).

·     128 -


Информация о работе «Язык С»
Раздел: Информатика, программирование
Количество знаков с пробелами: 439386
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
48443
0
0

... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...

Скачать
43709
0
0

... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...

Скачать
39778
0
1

... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...

Скачать
64931
0
0

... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...

0 комментариев


Наверх