- •Программирование
- •На языке высокого уровня
- •Часть 1. Основы языка Си
- •Методические указания
- •К выполнению лабораторных работ
- •Составитель: л.А. Прокушев
- •Подписано к печати Формат 60х84 1/16. Бумага тип. №3
- •Редакционно-издательский отдел
- •190000, Санкт-Петербург, ул. Б. Морская, 67 Общие методические указания
- •Алгоритмизация вычислительных процессов
- •Средства программирования вычислительных процессов Базовые элементы языка Си
- •Данные и их типы
- •Константы
- •Переменные
- •Ввод-вывод данных
- •Форматированный ввод
- •Форматированный вывод
- •Консольный ввод-вывод
- •Функция ввода символа (без отображения)
- •Функция очистки экрана результатов
- •Структура Си-программы
- •Директивы препроцессора
- •Выражения и операции
- •Логические выражения и операции
- •Работа с ветвящимися процессами Операторы
- •Оператор присваивания
- •Условный оператор (if)
- •Операторы передачи управления Пустой оператор
- •Оператор break (прервать) используется для прерывания работы текущего сложного оператора, в теле которого находится оператор break, и передачи управления на следующий по порядку оператор.
- •Оператор выбора (switch)
- •Действие оператора выбора состоит в следующем:
- •Введите 2 числа х, y : 3 8
- •Работа с циклическими вычислительными процессами
- •Циклы с фиксированным числом повторений Оператор цикла с предусловием (while)
- •Прерывание цикла
- •Циклы с неизвестным числом повторений Вычисление рекуррентных последовательностей
- •Оператор цикла с постусловием (do)
- •Вложенные циклы и организация диалога в программе
- •Оператор цикла с параметром (for)
- •Программа:
- •Программа:
- •Программа:
- •Работа с массивами
- •Описание массива
- •Доступ к элементам массива
- •Указатель
- •Занесение данных в массив
- •Многомерные массивы
- •Работа с функциями
- •Определение функции
- •Вызов функции
- •Передача параметров функции
- •Передача данных по значению
- •Передача данных по адресу
- •Пример. Составить функцию обмена значениями между переменными X и y. Верным решением является применение передачи данных по адресу.
- •Прототип (шаблон) функции
- •Блочная структура программы
- •Внешние описания переменных
- •Многомодульные программы Проект программы
- •Внешние ссылки
- •Создание проекта программы
- •Работа с указателями Объявления объектов со сложными описателями
- •Массивы указателей
- •Указатель на указатель
- •Указатель на функцию
- •Использование указателя на функцию как аргумента
- •Массивы указателей на функции
- •Часть 1. Основы языка Си 1
Указатель на функцию
Язык Си позволяет применять для вызова функции указатель особого рода – указатель на функцию. Имя функции – это указатель-константа, равный адресу точки входа в функцию (адрес первой машинной команды функции). Кроме того, можно описать указатель-переменную на функцию вида
тип (* имя) (список типов); , где
тип – спецификатор типа возвращаемого функций значения;
имя – идентификатор указателя-переменной на функцию;
список типов – необязательный перечень типов аргументов, передаваемых функции при ее вызове по значению указателя.
Например, рассмотрим определение объекта fun:
int (*fun ) ( int );
1 ) объект с этим именем есть
2 ) указатель
3 ) на функцию
4 ) с одним аргументом типа int
5 ) и возвращаемое значение типа int.
Скобки (*fun) необходимы, так как в описании скобки ( ) связываются с именем раньше, чем символ ‘*’. Объявление вида int *fun ( ); означает функцию fun, возвращающую указатель на объект целого типа. Точно так же как указание имени массива без [ ] означает адрес его первого байта, указание имени функции без ( ) задаёт адрес её начала.
Пример. Демонстрация использования указателя-переменной на функцию (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 использует указатель на функцию сравнения двух аргументов, которая может быть стандартной или пользовательской.
Пример. Демонстрация использования функции алгоритма быстрой сортировки с прототипом в <stdlib.h>:
void qsort (void base, int nelem, int width, int (*fcmp)(const void *elem1, const void *elem2));
сортирует 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(); /* задержка экрана результатов */
} /* конец функции main() */
int compare (const void *a, const void *b) /* функция сравнения */
{
return (strcmp(a,b)); /* возврат результата сравнения */
}
Результаты программы:
Результаты алгоритма быстрой сортировки:
cab
can
cap
car
cat