
- •В.В. Чуркин технологии программирования
- •Содержание
- •Введение
- •Указатели. Операции над указателями Операции адресации и разыменования.
- •Арифметические операции.
- •Присваивание указателей.
- •Смещение и индексирование указателей.
- •Функции
- •Объявление функции (прототип)
- •Параметры функции
- •Встроенные функции
- •Функции с параметрами со значениями по умолчанию
- •Параметры функции main()
- •Рекурсивные функции
- •Перегрузка функций
- •Шаблоны функций
- •Указатели на функции
- •Объявление и инициализация массива указателей на функции:
- •Указатель на функцию как возвращаемое функцией значение
- •Выделение и освобождение динамической памяти
- •Символьные и строковые данные Символьные константы
- •Строковые константы (строки)
- •Символьные переменные
- •Строки – переменные
- •Специальные функции ввода-вывода строк
- •Стандартная библиотека функций языка с
- •Файлы Потоковый ввод-вывод в языке с Функции верхнего уровня файлового ввода-вывода
- •Открытие и закрытие потока
- •Текстовый режим
- •Бинарный режим
- •Закрытие файла
- •Функции в языке c для работы с файлами
- •Двоичный (бинарный) режим обмена с файлами
- •Строковый обмен с файлами
- •Форматный обмен с файлами
- •Позиционирование в потоке
- •Ввод-вывод нижнего уровня
- •Открытие / закрытие файла
- •Чтение и запись данных
- •Произвольный доступ к файлу
- •Позиционирование файлов
- •Сортировки числовых массивов Принцип наименьших привилегий
- •Обменная сортировка (SwapSort)
- •Сортировка выбором (SelectSort)
- •Пузырьковая сортировка (BubbleSort)
- •Сортировка вставками (InsertSort)
- •Быстрая сортировка (QuickSort)
- •Поиск в числовых массивах
- •Структуры
- •Форматы определения структурных типов
- •Форматы определения объектов структурных типов
- •Операции над объектами структурного типа
- •Доступ к элементам объектов структурного типа
- •Структуры, массивы и указатели
- •Объединения (смеси)
- •Оператор switch (переключатель)
- •Динамические структуры данных
- •Реализация стека с помощью массива
- •Очередь
- •Очередь приоритетов
- •Реализация очереди с помощью массива
- •Линейные списки
- •Функции для работы с двунаправленным линейным списком
- •Реализация списка с помощью массивов
- •Поиск хэшированием
- •Бинарные деревья
- •Бинарное упорядоченное дерево (дерево поиска)
- •Идеально сбалансированное дерево
- •Операции с бинарным упорядоченным деревом
- •Удаление узла из дерева
- •Обход (просмотр) дерева
- •Реализация дерева с помощью массивов
- •Вывод динамических структур в файл и чтение их из файла
- •Сбалансированные (avl) деревья
- •Алгоритм avl-вставки.
- •Повороты
- •Классы и объектно-ориентированное программирование
- •Объявление класса
- •Определение класса (реализация класса)
- •Использование класса (драйвер класса)
- •Доступ к элементам класса
- •Отделение интерфейса от реализации
- •Обслуживающие функции-утилиты
- •Конструкторы
- •Windows-программы в Builder
- •Структура головного файла проекта
- •Структура заголовочного файла модуля формы (“Unit1.H”)
- •Структура файла реализации модуля формы (“Unit1.Cpp”)
- •Области видимости (или области действия) переменных в блоках. Время жизни переменных
- •Доступ к свойствам и функциям-элементам (методам) объектов, переменным и функциям в приложении, содержащем одну форму
- •Константные объекты и константные функции-элементы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Перегрузка операции индексирования []
- •Композиция классов
- •Дружественные функции класса
- •Дружественный класс
- •Использование указателя this
- •Статические элементы класса
- •Шаблон класса для статически и динамически создаваемых объектов
- •Конструктор 1
- •Деструктор
- •Вызовы конструкторов и деструкторов
- •Перегруженная операция присваивания
- •Конструктор 2 (конструктор копирования, конструктор копии)
- •Наследование. Иерархия классов.
- •Ключи доступа
- •Пример простого наследования (точка, круг)
- •Правила наследования функций-элементов. Вызовы конструкторов и деструкторов в иерархии
- •Виртуальные функции и полиморфизм
- •Правила определения и наследования виртуальных функций
- •Позднее (динамическое) связывание
- •Полиморфизм. Абстрактные и конкретные классы
- •Учебная литература (основная)
- •Учебная литература (для углубленного изучения)
- •Учебно-методические издания
Перегрузка функций
Перегрузка функций – это использование нескольких функций с одним и тем же именем, но с различными типами параметров. Компилятор определяет по типу параметров, какую функцию вызвать.
int max(int,int); //возвращает наибольшее из двух чисел
char* max(char*, char*); //возвращает подстроку наибольшей
//длины
int max(int, char*); //возвращает наибольшее из первого параметра
//и длины второго
int max(char*,int); //возвращает наибольшее из второго параметра
//и длины первого
void f(int a, int b, char* c, char* d)
{cout<<max(a,b)<<max(c,d)<<max(a,c)<<max(d,b);}
Шаблоны функций
Используются тогда, когда операции, выполняемые функциями, идентичны для разных типов. Шаблон – это незаконченная функция.
template <class T>
T maximum (T a, T b, T c)
{ T max=a;
if(b>max) max=b;
if(c>max) max=c;
return max;
}
В <> находится список формальных типов параметров функции. Здесь же могут быть и просто переменные.
template <class A, class B, int i, char ch>
void f()
{………..}
Формальные типы – это стандартные или пользовательские типы.
При вызове шаблоны преобразуются в функции, которые затем выполняются.
int i1, i2, i3;
cin>>i1>>i2>>i3;
cout<<maximum(i1, i2, i3);
double d1, d2, d3;
cin>>d1>>d2>>d3;
cout<<maximum(d1, d2, d3);
Вызов функции, который использует конкретный тип данных, приводит к созданию компилятором кода для соответствующей версии функции.
Примечание. Все формальные параметры шаблона функции должны использоваться в сигнатуре функции.
Указатели на функции
void f(int a) {……..} //определение функции
void (*pf)(int); //объявление указателя pf на функцию
Чтобы выделить объявление указателя, используют переопределение типа с помощью ключевого слова typedef:
typedef void(*pf)(int); // здесь *pf определяется как новое имя
// (синоним) функции f.
Указателю на функцию можно присвоить адрес функции:
pf=&f; //но можно и так: pf=f; так как имя функции является указателем.
Вызов функции через указатель: pf(10); можно и так: (*pf)(10);
Объявление и инициализация массива указателей на функции:
pf menu[]={&new, &open, &save};
new, open, save – имена ранее объявленных функций.
menu[2](5); - вызов функции save.
Передача в функцию указателя на функцию осуществляется так же, как и передача параметров других типов.
#include <iostream.h>
typedef void (*pf) (int);
void f1(pf ptr) // f1 имеет в качестве параметра указатель ptr типа pf
{ptr(5);} //вызов функции, переданной через указатель
void f(int i) {cout<<i;}
void main()
{f1(f); //5 //имя функции f используется в качестве фактического
//параметра функции f1
}
Примечание. Тип указателя и тип функции, которая вызывается через этот указатель, должны совпадать в точности.
Указатель на функцию как возвращаемое функцией значение
Такой указатель используется для организации меню в случаях, когда количество вариантов определяется не в точке исполнения, а в «промежуточной» функции. Из этой «промежуточной» функции возвращают в виде указателя на функцию адрес той конкретной функции, которая должна быть выполнена.
#include <iostream.h>
#include <conio.h>
int f1() {cout<<”действие 1:”; return 1;}
int f2() {cout<<”действие 2:”; return 2;}
int (*menu())() //функция menu() возвращает указатель на функцию
{ int k;
int(*menuptr[])()={f1, f2}; //массив указателей на функции
cout<<”\nВведите пункт меню (1/2):”;
cin>>k;
if(k<3&&k>0) return menuptr[k-1];
else return 0;
}
void main()
{ int(*r)(); //объявление указателя на функцию
int t;
while(1)
{ r=menu(); //обращение к меню
if(r==0) { cout<<”\nКонец!”;
getch();
return;
}
t=(*r)();
cout<<t;
}
}
Результат:
Введите пункт меню (1/2):1
действие 1:1
Введите пункт меню (1/2):2
действие 2:2
Введите пункт меню (1/2):5
Конец!