- •В.В. Чуркин технологии программирования
- •Содержание
- •Введение
- •Указатели. Операции над указателями Операции адресации и разыменования.
- •Арифметические операции.
- •Присваивание указателей.
- •Смещение и индексирование указателей.
- •Функции
- •Объявление функции (прототип)
- •Параметры функции
- •Встроенные функции
- •Функции с параметрами со значениями по умолчанию
- •Параметры функции main()
- •Рекурсивные функции
- •Перегрузка функций
- •Шаблоны функций
- •Указатели на функции
- •Объявление и инициализация массива указателей на функции:
- •Указатель на функцию как возвращаемое функцией значение
- •Выделение и освобождение динамической памяти
- •Символьные и строковые данные Символьные константы
- •Строковые константы (строки)
- •Символьные переменные
- •Строки – переменные
- •Специальные функции ввода-вывода строк
- •Стандартная библиотека функций языка с
- •Файлы Потоковый ввод-вывод в языке с Функции верхнего уровня файлового ввода-вывода
- •Открытие и закрытие потока
- •Текстовый режим
- •Бинарный режим
- •Закрытие файла
- •Функции в языке c для работы с файлами
- •Двоичный (бинарный) режим обмена с файлами
- •Строковый обмен с файлами
- •Форматный обмен с файлами
- •Позиционирование в потоке
- •Ввод-вывод нижнего уровня
- •Открытие / закрытие файла
- •Чтение и запись данных
- •Произвольный доступ к файлу
- •Позиционирование файлов
- •Сортировки числовых массивов Принцип наименьших привилегий
- •Обменная сортировка (SwapSort)
- •Сортировка выбором (SelectSort)
- •Пузырьковая сортировка (BubbleSort)
- •Сортировка вставками (InsertSort)
- •Быстрая сортировка (QuickSort)
- •Поиск в числовых массивах
- •Структуры
- •Форматы определения структурных типов
- •Форматы определения объектов структурных типов
- •Операции над объектами структурного типа
- •Доступ к элементам объектов структурного типа
- •Структуры, массивы и указатели
- •Объединения (смеси)
- •Оператор switch (переключатель)
- •Динамические структуры данных
- •Реализация стека с помощью массива
- •Очередь
- •Очередь приоритетов
- •Реализация очереди с помощью массива
- •Линейные списки
- •Функции для работы с двунаправленным линейным списком
- •Реализация списка с помощью массивов
- •Поиск хэшированием
- •Бинарные деревья
- •Бинарное упорядоченное дерево (дерево поиска)
- •Идеально сбалансированное дерево
- •Операции с бинарным упорядоченным деревом
- •Удаление узла из дерева
- •Обход (просмотр) дерева
- •Реализация дерева с помощью массивов
- •Вывод динамических структур в файл и чтение их из файла
- •Сбалансированные (avl) деревья
- •Алгоритм avl-вставки.
- •Повороты
- •Классы и объектно-ориентированное программирование
- •Объявление класса
- •Определение класса (реализация класса)
- •Использование класса (драйвер класса)
- •Доступ к элементам класса
- •Отделение интерфейса от реализации
- •Обслуживающие функции-утилиты
- •Конструкторы
- •Windows-программы в Builder
- •Структура головного файла проекта
- •Структура заголовочного файла модуля формы (“Unit1.H”)
- •Структура файла реализации модуля формы (“Unit1.Cpp”)
- •Области видимости (или области действия) переменных в блоках. Время жизни переменных
- •Доступ к свойствам и функциям-элементам (методам) объектов, переменным и функциям в приложении, содержащем одну форму
- •Константные объекты и константные функции-элементы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Перегрузка операции индексирования []
- •Дружественный класс
- •Использование указателя this
- •Композиция классов
- •Дружественные функции класса
- •Статические элементы класса
- •Шаблон класса для статически и динамически создаваемых объектов
- •Конструктор 1
- •Деструктор
- •Вызовы конструкторов и деструкторов
- •Перегруженная операция присваивания
- •Конструктор 2 (конструктор копирования, конструктор копии)
- •Наследование. Иерархия классов.
- •Ключи доступа
- •Пример простого наследования (точка, круг)
- •Правила наследования функций-элементов. Вызовы конструкторов и деструкторов в иерархии
- •Виртуальные функции и полиморфизм
- •Правила определения и наследования виртуальных функций
- •Позднее (динамическое) связывание
- •Полиморфизм. Абстрактные и конкретные классы
- •Учебная литература (основная)
- •Учебная литература (для углубленного изучения)
- •Учебно-методические издания
Произвольный доступ к файлу
Изменять значение указателя текущей позиции чтения/записи в файле можно с помощью функции:
long lseek(int fd, long offset, int origin);
Новая позиция определяется смещением offset относительно выбранной точки отсчета (origin). Точка отсчета задается одной из предопределенных констант, размещенных в заголовочном файле io.h:
SEEK_SET (имеет значение 0) – начало файла;
SEEK_CUR (имеет значение 1) – текущая позиция;
SEEK_END (имеет значение 2) – конец файла.
При удачном завершении lseek() возвращает новую текущую позицию чтения/записи, представляющую собой смещение от начала файла. Попытка переместиться за пределы файла считается ошибкой. Код ошибки заносится в глобальную переменную errno, определенную в заголовочном файле errno.h.
Для определения текущей позиции в файле можно использовать функцию:
long tell(int fd):
Примеры использования функции lseek().
1. Установка текущей позиции в файле на его начало:
lseek(fd, 0L, SEEK_SET);
2. Установка текущей позиции для последующего добавления данных в файл (позиция в конце файла):
lseek(fd, 0L, SEEK_END);
3. Модификация записей в существующем файле:
/* Прочитать запись в буфер */
read(fd, buff, sizeof(запись));
/* Вернуть указатель в файле на место,
с которого начиналось чтение записи */
lseek(fd, -sizeof(запись), SEEK_CUR);
/* Откорректировать запись в буфере */
………………………………………………
/* Поместить запись на прежнее место */
write(fd, buff, sizeof(запись));
Буфер buff может быть определен как массив символов, достаточный для размещения одной записи.
Файлы в C++
В C++ каждый файл рассматривается как последовательный поток байтов. Каждый файл завершается маркером конца файла (EOF). Когда файл открывается, то создается объект и с этим объектом связывается поток. Автоматически создаются 4 объекта – cin (“привязан” к клавиатуре), cout (“привязан” к экрану), cerr и clog (соответственно небуферизованный и буферизованный вывод ошибок). Для обработки файлов в C++ должны быть включены заголовочные файлы iostream.h и fstream.h. Файл fstream.h включает определения классов потоков ifstream (для ввода из файла), ofstream (для вывода в файл) и fstream (для ввода-вывода файлов). Файлы открываются путем создания этих классов потоков.
Открыть файл можно двумя способами:
1)имя_класса имя_объекта_класса(имя_файла,
режим_открытия_файла);
2)имя_класса имя_объекта_класса;
имя_объекта_класса(имя_файла,
режим_открытия_файла);
Режимы открытия:
ios::app – записать все данные в конец файла;
ios::ate – переместиться в конец исходного открытого файла; данные могут быть записаны в любое место файла;
ios::in – открыть файл для ввода;
ios::out – открыть файл для вывода; содержимое существующего файла отбрасывается без предупреждения;
ios::trunc – отбрасывать содержимое файла, если он существует;
ios::nocreate – если файл не существует, то операция его открытия не выполняется;
ios::noreplace – если файл существует, то операция его открытия не выполняется.
В C++ используют файлы с последовательным и произвольным доступом.
Файлы с последовательным доступом заполняют записями последовательно, возможно, разной длины. Для поиска данных в файле нужно читать файл последовательно до тех пор, пока не будут найдены требуемые данные. Это может привести к необходимости обрабатывать файл последовательно несколько раз за время выполнения программы (каждый раз с начала файла).
Файлы с произвольным доступом заполняются записями равной длины (структура). Доступ здесь – по номеру записи. Данные можно вводить и считывать как последовательно, так и произвольно, можно удалять и обновлять данные.
Файлы с произвольным доступом обеспечивают немедленный доступ к данным и используются в системах по обработке запросов (банковские системы, системы резервирования билетов на авиа- и ж.д. транспорте и т.д.).
Примеры
ofstream outfile(“t.dat”, ios::out);
Файл t.dat открывается для записи. Доступ к файлу в программе – через объект outfile.
int k;
………….
outfile<<k<<endl; //в файл выводится целое число из ячейки k и
//указатель текущей позиции файла переводится на следующую строку
outfile.close(); //файл, открытый для записи, закрывается
ifstream infile(“t.dat”, ios::in);
Файл t.dat открывается для чтения. Доступ к файлу в программе – через объект infile.
infile>>k; //ввод из файла целого числа в переменную k
infile.close(); //файл, открытый для чтения, закрывается.
Для неформатированного ввода-вывода используются функции-элементы read() и write() классов istream и ostream соответственно:
int s;
……………
outfile.write((char*)&s, sizeof(s));
infile.read((char*)&s, sizeof(s));
