- •Программирование на языке высокого уровня
- •Составитель: л.А. Прокушев
- •Подписано к печати Формат 60х84 1/16. Бумага тип. №3
- •Редакционно-издательский отдел
- •190000, Санкт-Петербург, ул. Б. Морская, 67
- •Алгоритмизация вычислительных процессов
- •Средства программирования вычислительных процессов
- •Данные и их типы
- •Константы
- •Переменные
- •Ввод-вывод данных
- •Ввод-вывод данных в стиле с
- •Форматированный ввод
- •Форматированный вывод
- •Консольный ввод-вывод
- •Функция ввода символа (без отображения):
- •Функция очистки экрана результатов:
- •Выражения и операции
- •Логические выражения и операции.
- •Работа с ветвящимися процессами Операторы
- •Оператор присваивания
- •Условный оператор (if)
- •Операторы передачи управления
- •Оператор break (прервать) используется для прерывания работы текущего сложного оператора, в теле которого находится оператор break, и передачи управления на следующий по порядку оператор.
- •Оператор выбора (switch)
- •Действие оператора выбора состоит в следующем:
- •Введите 2 числа х, y : 3 8
- •Работа с циклическими вычислительными процессами
- •Циклы с фиксированным числом повторений Оператор цикла с предусловием (while)
- •Прерывание цикла
- •Циклы с неизвестным числом повторений Вычисление рекуррентных последовательностей
- •Оператор цикла с постусловием (do)
- •Вложенные циклы и организация диалога в программе
- •Оператор цикла с параметром (for)
- •Программа:
- •Работа с массивами
- •Описание массива
- •Доступ к элементам массива
- •Указатель.
- •Занесение данных в массив
- •Многомерные массивы
- •Работа с функциями
- •Определение функции
- •Вызов функции
- •Передача параметров функции
- •Передача данных по значению
- •Передача данных по адресу
- •Прототип (шаблон) функции
- •Блочная структура программы
- •Внешние описания переменных
- •Многомодульные программы Проект программы
- •Внешние ссылки
- •Создание проекта программы
- •Работа с указателями Объявления объектов со сложными описателями
- •Массивы указателей
- •Указатель на указатель
- •Указатель на функцию
- •Использование указателя на функцию как аргумента
- •Массивы указателей на функции
Указатель на функцию
Язык С позволяет применять для вызова функции указатель особого рода – указатель на функцию. Имя функции – это указатель-константа, равный адресу точки входа в функцию (адрес первой машинной команды функции). Кроме того, можно описать указатель-переменную на функцию вида
тип (* имя) (список типов); , где
тип – спецификатор типа возвращаемого функций значения;
имя – идентификатор указателя-переменной на функцию;
список типов – необязательный перечень типов аргументов, передаваемых функции при ее вызове по значению указателя.
Например, рассмотрим определение объекта fun:
int (*fun ) ( int );
1 ) объект с этим именем есть
2 ) указатель
3 ) на функцию
4 ) с одним аргументом типа int
5 ) и возвращаемое значение типа int.
Скобки (*fun) необходимы, так как в описании скобки ( ) связываются с именем раньше, чем символ *. Объявление вида int *fun ( ) означает функцию fun, возвращающую указатель на объект целого типа. Точно так же как указание имени массива без [ ] означает адрес его первого байта, указание имени функции без ( ) задаёт адрес её начала.
Пример 46.
Демонстрация использования указателя-переменной на функцию (funprt), которой можно присваивать ссылки на разные функции.
Программа:
#include <stdio.h>
#include <conio.h> // для функций clrscr и getch
int difference (int, int); // прототипы функций
int sum (int, int);
void main ()
{ /* int (*funptr) (int, int); указатель-переменная на функцию с 2-мя
аргументами */
int (*funptr) (); // указатель-переменная без аргументов
int var1=2, var2=5, ret; // рабочие переменные
clrscr(); // очистка экрана
funptr = difference; // указатель получает адрес 1-й функции
ret = funptr(var1, var2); // результат функции по указателю
puts (“Результаты программы:”);
printf (“ret = %d\n”, ret); // вывод результата
funptr = sum; // указатель получает адрес 2-й функции
ret = funptr(var1, var2); // результат функции по указателю
printf (“ret = %d\n”, ret); // вывод результата
getch(); // задержка экрана результатов
}
int difference (int a, int b) // описание функции вычитания
{ return (a – b); }
int sum (int a, int b) // описание функции сложения
{ return (a+b); }
Результаты программы:
ret = –3
ret = 7
Использование указателя на функцию как аргумента
Многие функции (в том числе библиотечные) в качестве аргумента используют указатель на функцию. Это позволяет разрабатывать универсальные функции.
К примеру, стандартная библиотечная функция быстрой сортировки qsort использует указатель на функцию сравнения двух аргументов, которая может быть стандартной или пользовательской.
Пример 47.
Демонстрация использования функции алгоритма быстрой сортировки с прототипом в <stdlib.h>:
void qsort (void *base, int nelem, int width, int (*fcmp)(const void *elem1, const void *elem2));
Функция qsort сортирует nelem элементов (объектов) размером width каждый, размещенных в памяти, начиная с указателя base, в соответствии с функцией сравнения (библиотечной или пользователя), задаваемой переменной-указателем fcmp на функцию сравнения с двумя аргументами, которая возвращает значение:
< 0, если *elem1 < *elem2,
= 0, если *elem1 == *elem2,
> 0, если *elem1 > *elem2.
Программа:
#include <stdio.h>
#include <stdlib.h> // для функции qsort()
#include <string.h> // для функции strcmp()
#include <conio.h>
int compare (const void *a, const void *b); // прототип функции
void main (void)
{ int i;
char list [5][4] = {“cat”, “car”, “cab”, “cap”,”can” }; /* массив обьектов сортировки */
clrscr ();
qsort (list, 5, sizeof(list[0]), compare); // вызов функции
puts (“Результаты алгоритма быстрой сортировки:”);
for (i=0; i<5; i++) // цикл по элементам (строкам)
printf(“%s\n”, list[i]); // вывод отсортированных строк
getch(); // задержка экрана результатов
}
int compare (const void *a, const void *b) // функция сравнения
{
return (strcmp(a,b)); // возврат результата сравнения
}
Результаты программы:
Результаты алгоритма быстрой сортировки:
cab
can
cap
car
cat