Until (n in nb) and not (n in k);
k:=k+[n];
Write(n:4)
End;
WriteLn
End
End.
Записи
Запис являє собою сукупність обмеженого числа логічно зв'язаних компонентів, що належать до різних типів. Компоненти запису називаються полями, кожне з яких визначається ім'ям. Поле запису містить ім'я поля, слідом за яким через двокрапку вказується тип цього поля. Поля запису можуть відноситися до будь-якого типу, припустимому в мові Паскаль, за винятком файлового типу.
Опис запису в мові ПАСКАЛЬ здійснюється за допомогою службового слова RECORD, слідом за яким описуються компоненти запису. Завершується опис запису службовим словом END.
Наприклад, записна книжка містить прізвища, ініціали і номери телефону, тому окремий рядок у записній книжці зручно представити у виді наступного запису:
type Row=Record
FIO: String[20];
TEL: String[7]
End;
var str: Row;
Опис записів можливий і без використання імені типу, наприклад:
var str: Record
FIO: String[20];
TEL: String[7]
End;
Звертання до запису в цілому допускається тільки в операторах присвоювання, де ліворуч і праворуч від знака присвоювання використовуються імена записів однакового типу. У всіх інших випадках оперують окремими полями записів. Щоб звернутися до окремого компонента запису, необхідно задати ім'я запису і через крапку вказати ім'я потрібного поля, наприклад:
Str.FIO, str.TEL
Таке ім'я називається складеним. Компонентом запису може бути також запис, у такому випадку складене ім'я буде містити не два, а більшу кількість імен.
Звертання до компонентів запису можна спростити, якщо скористатися оператором приєднання with.
Він дозволяє замінити складені імена, що характеризують кожне поле, просто на імена полів, а ім'я запису визначити в операторі приєднання:
With M do OP;
Тут М - ім'я запису, ОР - оператор, простий чи складений. Оператор ОР являє собою область дії оператора приєднання, у межах якої можна не використовувати складені імена.
Іноді вміст окремого запису залежить від значення одного з її полів. У мові ПАСКАЛЬ допускається опис запису, що складає з загальної і варіантної частин. Варіантна частина задається за допомогою конструкції
Case P of,
де Р - ім'я поля з загальної частини запису. Можливі значення, прийняті цим полем, перелічуються так само, як і в операторі варіанта. Однак замість указівки виконуваної дії, як це робиться в операторі варіанта, вказуються поля варіанта, укладені в круглі дужки. Опис варіантної частини завершується службовим словом end. Тип поля Р можна вказати в заголовку варіантної частини, наприклад:
case P: Integer of
Ініціалізація записів здійснюється за допомогою типізованих констант:
Type
RecType= Record
x,y: Word;
ch: Char;
dim: Array[1..3] of Byte
End;
Const
Rec: RecType= ( x: 127; y: 255;
ch: 'A';
dim: (2, 4, 8) );
Файли
Введення файлового типу в мову ПАСКАЛЬ викликано необхідністю забезпечити можливість роботи з периферійними (зовнішніми) пристроями ЕОМ, призначеними для вводу, виводу і збереження даних.
Файловий тип даних чи файл визначає упорядковану сукупність довільного числа однотипних компонентів.
Загальна властивість масиву, множини і запису полягає в тім, що кількість їхніх компонентів визначено на етапі написання програми, тоді як кількість компонент файлу в тексті програми не визначається і може бути довільним.
Поняття файлу досить широке. Це може бути звичайний файл на диску, комунікаційний порт ЕОМ, пристрій для друку, клавіатура чи інші пристрої.
При роботі з файлами виконуються операції вводу - виводу. Операція вводу означає перепис даних із зовнішнього пристрою (із вхідного файлу) в основну пам'ять ЕОМ, операція виводу - це пересилання даних з основної пам'яті на зовнішній пристрій (у вихідний файл).
Файли на зовнішніх пристроях часто називають фізичними файлами. Їхні імена визначаються операційною системою. У програмах мовою Паскаль імена файлів задаються за допомогою рядків. Наприклад, ім'я файлу на диску може мати вид:
'A:\LAB1.DAT'
'c:\ABC150\pr.pas'
'lab3.pas'.
Операційна система MS-DOS не робить особливого розходження між файлами на дисках і стрічках, пристроями ЕОМ і портами комунікацій. У TURBO PASCAL можуть використовуватися імена пристроїв і портів, визначені в MS-DOS, наприклад:
'CON', 'LPT1', 'PRN', 'COM1', 'AUX', 'NUL'.
З файловою системою TURBO PASCAL зв'язане поняття буфера вводу - виводу. Ввод і вивід даних здійснюється через буфер. Буфер - це область у пам'яті, що виділяється для кожного файлу. При записі у файл вся інформація спочатку направляється в буфер і там накопичується доти, поки весь обсяг буфера не буде заповнений. Тільки після цього чи після спеціальної команди скидання відбувається передача даних на зовнішній пристрій. При читанні з файлу дані спочатку зчитуються в буфер, причому даних зчитується не стільки, скільки запитується, а скільки поміститься в буфер.
Механізм буферизації дозволяє більш швидко й ефективно обмінюватися інформацією з зовнішніми пристроями.
Для роботи з файлами в програмі необхідно визначити файлову змінну. TURBO PASCAL підтримує три файлових типи: текстові файли, компонентні файли, безтипові файли.
Опис файлових змінних текстового типу виробляється за допомогою службового слова Text, наприклад:
var tStory: Text;
Опис компонентних файлів має вид:
var fComp: File of T;
де T - тип компонента файлу. Приклади опису файлової перемінний компонентного типу:
type M= array[1..500] of Longint;
var f1: File of Real;
f2: File of Integer;
fLi: File of M;
Безтипові файли описуються за допомогою службового слова File:
var f: File;
Файлові змінні, котрі описані в програмі, називають логічними файлами. Всі основні процедури і функції, що забезпечують ввід - вивід даних, працюють тільки з логічними файлами. Фізичний файл повинний бути зв'язаний з логічним до виконання процедур відкриття файлів.
TURBO PASCAL вводить ряд процедур і функцій, застосовних для будь-яких типів файлів: Assign, Reset, Rewrite, Close, Rename, Erase, Eof, IOResult.
Процедура Assign( var f; FileName: String ) зв'язує логічний файл f з фізичним файлом, повне ім'я якого задане в рядку FileName.
Процедура Reset( var f ) відкриває логічний файл f для наступного читання даних чи, як говорять, відкриває вхідний файл. Після успішного виконання процедури Reset файл готовий до читання з нього першого елемента.
Процедура Rewrite( var f ) відкриває логічний файл fдля наступного запису даних (відкриває вихідний файл). Після успішного виконання цієї процедури файл готовий до запису в нього першого елемента.
Процедура Close( var f ) закриває відкритий до цього логічний файл. Виклик процедури Close необхідний при завершенні роботи з файлом. Якщо з якоїсь причини процедура Close не буде виконана, файл все одно буде створений на зовнішньому пристрої, але вміст останнього буфера в нього не буде перенесено. Для вхідних файлів використання оператора закриття файлу необов'язково.
Логічна функція EOF( var f ): Boolean повертає значення TRUE, коли при читанні буде досягнутий кінець файлу. Це означає, що вже прочитано останній елемент у файлі чи файл після відкриття виявився порожній.
Процедура Rename( var f; NewName: String ) дозволяє перейменувати фізичний файл на диску, зв'язаний з логічним файлом f. Перейменування можливе після закриття файлу.
Процедура Erase( var f ) знищує фізичний файл на диску, що був зв'язаний з файлової змінною f. Файл до моменту виклику процедури Erase повинний бути закритий.
Функція IOResult: Integer повертає ціле число, що відповідає коду останньої помилки вводу - виводу. При нормальному завершенні операції функція поверне значення 0. Значення функції IOResult необхідно привласнювати якійсь змінній, тому що при кожнім виклику функція зануляє своє значення. Функція IOResult працює тільки при виключеному режимі перевірок помилок вводу - виводу чи з ключем компіляції {$I-}.
2.13.1 Текстові файли
Особливе місце в мові ПАСКАЛЬ займають текстові файли, компоненти яких мають символьний тип. Для опису текстових файлів у мові визначений стандартний тип Тext:
var TF1, TF2: Text;
Текстові файли являють собою послідовність рядків, а рядок - послідовність символів. Рядки мають змінну довжину, кожен рядок завершується ознакою кінця рядка.
З ознакою кінця рядка зв'язана функція EOLn(var T:Text):Boolean, де Т - ім'я текстового файлу. Ця функція приймає значення TRUE, якщо був досягнутий кінець рядка, і значення FALSE, якщо кінець рядка не був досягнутим.
Для операцій над текстовими файлами, крім перерахованих, визначені також оператори звертання до процедур:
ReadLn(T) - пропускає рядок до початку наступної;
WriteLn(T) - завершує рядок файлу, у яку виробляється запис, ознакою кінця рядка і переходить до початку наступної.
Для роботи з текстовими файлами введена розширена форма операторів вводу і виводу. Оператор
Read(T,X1,X2,...XK)
еквівалентний групі операторів
Begin
Read(T,X1);
Read(T,X2);
...........
Read(T,XK)
End;
Тут Т - текстовий файл, а змінні Х1, Х2,....,ХК можуть бути або змінними цілого, дійсного чи символьного типу, або рядком. При читанні значень змінних з файлу вони перетворяться з текстового уявлення в машинне.
Оператор
Write(T,X1,X2,...XK)
еквівалентний групі операторів
Begin
Write(T,X1);
Write(T,X2);
...........
Write(T,XK)
End;
Тут Т - також текстовий файл, але змінні Х1,Х2,...,ХК можуть бути цілого, дійсного, символьного, логічного типу чи рядком. При записі значень змінних у файл вони перетворяться з внутрішнього уявлення в текстовий.
До текстових файлів відносяться стандартні файли INPUT, OUTPUT.
Розглянуті раніше оператори вводу - виводу є частковими випадками операторів обміну з текстовими файлами, коли використовуються стандартні файли вводу - виводу INPUT, OUTPUT.
Робота з цими файлами має особливості:
· імена цих файлів у списках вводу - виводу не вказуються;
· застосування процедур Reset, Rewrite і Close до стандартних файлів вводу - виводу заборонено;
· для роботи з файлами INPUT, OUTPUT введений різновид функції EOLn без параметрів.
TURBO PASCAL уводить додаткові процедури і функції, застосовні тільки до текстових файлів, це SetTextBuf, Append, Flush, SeekEOLn, SeekEOF.
Процедура SetTextBuf( var f: Text; var Buf; BufSize: Word ) служить для збільшення чи зменшення буфера вводу - виводу текстового файлу f. Значення розміру буфера для текстових файлів за замовчуванням дорівнює 128 байтам. Збільшення розміру буфера скорочує кількість звертань до диска. Рекомендується змінювати розмір буфера до відкриття файлу. Буфер файлу почнеться з першого байта змінної Buf. Розмір буфера задається в необов'язковому параметрі BufSize, а якщо цей параметр відсутній, розмір буфера визначається довжиною змінної Buf.
Процедура Append( var f: Text ) служить для спеціального відкриття вихідних файлів. Вона застосовна до вже існуючих фізичних файлів і відкриває їх для дозапису в кінець файлу.
Процедура Flush( var f: Text ) застосовується до відкритих вихідних файлів. Вона примусово записує дані з буфера у файл незалежно від ступеня його заповнення.
Функція SeekEOLn( var f: Text ): Boolean повертає значення True, якщо до кінця рядка залишилися тільки пробіли.
Функція SeekEOF( var f: Text ): Boolean повертає значення True, якщо до кінця файлу залишилися рядки, заповнені пробілами.
2.13.2 Компонентні файли
Компонентний чи типізований файл - це файл з оголошеним типом його компонентів. Компонентні файли складаються з машинних представлень значень змінних, вони зберігають дані в тім же виді, що і пам'ять ЕОМ.
Опис величин файлового типу має вид:
type M= File Of T;
де М - ім'я файлового типу, Т- тип компонента. Наприклад:
Type
FIO= String[20];
SPISOK=File of FIO;
Var
STUD, PREP: SPISOK;
Тут STUD, PREP - імена файлів, компонентами яких є рядки. Опис файлів можна задавати в розділі опису змінних:
Var
fsimv: File of Char;
fr: File of Real;
Компонентами файлу можуть бути всі скалярні типи, а зі структурованих - масиви, множини, записи. Практично у всіх конкретних реалізаціях мови ПАСКАЛЬ конструкція "файл файлів" неприпустима.
Всі операції над компонентними файлами виробляються за допомогою стандартних процедур: