- •Структура програми
- •Ідентифікатори.
- •Запис чисел на Pascal.
- •Додаткова інформація про оператор write (writeln)
- •3. Дано 3-й дійсні числа а,ь,с. Визначити, скільки серед них від'ємних.
- •Складений оператор.
- •Результати операцій над логічними даними:
- •Var ім 'я_масиву:аrrау[t1 ] of t2;
- •Var ім’я_масиву: ім'я_типу;
- •Var ім’я_мас:ім 'я_типу;
- •Процедури.
- •Структура процедури.
- •Параметри-значення та параметри-змінні.
- •Функції.
- •Відмінні особливості функції в порівнянні з процедурами:
- •Рекурсивні структури.
- •If умова then a;
- •If умова then a;
- •If умова then a;
- •Множини.
- •Var ім'я_запису: record
- •Var ім'я_запису:ім'я_типу;
- •Оператор приєднання.
- •With ім’я_запису do
- •Записи з варіантами.
- •Var ім'я_файлу: iм)я_типу; читання файлів.
- •Запис файлу.
- •Write(ім’я, параметри);
- •Читання та запис файлів.
- •Файлова система.
- •Фізичні файли.
- •Файлові типи.
- •Текстові файли.
- •Текст - орієнтовані процедури та функції.
- •Створення текстових файлів.
- •Операції введення-виведення текстових файлів.
- •Переваги типізованих файлів :
- •Безтипові файли.
- •Послідовний та прямий доступ до файлів.
- •Вказівники.
- •Зсилочнии тип.
- •Var p:pointer; (змінна — вказівник);
- •Операції розіменування.
- •Списки.
- •1. Зв'язне представлення з одним зв'язком.
- •2. Зв'язані представлення з двома зв'язками.
- •3В’язані списки.
- •Перегляд зв'язаного списку.
- •Списки властивостей.
- •Pascal – об’єктно-орієнтована мова.
- •Опис об’єкта: рядок
- •Розробка програм на мові тр з використанням мов Асемблера та с.
- •Підпрограма сортування методом обміну
- •Застосування механізму переривань
- •Лівий, правый: зв ’язок; дані: тип_даних;
Переваги типізованих файлів :
- Вони максимально ефективним способом характеризують числову інформацію;
- Дозволяють зчитувати і записувати складні і громіздкі структури буквально однією командою.
Наприклад:
Туре
Dim_20*1OO=array[1..20,1..100]of real;
Var xx, yy: dim_20* 100;
F:file of dim_20xlOO;
Begin
Reset(f);
read(f,xx); {відкриває файл і зчитує відразу весь масив}
…………………………………………………….
write (f,yy); {записує відразу весь масив}
……………………………………………...
end.
Масив чисел yy буде записаний в файлі як один елемент. Якщо записано файл масивів, то в нього не можна записати окреме число (як і не можна прочитати одне число).
В той самий час компонентні файли не оптимальні для зберігання рядків і мають складні внутрішні представлення. Розмір буферу для даних файлів встановлюється автоматично, виходячи з розмірів компонентів. Користувачу не надається можливість змінити коректним способом його розмір.
Безтипові файли.
Стандарт ТР вводить особливий файловий тип, який являється по суті
узагальненим файловим типом. Позначення складається тільки зі слова
file без вказування типу компонентів.
Безтиповий тип - це дуже потужний засіб роботи з файлами, так як він
дозволяє маніпулювати з даними не замислюючись про їх типи. З його
допомогою, можна записувати на диск довільні ділянки робочої пам'яті,
та зчитувати їх в пам'ять диску. Можливо перетворювати дані, які
зчитуються із безтипового файлу в любий формат засобом приведення
типів.
Введення-виведення у безтипові файли здійснюється спеціальними
процедурами:
BlockRead та BlockWrite.
Крім того розширюється синтаксис процедур
Reset і Rewrite. В решті принципи роботи залишаються ті ж самі, як і
при роботі з типізованими файлами. Перед використанням файлова
змінна повинна бути зв'язана з конкретним фізичним файлом через виклик оператора Assign. Файл повинен бути відкритим для читання або запису за допомогою виклику процедури Reset(f) і Rewrite(f). Після закінчення роботи файл повинен бути закритим процедурою Close. Відкриваючи безтиповий файл для роботи, користувач неявно встановлює розмір буферу передачі даних, який дорівнює 128 байтів. Однак, можливо явним способом вказати інший розмір буфера (чим він більший, тим швидше проходить введення-виведення), виходячи з ресурсів пам'яті і зручності роботи з даними. Для задання буферу необхідно після оператора Assist відкрити файл розширеним записом процедур:
Reset(Var f:file; BufSize:word);
Rewrite(Var f:file; BufSize:word);
Параметр BufSize задає число байт, зчитаних із файлу за одне звернення до нього, або тих, що записуються в нього. Чим більше значення BufSize, тим швидше проходить обмін даними між носієм файлу (диск) і ОП машини, але тим більша і затрата пам'яті, тому, що саме в пам'яті знаходиться буфер файлу.
Мінімальний блок, який може бути записаний чи прочитаний із файлу -це один байт. Щоб задати його необхідно встановити саме таку величину буфера при відкритті файлу. Максимальний розмір блоку не може перевищувати 64 Кб.
Під час відлагодження програми в ТР можна перевірити розмір буфера, помістивши в вікно перегляду або в вікно аналізу файлову змінну £, що приведена до типу FileRec. (Для цього необхідно підключення модуля DOS)
Для зчитування або запису даних в безтипових файлах застосовувати стандартні процедури Read і Write не рекомендується, їх заміняють процедурами:
BlockRead(Var f:file; VarDestin; count: word[; Readln: word]);
BlockWrite (Var f:file; Vаr Sourse; count: word[; WriteOut: word]);
Ці процедури здійснюють читання в любу змінну Destin і запис із змінної Sourse компонентів файлу, або його рядків чи блоків, що складаються з тієї кількості байтів, яка визначена для буфера файлу f. Якщо count > 1, то за одне звернення буде зчитано count ємностей буферу. Значення count <l не має змісту. Завжди повинна виконуватися умова:
Соипt*Розмір_буферу < 64 Кбайт
Необов'язковий параметр Readin повертає число блоків (буферів), зчитаних поточною операцією BlockRead. Аналогічний параметр WriteOut процедури BlockWrite після кожної операції запису показує число блоків, що записане в даний файл цією операцією.
Якщо операції запису чи читання пройшли успішно, це значить що Readin і WriteOut будуть дорівнювати відповідним значенням параметрів Count, але якщо виник збій при введенні-виведенні і замовлене число блоків не перенеслось, то параметри Readin і WriteOut будуть містити ціле число вдало перенесених блоків (невдача посередині блоку практично рівносильна відміні його читання чи запису). Таким чином, ці параметри можуть використовуватись для контролю виконання операцій BlockRead і BlockWrite.
Приклад:
Var f1,f2:file; {файлові змінні}
Readln, WriteOut: word; {змінні контролю}
Destin, Source: word;
Begin
……………..
BlockRead(fl, Destin, 3, Readln);
If readin 3 then {обробка помилки читання}
…………….
BlockWrite(f2t Source, 4, WriteOut) ;
If WriteOut< > 4 then {обробка помилки запису}
…………….
end.
Якщо при виклику BlockRead останній параметр не вказано, то неможливість зчитати задане число блоків викличе помилку введення-виведення і зупинку програми. Процедури введення-виведення BlockRead і BlockWrite не мають списків введення та виведення, оскільки не визначений тип компонентів файлу. Замість них в викликах присутні безтипові змінні Destin і Source. Адреса початку змінної в пам'яті відповідає адресі пам'яті, починаючи з якої задану кількість байт буде виведено в файл при запису чи вміщено в пам'ять із файлу при читанні. Передаючи змінну процедурі, ми завжди передаємо адресу її змісту, точніше першого байту її значення.
Якщо змінна х масив Var x: array[1..10]of... ,то виклик BlockWrite або BlockRead буде приймати в ній за точку початку відліку блоку перший елемент масиву. Можна більш явно в виклику вказати початок блоку x як х[1]. Але якщо підставляти х[5], то перелік блоку буде вестись уже, починаючи з п'ятого елементу масива.
Особливо обережно треба поводитися зі вказівниками при підстановці їх у BlockWrite і BlockRead. Вказівники повинні бути розіменовані для того, щоб вказувати на дані, а не на місце в пам'яті де зберігається сам вказівник.
Якщо визначений вказівник Р
Type Dim =array[0.. 999] of real;
Var p:^Dim; {вказівник на масив} f:file;
то після створення динамічного масиву Р^, викликом процедури New(p) і його заповнення, він може бути записаний в файл наступним чином:
Assign(f, 'dimfile.dat') ; {зв'язує файли}
Rewrite(f,Sizeof(Dim)); {відкриває файл для читання}
BlockWrite(f,p^ ,1); {записує масив у файл, зсилка р^ розіменована}
Якщо помилково записати р замість р^ то процедура буде працювати, але збережеться у файлі кусок пам'яті, починаючи з Addr(p), який зовсім не дорівнює адресі динамічного масиву Addr(p^). Щоб прочитати згодом записаний масив із файлу, потрібно змінити напрям виведення даних ' (Місце під р повинно бути зарезервовано):
New (р);
Assign(f, 'dimfile.dat');
Reset(f, SizeOf(dim)); {відкриття файлу для читання}
BlockReadln(f, р^ , 1); {читання масиву із файлу}
Close(f);
End.
Перед читанням блоку в динамічну змінну (р^), вона повинна бути коректним чином створена (через виклик New або GetMem, в протилежному випадку наслідки будуть непередбачені). Блочний спосіб роботи з файлами дуже ефективний по часу, і якщо програма використовує великі масиви попередньо обчислювальних констант, то може виявитись більш вигідним винести їх обчислення в іншу програму, котра їх збереже на диску, а в розрахунковій програмі просто встановити, оператори блочного читання вже розрахованих значень. В таких випадках можна навіть виграти на особливостях компілятора ТР. Зазвичай при компіляції програми пам'ять під статичні масиви відводиться в порядку їх слідування в описі. Якщо описані:
Var A,B,C:Array[1..2000] of real;
то їх елементи ставляться в один суцільний ланцюжок.
Addr(B) =Addr(A) +SizeOf(A);
{вказівник на початок об 'єктa в пам 'яті}
Addr(C) =Addr(B)+SizeOf(B);
Це вірно не лише для масивів, але і для любих статичних структур, крім об'єктів: пам'ять в межах блоку опису змінних відводиться послідовно по мірі слідування. Використовуючи цей факт, можна записати або зчитати блоком відразу кілька стуктур даних, прийнявши за початок блоку першу з них:
Assign(f, 'ABC.dat');
Rewrite(f, SizeOf(A)); {відкриває файл та записує в нього 3 блока відразу}
BlockWrite(f,A,3);
Close(f);
End.
Іншою, більш специфічною областю застосування безтипових файлів є робота з системними областями IBM, в тому числі з відеопам'яттю.
