GOSY / 1 блок-все-шпора(печать)
.pdf7.Файлы данных в языке Object Pascal: открытие, чтение, запись, закрытие. Текстовые типизированные, нетипизированые файлы. Прямой и последовательный доступ к файлам.
Файлом называется область постоянной памяти, имя которой, размер, специальные атрибуты и местоположение хранятся в операционной системе (О.С). Одна из важных функций О.С. – поддержка файловой системы. В файловой системе определены процедуры создания, хранения, копирования, удаления, чтения и записи файлов. При чтении и записи файла О.С. устанавливает для такого файла специальную программу обработки файлов и выделяет определѐнную часть памяти под промежуточный буфер. Т.о. система открывает файл для дозаписи, обновления, чтения, перезаписи ит.д. Размер буфера превышает стандартную порцию выводимой информации, он ее накапливает, а затем все передает в файл. Буфер экономит время.
Введение файлового типа в язык Паскаль вызвано необходимостью обеспечить возможность работы с периферийными (внешними) устройствами ЭВМ, предназначенными для ввода, вывода и хранения данных.
Файлы на внешних устройствах часто называют физическими файлами. Их имена определяются операционной системой. В программах на языке Паскаль имена файлов задаются с помощью строк. Например, имя файла на диске может иметь вид:
'LAB1.DAT'
'c:\ABC150\pr.txt' 'my_files'
Типы файлов
1. Текстовые файлы связываются с файловыми переменными, принадлежащими к стандартному типу TextFile. Текстовые файлы предназначены для хранения текстовой информации. Именно в такого типа файлах хранятся, например, исходные тексты программ. Компоненты (записи) текстового файла могут иметь переменную длину, что существенно влияет на характер работы с ними. Текстовый файл трактуется в Object Pascal как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последовательно, начиная с первой. При создании текстового файла в конце каждой строки ставится специальный признак eoln (End Of LiNe - конец строки), а в конце всего файла - признак eof (End Of File - конец файла).
2. . типизированный файл представляет собой набор записей или файл базы данных. Является файлом прямого доступа: у каждой записи имеется номер, можно обращаться к этому номеру. Доступ к файлу – более эффективный, разрешается одновременно выполнять операции чтения и записи.
3. .нетипизированные файлы - это последовательность компонент произвольного типа
51
Доступ к файлу в программе происходит с помощью переменных файлового типа. Переменную файлового типа описывают одним из трех способов:
file of тип - типизированный файл (указан тип компоненты); text - текстовый файл;
file - нетипизированный файл.
Примеры описания файловых переменных: var f1: file of char;
f2: file of integer; f3: file;
t: text;
Работа с файлами. Вначале файл создается обращением к функции function FileCreate(FileName: String): Integer;
Файлы становятся доступны программе только после выполнения особой процедуры открытия файла. Эта процедура заключается в связывании ранее объявленной файловой переменной с именем существующего или вновь создаваемого файла, а также в указании направления обмена информацией: чтение из файла или запись в него.
Файловая переменная связывается с именем файла в результате обращения к стандартной процедуре AssignFile :
AssignFile (<ф.п.>, <имя файла>);
Здесь <ф.п.> - файловая переменная (правильный идентификатор, объявленный в программе как переменная файлового типа);
<имя файла > - текстовое выражение, содержащее имя файла и, если это необходимо, маршрут доступа к нему.
Инициировать файл означает указать для этого файла направление передачи данных. В Object Pascal можно открыть файл для чтения, для записи информации, а также для чтения и записи одновременно.
а) текстовые файлы м.б. открыты в следующих режимах - Reset (Ltil)- открытие существующего файла для чтения, Rewrite(Ltil) - создание и открытие нового файла на диске для записи, Append(ltil) - открытие существующего файла для дозаписи;
б) типизированные файлы открываются в режимах Reset(ltil) и Rewrite(Ltil).
в) нетипизированного файла: Reset(f, BufSize), Rewrite(f, BufSize)
Параметр BufSize задает число байтов, считываемых из файла или записываемых в него за одно обращение. Минимальное значение BufSize - 1 байт, максимальное - 64 К байт. Если BufSize не указан, то по умолчанию он принимается равным 128.
Процедуры чтения из файла и записи в файл производятся следующим образом:
а) текстовый файл. Считывание информации из файла: Read, Readln(имя файловой переменной, список вывода); запись информации в файл: Write, Writeln(имя файловой переменной, список вывода).
52
б) типизированный файл. Здесь работают те же процедуры, что и для текстовых файлов, однако действуют они на отдельные поля записей данного файла, а не на строки, поэтому здесь используютсяся Write, Read. Для перехода к нужной записи: Seek ( Ltil, номер записи: типа Longint ). Номера записей начинаются с цифры ноль. Для записи и считывания файлов баз данных используется оператор With.
в) Чтение данных из нетипизированного файла: BlockRead(f, X, Count,
QuantBlock);
Эта процедура осуществляет за одно обращение чтение в переменную X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера. Значение Count не может быть меньше 1. За одно обращение нельзя прочесть больше, чем 64 К байтов. Необязательный параметр QuantBlock возвращает число блоков, прочитанных текущей операцией BlockRead. В случае успешного завершения операции чтения QuantBlock = Count, в случае аварийной ситуации параметр QuantBlock будет содержать число удачно прочитанных блоков. Отсюда следует, что с помощью параметра QuantBlock можно контролировать правильность выполнения операции чтения.
Запись данных в нетипизированный файл: BlockWrite(f, X, Count,
QuantBlock);
Эта процедура осуществляет за одно обращение запись из переменной X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера. Необязательный параметр QuantBlock возвращает число блоков, записанных успешно текущей операцией BlockWrite.
Закрытие файла CloseFile выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования процедуры AssignFile.
Процедуры и функции
AssignFile(var F; FileName: String) - связывает файловую переменную f с именем файла FileName
CloseFile (var F) - закрывает файл, однако связь файловой переменной F с именем файла, установленная ранее процедурой AssignFile, сохраняется.
Rewrite (<ф.п.>) - инициирует запись информации в файл, связанный с файловой переменной <ф.п.>. После успешного выполнения этой процедуры файл готов к записи в него первого элемента. Если указанный файл уже существовал, то все данные из него уничтожаются.
Reset(<ф.п.>) - открывает для чтения файл, с которым связана файловая переменная f. После успешного выполнения процедуры Reset файл готов к чтению из него первого элемента. Процедура завершается с сообщением об ошибке, если указанный файл не найден.
53
Append (<ф.п.>) - инициирует запись в ранее существовавший текстовый файл для его расширения, при этом указатель файла устанавливается в его конец. Процедура Append применима только к текстовым файлам, т. е. их файловая переменная должна иметь тип TextFile. Процедурой Append нельзя инициировать запись в типизированный или нетипизированный файл. Если текстовый файл ранее уже был открыт с помощью Reset или Rewrite, использование процедуры Арpend приведет к закрытию этого файла и открытию его вновь, но уже для добавления записей.
Read, Readln(имя файловой переменной, список вывода) - считывание информации из файла.
Write, Writeln(имя файловой переменной, список вывода) - запись информации в файл.
Procedure Seek(var F; N: Longint) - смещает указатель файла F к требуемому компоненту: n - номер компонента файла (первый компонент файла имеет номер 0)
Function SeekEof(var F: Text): Boolean; - Пропускает все пробелы, знаки табуляции и маркеры конца строки eoln до маркера конца файла eof или до первого значащего символа и возвращает True, если маркер eof обнаружен
Function SeekEoln (var F: TextFile): Boolean; - Пропускает все пробелы и знаки табуляции до маркера конца строки eoln или до первого значащего символа и возвращает True, если маркер обнаружен
Function EOF (var F) : Boolean - Тестирует конец файла и возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан
Function Eoln(var F: TextFile): Boolean - Тестирует маркер конца строки и возвращает True, если конец строки достигнут
Function FilePos (var F): Longint - Возвращает текущую позицию в файле, т. е. номер компонента, который будет обрабатываться следующей операцией ввода-вывода.
Ввод данных. При вводе исходных данных происходит преобразование из внешней формы представления во внутреннюю, определяемую типом переменных. Переменные, образующие список ввода, могут принадлежать либо к целому, либо к действительному, либо к символьному типам. Чтение исходных данных логического типа в языке Паскаль недопустимо.
Значения исходных данных могут отделяться друг от друга пробелами и нажатием клавиш табуляции и Enter.
Не допускается разделение вводимых чисел запятыми!
Процедура Read предназначена для последовательного чтения из текстового файла символьных представлений переменных Vi. При чтении переменных типа char выполняется чтение одного символа и присваивание считанного значения переменной. Если перед выполнением чтения указатель файла достиг
54
конца очередной строки, то результатом чтения будет символ cr (код #1з), а если достигнут конец файла, то символ eof (код #26). Процедуру Read не рекомендуется использовать для ввода переменных типа string, т. к. она не способна ―перепрыгнуть‖ через разделитель строк eoln и читает только первую строку текстового файла. Для ввода последовательности строк нужно использовать процедуру ReadLn.
При вводе численных переменных процедура Read вначале выделяет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк eoln пропускаются; после выделения первого значащего символа, наоборот, любой из перечисленных символов или символ eof служат признаком конца подстроки. Выделенная таким образом подстрока затем рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления числовой константы, возникает исключительная ситуация. Если при пропуске ведущих пробелов встретился символ eof, переменная получает значение 0. В Object Pascal не предусмотрен ввод шестнадцатеричных констант.
Процедура ReadLn идентична процедуре Read за исключением того, что после считывания последней переменной оставшаяся часть строки до маркера eoln пропускается, поэтому следующее обращение к ReadLn начинается с первого символа новой строки. Кроме того, эту процедуру можно вызвать без параметров vi что приведет к пропуску всех символов текущей строки вплоть до eoln.
Вывод данных. Для вывода результатов работы программы на экран используются процедуры:
Write(A1,A2,...AK); WriteLn(A1,A2,...AK);
Первый из этих операторов производит вывод значений переменных А1, А2,...,АК в строку экрана. Второй оператор, в отличие от первого, не только производит вывод данных на экран, но и производит переход к началу следующей экранной строки. Если процедура writeln используется без параметров, то она просто производит пропуск строки и переход к началу следующей строки.
Переменные, составляющие список вывода, могут относиться к целому, действительному, символьному или булевскому типам. В качестве элемента списка вывода кроме имен переменных могут использоваться выражения и строки.
Форма представления значений в поле вывода соответствует типу переменных и выражений: величины целого типа выводятся как целые десятичные числа, действительного типа - как действительные десятичные
55
числа с десятичным порядком, символьного типа и строки - в виде символов, логического типа - в виде логических констант TRUE и FALSE.
Оператор вывода позволяет задать ширину поля вывода для каждого элемента списка вывода. В этом случае элемент списка вывода имеет вид А:К, где А - выражение или строка, К - выражение либо константа целого типа. Если выводимое значение занимает в поле вывода меньше позиций, чем К, то перед этим значением располагаются пробелы. Если выводимое значение не помещается в ширину поля К, то для этого значения будет отведено необходимое количество позиций.
Для величин действительного типа элемент списка вывода может иметь вид А:К:М, где А - переменная или выражение действительного типа, К - ширина поля вывода, М - число цифр дробной части выводимого значения. К и М - выражения или константы целого типа. В этом случае действительные значения выводятся в форме десятичного числа с фиксированной точкой.
Пример записи операторов вывода: var rA, rB: Real;
iP,iQ:Integer; bR, bS: Boolean;
chT, chV, chU, chW: Char; begin
. . .
WriteLn(rA, rB:10:2); WriteLn(iP, iQ:8); WriteLn(bR, bS:8); WriteLn(chT, chV, chU, chW);
end.
Процедура write обеспечивает вывод в текстовый файл группы переменных. Если ширина поля вывода не указана, соответствующий параметр выводится вслед за предыдущим без какого-либо их разделения. Символы и строки передаются выводному файлу без изменений, но снабжаются ведущими пробелами, если задана ширина поля вывода и эта ширина больше требуемой для вывода.
При выводе логических выражений в зависимости от их значения выводятся слова True или False. (Ввод логических констант процедурами Read или ReadLn не предусмотрен.)
Вещественные числа выводятся в экспоненциальном формате, если не указан параметр Decpiaces, в противном случае выбирается формат представления числа с фиксированной точкой. Процедура writeln полностью идентична процедуре Write за исключением того, что выводимая последовательность символов автоматически завершается маркером eoln (свое название процедура получила от Write Line - писать строку). При вызове WriteLn можно опускать параметры Vi-в этом случае в файл передается пустая строка.
56
8. Объектно-ориентированное программирование – общая характеристика и сравнительный анализ. Объект и класс. Базовые принципы ООП – инкапсуляция, полиморфизм и наследование.
Программирование объектов в структурном программировании очень запутанная задача. Это привело к появлению нового стиля программирования
– объектно-ориентированное. Это произошло в конце 80-х годов, когда в Паскале появилось понятие «объекты», а в Си – «класс». Начиная с 5 версии Паскаля, появляются объекты и библиотека. Это была попытка создать для Паскаля визуальную среду программирования – Turbo Vision. В Си доминировал Си + +.
Появление объектно-ориентированной парадигмы программирования неразрывно связано с созданием систем визуального программирования. Это связано с двумя процессами:
1)появлением графического интерфейса в ОС;
2)в этом интерфейсе появились пиктограммы – визуальные объекты, связанными с какими-то действиями.
Эти объекты имели набор свойств, которые можно было настраивать. Появилась необходимость провести аналогию между объектами ОС и объектами в программировании. Начался процесс автоматизации программирования, появились генераторы – программы, которые генерируют стандартные процедуры и функции в интерактивном режиме (управление работой с помощью мышки, окон и элементов ввода). Наиболее удобным интерфейсом для генератора стала среда визуального программирования. Первоначально название типа и его значения в Паскале было одинаковым – object, что создавало путаницу при использовании и описании. Это дало основание для заимствования из языка Си понятия класс (class) для названия типа объектов. Поэтому в Object Pascal уже определена специальная пользовательская структура данных – класс.
Основная цель ООП повышение эффективности разработки программ. В традиционных методах программирования изменение данных или правил и методов их обработки часто приводило к необходимости значительного изменения программы, что приводило к увеличению вероятности ошибок и возрастает время, необходимое для отладки программы. Использование ООП позволяет выйти из такой ситуации с min потерями, сведя необходимую модификацию программы к еѐ расширению и дополнению.
Понятие объекта в языках программирования реализовано, как совокупность свойств (структур данных, характерных для этого объекта), методов их обработки (программ изменения свойств) и событий, на который данный объект может реагировать, и они же приводят к изменению свойств объекта. <Имя потомка> =
object<имя предка> поле;
57
…
поле; метод;
…
метод; end;
Объекты могут иметь идентичную структуру и отличаться только значениями свойств. В таких случаях в программе создаѐтся новый тип, основанный на единой структуре объекта, он называется классом, а каждый конкретный объект, имеющий структуру этого класса – экземпляр класса. Класс имеет заранее заданные свойства. Класс знает, как решать определѐнные задачи, т.е. располагает методами решения. Но обычно класс не используется в программах. Класс является как бы шаблоном, на основе которого создаются экземпляры класса или объекты.
Элементами класса являются поля, методы и свойства. Поля – это данные, которые образуют значение нового типа данных. Методы – процедуры или функции, с помощью которых реализуются действия объекта. Свойства – это структура, которая обеспечивает ввод и вывод данных через специальные процедуры чтения и записи. Т.о. прямой доступ к полям запрещен, а значение полей можно изменять с помощью методов, либо с помощью процедур свойства. Поля разделены на связанные со свойствами и те, которые связаны с методами.
Класс является как бы шаблоном, на основе которого создаются экземпляры класса или объекты.
Программа, написанная с использованием ООП, состоит из объектов, которые могут взаимодействовать между собой. Основные понятиями, связанными с классами:
1)Инкапсуляции – объединение записей с процедурами и функциями, работающими с этими записями. Работа с данными и детали еѐ реализации скрыты от внешнего пользователя объекта. Преимущества инкапсуляции заключается в модульности и изоляции кода объекта от другого кода программы.
Инкапсуляция –это скрытие полей внутри класса и оьъединение в классе информационных полей и процедур их обработки: методов и свойств.
По принципу инкапсуляции для обращения к информационным полям объета нужно либо использовать метод, либо сделать это поле свойством. Произвольный доступ к информационным полям как бы запрещѐн.
Такая защита информационных полей повышает надѐжность работы объекта, а соединение информационных полей и процедур действия упрощает визуализацию программирования.
Т.о. объекты получают возможность реагировать на события и субытийно управляемое программирование упрощается.
58
Динамический характер объектов, классов, полей, свойств, методов позволяет во-первых более оптимально использовать память и убыстрять работу, а так же виртуализировать объекты.
Виртуальные объекты- это объекты, которые имеют несколько вариантов и в различной ситуации действуют разные варианты. Виртуальными делают свойства и методы, есть просто в виртуальные, а есть динамические. Инкапсуляция имеет следующие достоинства:
1)объект класса, у которого есть методы, обладает особыми свойствами, которыми недоступны другим типам данных. Особенно удобны методы для описания действий самого объекта. Например, объект кошка может догонять, убегать, подпрыгивать и т.д. и все это можно сделать в виде методов.
2)скрытие полей и связь их с методами и свойствами повышает надежность работы объекта, так как ограничение мешает неквалифицированному пользователю неправильно использовать объект.
Возможность инкапсуляции появилась вместе с формированием процедурного типа данных, где элементом является процедура или функция определенного вида.
3)преимущества инкапсуляции заключается в модульности и изоляции
кода объекта от другого кода программы.
2)Наследование – задание объекта, затем использование его для построения иерархии порожденных объектов с наследованием доступа каждого из порожденных объектов к коду и данным предка.
Возможность создания новых объектов, которые наследуют свойства и поведение родительских объектов. Это позволяет создавать иерархии объектов, включающие наборы объектов, порождѐнных от одного общего предка и обладающих всѐ большей специализацией и функциональностью по сравнению со своими предками, но использующие все возможности родительских классов. Преимущество наследования заключается в совместном использовании многими объектами общего кода.
Наследованиеклассы построены по принципу наследования, когда новый класс может быть объявлен наследником класса родитель(имя=class(имя родителя)) при этом он автоматически наследует все поля, свойства и методы родителя, что значительно упрощает программирование, в результате принято разрабатывать наследственную иерархию классов.
Построение такой иерархии-это нововведение.
При изучении различных объектов возникает проблема их описания в виде класса. В этой проблеме есть следующие характеристики:
1) часто объект достаточно сложен, что мешает спроектировать его свойства;
59
2) многие объекты подобны друг другу, но отличаются 2-3 свойствами. Неразумно дублировать их свойства при описании других классов.
Для решения данных проблем строят дерево наследования, начиная с определения корневого класса.
Главная идея при построении дерева наследования – это разделение свойств, методов и полей по уровням иерархии. Если дерево наследования уже существует, то изменение любого свойства или метода автоматически переносится на все потомки. После того, как определена структура иерархии наследования, можно приступать к проектированию. Проектирование берется от корня к листьям. Сначала проектируется корневой класс, а затем все ниже лежащие. Дерево наследования обладает свойством накопления, т.е. можно разрабатывать новые уровни иерархии, создавая новых потомков. При этом, в отличие от библиотек процедур и функций, необязательно помнить о тонкостях программирования выше лежащих классов.
Преимущество наследования заключается в совместном использовании многими объектами общего кода.
3)Полиморфизм – задание одного имени действию, которое передается вверх и вниз по иерархии объектов, с реализацией этого действия способом, соответствующим каждому объекту в иерархии. Означает «много форм». Это свойство объектов переопределять методы наследуемого класса. Это значит, что вызов метода объекта для переменной приведѐт к выполнению кода, конкретного экземпляра класса, соответствующего данной переменной. Работает, главным образом, через указатели.
Полиморфизм может быть реализован перекрытием методов, созданием виртуальных и динамических методов. Перекрытие методов образуется при наследовании. Метод потомка с тем же именем перекрывает метод предка. Существуют перегружаемые методы, которые перегружаются по мере необходимости. Они имеют одно имя, но разное содержимое, хранятся в специальных таблицах. В зависимости от типа таблиц существуют виртуальные и динамические объекты. Наличие полиморфизма позволяет упростить, унифицировать и стандартизировать процедуры обработки событий, связанных с этими методами.
8.2 Понятие класса в языке ObjectPascal. Структура класса: поля, методы, свойства. Доступ к структурным элементам класса. Иерархия наследования классов. Конструктор и деструктор класса.
Понятие объекта в языках программирования реализовано, как совокупность свойств (структур данных, характерных для этого объекта), методов их обработки (программ изменения свойств) и событий, на который данный объект может реагировать, и они же приводят к изменению свойств объекта. <Имя потомка> =
object<имя предка> поле;
60
