- •230100 Информатика и вычислительная техника
- •Введение
- •1.Функции
- •1.1. Создание пользовательских функций. Передача аргументов
- •1.2. Глобальные и локальные переменные
- •2.Процедуры
- •2.1. Пользовательские процедуры
- •2.2. Упреждающее объявление процедур и функций (forward)
- •3.Концепция типа данных
- •3.1. Абстракции в обработке информации
- •3.2. Понятие типа данных
- •3.3. Иерархия типов данных
- •3.4. Стандартные типы данных
- •3.5. Тип данных Boolean
- •3.6. Тип данных char
- •3.7. Ограниченные типы
- •4.Множества. Массивы
- •4.1. Операции над множествами
- •4.2. Массивы
- •4.3. Утверждения о массивах
- •5.Индуктивные функции на последовательностях (файлах, массивах)
- •5.1. Схема Горнера
- •5.2. Индуктивные функции
- •6.Записи
- •6.1. Представление сложных типов данных в памяти
- •6.2. Упаковка элементов сложных типов данных
- •6.3. Представление записей в памяти
- •7.Процедуры и функции
- •7.1. Создание пользовательских функций. Передача аргументов
- •7.2. Процедуры
- •7.3. Передача параметров по ссылке и значению
- •8.Основы объектно-ориентированного подхода
- •8.1. Основные положения объектно-ориентированного подхода
- •9.Конструкторы и деструкторы. Инкапсуляция
- •9.1. Хранение объектов в памяти. Доступ к свойствам из методов
- •9.2. Принцип инкапсуляции
- •9.3. Поля и свойства
- •10.Наследование и полиморфизм
- •10.1. Принцип полиморфизма
- •10.2. Виртуальные методы
- •10.3. Пример описания объекта
- •10.4. Параметры-процедуры
- •11.Основы программирования графики
- •11.1. Основные понятия компьютерной графики
- •11.2. Получение сведений о режимах экрана. Эффекты прозрачности
- •11.3. Графические построения
- •11.4. Построение графиков функций
- •11.5. Использование компонента tChart
- •11.6. Построение геометрических фигур
- •11.7. Обновление изображения
- •12.Построение динамических изображений
- •12.1. Анимация на основе операции xor
- •12.2. Буферизация фона
- •12.3. Работа с таймером
- •13.Динамические структуры данных
- •13.1. Размещение динамических переменных в памяти
- •13.2. Захват и освобождение динамической памяти
- •13.3. Нетипизированные указатели
- •14.Линейные списки: основные виды и способы реализации
- •14.1. Линейный список как абстрактный тип данных
- •14.2. Операции с динамическими массивами
- •14.3. Сортировка динамических массивов
- •14.4. Деревья
- •14.5. Потоки в памяти
- •15.Сортировка и поиск
- •15.1. Алгоритмы поиска
- •15.1.1Линейный поиск
- •15.1.2Двоичный поиск
- •15.1.3Поиск текстовых строк
- •15.2. Сортировка данных
- •15.2.1Сортировка массивов
- •16.Сортировка файлов. Рекурсия
- •16.1. Рекурсивные определения и алгоритмы
- •16.2. Программирование рекурсивных алгоритмов
- •16.3. Сортировка файлов
- •17.Файлы
- •17.1. Буферизация
- •17.2. Работа с текстовыми файлами
- •17.3. Работа с двоичными файлами данных
- •17.4. Нетипизированные файлы
- •17.5. Файловые потоки
- •18.Работа с файловой системой
- •18.1. Стандартные файловые диалоги
- •18.2. Получение сведений о дисках
- •18.3. Получение сведений о файлах
- •18.4. Сканирование дисков и директорий
- •19.Обработка исключительных ситуаций
- •19.1. Векторы прерываний
- •19.1.1Хранение данных в стеке
- •19.2. Контроль ввода-вывода
- •19.3. Обработка исключительных ситуаций в Delphi
- •20.Отладка программ
- •20.1. Интегрированная среда программирования
- •20.2. Инструменты отладки программ
- •20.3. Типичные ошибки в программировании
- •21.Принципы построения трансляторов
- •21.1. Синтаксис и семантика языков программирования
- •21.2. Структура языков программирования
- •21.3. Структура и организация работы транслятора
- •22.Параллельные процессы
- •22.1. Создание многопоточных приложений
- •22.2. Управление скоростью работы потоков
- •23.Модульные программы
- •23.1. Создание dll-библиотеки на Delphi
- •23.2. Вызов dll
- •23.2.1Статическое связывание
- •23.2.2Динамическое связывание
- •23.3. Отладка проектов с dll
- •23.4. Хранение форм в dll-библиотеках
- •24.Обмен данными между приложениями
- •24.1. Работа с буфером обмена
- •24.2. Основы ole-технологии
- •25.События и сообщения
- •25.1. Отправка и получение сообщений
- •25.2. Предотвращение повторного запуска программы
- •26.1. Основы com-технологии
- •26.2. Вывод отчета при помощи Microsoft Word
- •26.2.1Проверка наличия сом-сервера на компьютере
- •Общее правило: при работе с любым сом-сервером запретите пользователю им пользоваться, пока с сом-сервером работает ваша программа.
- •26.3. Подключение к сом-серверу Word из Delphi
- •26.4. Управление форматированием документа
- •26.5. Работа с таблицами
- •26.6. Запуск Word из внешней программы
- •26.7. Работа с AutoCad по com-технологии
- •27.Принципы организации реляционных баз данных
- •27.1. Основные сведения о базах данных
- •27.2. Проектирование структуры базы данных
- •27.3. Нормализация структур баз данных
- •28.Работа с локальными бд
- •28.1. Драйвер баз данных bde
- •28.2. Создание баз данных
- •29.Программная обработка локальных бд
- •29.1. Редактирование локальных бд
- •29.2. Вывод бд на экран
- •29.3. Цветовое выделение строк бд
- •30.Работа с распределенными бд
- •30.1. Основы языка sql
- •30.2. Понятие алиаса
- •30.4. Подключение к sql-серверу
- •31.Программная обработка данных в архитектуре "клиент – сервер"
- •31.1. Программный доступ к полям бд
- •31.2. Фильтрация и сортировка данных
- •32.Работа с нормализованными бд
- •32.1. Связывание таблиц
- •32.2. Вычисляемые поля
- •33.Субд Interbase
- •33.1. Работа с сервером Local InterBase
- •33.2. Утилита InterBase Server Manager
- •34.Работа с языком xml
- •34.1. Структура xml-документа
- •34.2. Использование xml в среде Delphi
- •34.3. Концепция dom - объектная модель документа
- •34.4. Использование xml
- •35.Основы программирования для Интернет
- •35.1. Работа с протоколом ftp
- •35.2. Передача файлов по ftp
- •Библиографический список
- •Приложение. Зарезервированные слова sql
- •Предметный указатель
17.1. Буферизация
Очень важный момент при любой работе с файлами – их буферизация. Если программа будет считывать информацию из файла байт за байтом, то после каждого чтения будет заново выполняться установка магнитных головок в новое положение. В итоге работа с файлом замедлится до безобразия. Чтобы такого ужаса не происходило, файл надо читать и записывать как можно более большими кусками (блоками). Лучше всего, когда размер такого блока кратен размеру блока на носителе информации. На жестких дисках и дискетах размер блока, как правило, кратен 256 байтам. Тогда программа за одну операцию чтения или записи может прочитать или считать 25600 байт или 512000 байт и т.д. Но для работы алгоритма нужен только один текущий элемент файла! А куда девать остальное? Если размер элемента – 1 байт, а мы считали 256 байт, то как быть с оставшимися 255-ю? Ответ прост: положить в буфер.
Буфер – специальная область памяти для временного хранения информации, которой программа обменивается с внешними носителями (Рис. 17 .61).
Рис. 17.61. Буферизация ввода-вывода.
Буферизацию надо использовать всегда, при любых файловых операциях. В ряде случаев буферизацию незаметно для программиста выполняет Паскаль, а иногда ее надо делать самостоятельно.
Буфер работает по принципу "первый пришел – первый ушел" (FIFO – First In, First Out). Чаще всего применяется кольцевой буфер – массив, в котором выделены индексы текущего записываемого (in) и считываемого (out) элемента (Рис. 17 .62).
Рис. 17.62. Кольцевой буфер.
Кольцевой буфер легко создать в прикладной программе:
CONST BS=10240; { размер буфера } VAR buf:ARRAY[0..BS-1] OF WORD; n,in,out:WORD;
{n – число элементов в буфере } PROCEDURE Put(x:WORD); BEGIN IF n=BS THEN EXIT; INC(n); buf[in]:=x; in:=(in+1) MOD BS; END; PROCEDURE Get(VAR x:WORD); BEGIN IF n=0 THEN EXIT; DEC(n); x:=buf[out]; out:=(out+1) MOD BS; END;
Процедуры Put и Get предназначены соответственно для записи и считывания данных из файла. На самом деле данные сначала заносятся в буфер, а уж потом попадают в файл или в программу.
Буферизация требует непреложного выполнения простого правила: перед закрытием файла его буфер должен быть принудительно сброшен на диск. Делается это так:
FOR I:=in TO out DO Write(f,buf[I]); Close(f)
Несброшенный буфер приведет к потере "хвоста" файла.
17.2. Работа с текстовыми файлами
Текстовые файлы – самые простые. Они состоят из строк. Каждая строка заканчивается комбинацией символов с кодами 13 и 10. Ниже перечислены процедуры и функции, обеспечивающие работу с текстовыми файлами:
VAR f: TEXTFILE – особый тип данных "файловая переменная". Файловая переменная – представитель файла в программе;
ASSIGNFILE(f,name) – связывает файловую переменную f с файлом с именем name;
SetTextBuf(f,buf) – выделение буфера (массива) buf файлу f;
Reset(f) – открытие файла f для чтения;
ReWrite(f) – создание файла f;
ReadLn(f,a) – считывание строки из файла f в переменную a типа STRING;
WriteLn(f,a) – запись в файл f текстовой строки a;
EOF(f) – проверка конца файла. Если достигнут конец, возвращает TRUE;
CloseFile(f) – закрытие файла f
Рассмотрим простейший пример – вывод текстового файла на экран. Скорее всего, на компьютере есть командный файл C:\Autoexec.bat, автоматически выполняемый при перезагрузке машины. Интересно посмотреть, что там внутри…
VAR f:TEXTFILE; a:STRING; p:^BYTE; BEGIN GetMem(p,10240); { буфер в 10Кб} AssignFile(f,’C:\autoexec.bat’); SetTextBuf(f,p^); Reset(f); WHILE Not(EOF(f)) DO BEGIN ReadLn(f,a);
Memo1.Lines.Add(a)
END;
CloseFile(f);
FreeMem(p,10240);
Обратите внимание на то, что буфер выделяется в динамической памяти. Цикл WHILE NOT(EOF(f)) … - стандартный цикл считывания файла, пока не достигнут его конец (end-of-file). В конце программы выполняются два совершенно необходимых действия: во-первых, файл закрывается, а во-вторых, освобождается захваченная область динамической памяти.
О закрытии файлов надо сказать особо. В сове время было установлено, что очень легко научить обезьяну открывать кран с водой, но вот приучить ее закрывать за собой воду практически невозможно. Ситуация с начинающими программистами аналогична – они забывают закрывать файлы. Незакрытый файл – подлинное бедствие. Дело в том, что число одновременно открытых файлов в операционной системе ограничено, причем число это не очень большое – обычно 40. Из 40 файлов около десятка постоянно открыты самой операционной системой – остается 30. Если программа-вредитель не закрывает за собой файлы, для операционной системы они регистрируются как открытые. В итоге примерно на тридцатом запуске такой программы, а то и того раньше, компьютер зависает.
А что будет, если в текстовый файл вывести число? Например, так:
VAR a:WORD; f:TEXTFILE; … WriteLn(f,a);
Как ни странно, ничего страшного не произойдет. Дело в том, что для удобства пользователя процедуры Read и Write сделаны с отступлением от жесткой типизации. Их аргументами могут быть переменные многих типов, к тому же число аргументов может быть произвольным. Интересно, что такие "вольности" из серьезных языков позволяет только Паскаль, несмотря на его в целом строгую структуру. Поэтому, если в текстовый файл будет выводиться число, Паскаль автоматически преобразует его в текстовый вид. Это не столь простая задача, как кажется. В памяти числа хранятся в компактном двоичном представлении. Например, число 500 занимает два байта и выглядит как значения: 1 (старший байт) и 244 (младший байт). Число 500 получается по формуле . Чтобы перевести число в десятичный вид, понятный человеку, выполняются следующие действия:
I:=0;
REPEAT d[I]:=x MOD 10;
x:= x DIV 10;
INC(i); UNTIL x=0; REPEAT
DEC(I);
Write(f,CHR(d[I]+ORD(‘0’)) UNTIL I=0;
Операции DIV и MOD позволяют легко разделить число на десятичные цифры (в данном случае это 5,0 и 0). Основная хитрость программы заключена в строке CHR(d[I]+ORD(‘0’)). В любых таблицах кодировок коды цифр идут подряд, возрастая от 0 до 9. В данном примере берется код символа "0" {ORD('0')} и к нему прибавляется текущая цифра d[i], а полученное значение используется как код символа для получения самого символа при помощи функции CHR.