ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 28.06.2020
Просмотров: 1695
Скачиваний: 3
СОДЕРЖАНИЕ
Тема 15: Пошук і сортування елементів масиву. Класи алгоритмів сортування
Тема 16: Динамічна пам'ять. Адреси і покажчики
Тема 17: Оголошення покажчиків, виділення та звільнення динамічної пам’яті
Тема 18: Процедури та функції для роботи з динамічною пам’яттю
Тема 19: Символьний тип даних. Упаковані масиви
Тема 20: Процедури та функції для обробки рядків
Тема 21: Структурований тип даних - безліч
Тема 22: Структурований тип даних – записи
Тема 23: Опис файлових змінних. Обробка типізованих файлів
Тема 24: Послідовний та прямий доступ до файлів
Тема 25: Обробка не типізованих файлів
Тема 26: Робота з текстовими файлами
Тема 28: Поняття та робота з процедурами та функціями
Тема 29: Використання модуля CRT. Програмування клавіатури
Тема 30: Використання модуля CRT. Текстове виведення на екран. Програмування звукового генератора
Тема 31: Графічні можливості TP 7.0. Використання бібліотеки Graph
Тема 32: Бібліотечні модулі користувача
Тема 33: Основні принципи ООП. Створення об’єктів. Використання об’єктів
Основні алгоритми обробки масивів
Тема 18: Процедури та функції для роботи з динамічною пам’яттю
Нижче приводиться опис як вже розглянутих процедур і функцій, так і деяких інших, які можуть виявитися корисними при зверненні до динамічної пам'яті.
Функція ADDR.
Повертає результат типа POINTER, в якому міститься адреса аргументу.
Звернення: ADDR ( X )
тут Х- будь-який об'єкт програми (ім'я будь-якої змінної, процедури, функції). Повертана адреса сумісна з покажчиком будь-якого типа. Відзначимо, що аналогічний результат повертає операція @ .
Функція CSEG.
Повертає значення, що зберігається в регістрі CS мікропроцесора на початку роботи програми в регістрі CS міститься сегмент початку кода програми).
Звернення: CSEG
Результат повертається в слові типа WORD.
Процедура DISPOSE.
Повертає в купу фрагмент динамічної пам'яті, який раніше був зарезервований за покажчиком, що типізувався.
Звернення: DISPOSE(TP)
тут ТР - покажчик, що типізується. При повторному використанні процедури стосовно вже звільненого фрагмента виникає помилка періоду виконання. При звільненні динамічних об'єктів можна вказувати другим параметром звернення до DISPOSE ім'я деструкції (детальніше за див. гл.10).
Функція DSEG.
Повертає значення, що зберігається в регістрі DS мікропроцесора (на початку роботи програми в регістрі DS міститься сегмент почала даних програми).
Звернення: DSEG
Результат повертається в слові типа WORD.
Процедура FREEMEM.
Повертає в купу фрагмент динамічної пам'яті, який раніше був зарезервований за покажчиком, що не типізувався.
Звернення: FREEMEM ( Р, SIZE )
тут Р - покажчик, що не типізується;
SIZE - довжина в байтах фрагмента, що звільняється.
При повторному використанні процедури стосовно вже звільненого фрагмента виникає помилка періоду виконання.
Процедура GETMEM.
Резервує за покажчиком, що не типізується, фрагмент динамічної пам'яті необхідного розміру.
Звернення: GETMEM ( Р, SIZE )
За одне звернення до процедури можна зарезервувати не більше 65521 байта динамічної пам'яті. Якщо немає вільної пам'яті необхідного розміру, виникає помилка періоду виконання. Якщо пам'ять не фрагментована, послідовні звернення до процедури резервуватимуть послідовні ділянки пам'яті, так що почало наступного розташовуватиметься відразу за кінцем попереднього.
Процедура MARK.
Запам'ятовує поточне значення покажчика купи HEAPPTR.
Звернення: MARK ( PTR )
тут PTR - покажчик будь-якого типа, в якому буде повернено поточне значення HEAPPTR. Використовується спільно з процедурою RELEASE для звільнення частини купи.
Функція MAXAVAIL.
Повертає розмір в байтах найбільшої безперервної ділянки купи.
Звернення: MAXAVAIL
Результат має типа LONGINT. За один виклик процедури NEW або GETMEM не можна зарезервувати пам'яті більше, ніж значення, повертане цією функцією.
Функція MEMAVAIL.
Повертає розмір в байтах найбільшої безперервної ділянки купи.
Звернення: MEMAVAIL
Результат має типа LONGINT.
Процедура NEW.
Резервує фрагмент купи для розміщення змінної.
Звернення: NEW ( ТР )
тут ТР - покажчик, що типізується.
За одне звернення до процедури можна зарезервувати не більше 65521 байта динамічної пам'яті. Якщо немає вільної пам'яті необхідного розміру, виникає помилка періоду виконання. Якщо пам'ять не фрагментована, послідовні звернення до процедури резервуватимуть послідовні ділянки пам'яті, так що почало наступного розташовуватиметься відразу за кінцем попереднього.
Процедура NEW може викликатися як функція. В цьому випадку параметром звернення до неї є тип змінної, що розміщується в купі, а функція NEW повертає значення типа покажчик. Наприклад:
type
Pint =^Integer;
var p: Pint;
begin
p := New(Pint);
......
end.
При розміщенні в динамічній пам'яті об'єкту дозволяється як другий параметр звернення до NEW вказувати ім'я конструктора.
Функція OFS.
Повертає значення типа WORD, що містить зсув адреси вказаного об'єкту.
Виклик: OFS ( X )
тут Х- вираження будь-якого типа або ім'я процедури.
Функція PTR.
Повертає значення типа POINTER по заданому сегменту SEG і зсуву OFS.
Виклик: PTR ( SEG, OFS )
тут SEG - вираження типа WORD, що містить сегмент;
OFS - вираження типа WORD, що містить зсув.
Значення, повертане функцією, сумісно з покажчиком будь-якого типа.
Процедура RELEASE.
Звільняє ділянку купи.
Звернення: RELEASE ( PTR )
тут PTR - покажчик будь-якого типа, в якому заздалегідь було збережено процедурою MARK значення покажчика купи. Звільняється ділянка купи від адреси, що зберігається в PTR, до кінця купи. Одночасно знищується список всіх вільних фрагментів, які, можливо, були створені процедурами DISPOSE або FREEMEM.
Функція SEG.
Повертає значення типа WORD, що містить сегмент адреси вказаного об'єкту.
Виклик: SEG ( X )
тут X - вираження будь-якого типа або ім'я процедури.
Функція SIZEOF.
Повертає довжину в байтах внутрішнього представлення вказаного об'єкту.
Виклик: SIZEOF ( X )
тут X - ім'я змінної, функції або типа. Замість константи SIZEOFREAL можна було б використовувати звернення SIZEOF(REAL).
Питання для контролю.
1. Призначення функції ADDR?
2. Призначення функції CSEG?
3. Призначення функції DISPOSE?
4. Призначення функції DSEG?
5. Призначення процедури FREEMEM?
6. Призначення процедури GETMEM?
7. Призначення процедури NEW?
8. Призначення процедури MARK?
9. Призначення процедур MAXAVAIL, MEMAVAIL?
10. Призначення процедури RELEASE?
11. Призначення функції SEG?
12. Призначення функції SIZEOF?
Тема 19: Символьний тип даних. Упаковані масиви
Дані символьного типу. Символьний тип приймає значення з усієї таблиці ASCII (256 символів).
Символьна константа – це символ, укладений в апострофи, наприклад:
'А', 'у', '?', '+', '', '4'.
Апострофи є ознакою символьної константи.
Щоб представити сам апостроф, його потрібно повторити двічі й укласти в апострофи: ’’’’.
Символьна константа займає один байт пам'яті. Її можна позначити ім'ям і задавати в розділі Соnst, наприклад:
const
simbol_1 = ‘A’
simbol_2 = ‘+’
Символьна змінна приймає значення одного символу, тобто одній змінній можна привласнити значення тільки одного символу. Змінна описується в розділі Var ключовим словом Char (символ), наприклад:
var
simbol : char;
. . . . . .
simbol : 'А';
Кожен символ має код з діапазону 0 – 255 і може бути записаний кодовим представленням з попередньою вказівкою решітки (діеза): #10 – десятковий код, #$A – 16-річний код символу.
Кодом представляють символи, що не мають графічного зображення, наприклад – кінець рядка чи звуковий сигнал комп'ютера та ін.
При виведенні значень символьних даних можна використовувати формат. Наприклад:
writeln (a1, a2:2, a3:2);
Для розділення виведених значень символьних даних можна використовувати пробіл. Наприклад:
writeln (a1, ' ',a2, ' ',a3);
За причини того, що символи мови упорядковані, до символьних даних можна застосовувати операції відношень: <, <=, =, >=, >, <>.
'+' < '-';
'*' > '4'.
Чим далі буква в списку алфавіту, тим вона більше. Тому, 'В' > 'А'; 'OКО'>'ОКА'.
Результатом операції порівняння є логічна константа True чи False. Наприклад, результатом операції 'D' < 'F' є значення True.
До символьних даних застосовні наступні убудовані функції:
Ord (X) – повертає ASCII-код символу X.
Наприклад Ord(‘R’) = 82.
Дізнатися значення можна, виконавши:
begin
writeln (ord(‘R’));
end.
чи в меню Debug виконавши команду Evaluate / Modify... (Ctrl + F4) і в поле Expression ввести Ord(‘R’). У поле Result одержимо 82.
Chr(N) – визначає символ по ASCII-коду N, наприклад, Chr(83) = ‘S’.
Pred(X) – повертає попередній символ ASCII відносно символу Х. Наприклад Рred(‘S’) = ‘R’.
Succ(X) – повертає наступний символ ASCII відносно символу Х. Наприклад Succ(‘R’) = ‘S’.
При використанні функції Pred(X) і Succ(X) повинні бути як попередній, так і наступний символ відносно Х, інакше значення цих функцій буде не визначено.
UpCase(‘X’) – перетворить латинські малі літери в прописні. Інші символи, у тому числі букви кирилиці, не перетворить.
Наприклад:
var
x : char;
begin
x : = UpCase(‘r’)
end. Результат: R
Символьний рядок являє собою послідовність символів, укладених в апострофи. Це фіксований рядок. Наприклад:
‘Summa=’, ‘Гімназія юридичного профілю’, ‘Результат’.
Максимальна довжина рядка 255 символів. Рядок можна позначити ім'ям у розділі констант, наприклад:
const
st1='Обсяг'
. . . . .
begin
. . . . . .
writeln('Обсяг')
. . . . .
end.
або використовувати її явно в розділі операторів, наприклад:
begin
. . . . .
writeln('Обсяг')
. . . . .
end.
При виконанні програми в обох випадках буде виведений рядок 'Обсяг'.
До рядків застосовні операції відношень. Результатом цих операцій є логічні константи True чи False. Порівняння рядків виконується посимвольно зліва направо. Два рядки будуть однаковими, якщо вони мають рівну кількість однакових символів. Наприклад:
'ПРИКЛАД' = 'ПРИКЛАД', але 'ABC' < > 'ACB', тому що при порівнянні других символів 'В' < 'С';
' ПРИКЛАД ' > 'ПРИКЛАД', тому що в першому рядку на один пробіл більше, ніж у другому.
Змінній неможна привласнити значення фіксованого рядка, тому що фіксований рядок – це константа, і запис
var
s : char;
. . . .
s := 'Обсяг'
неприпустимо. Змінній можна привласнити тільки значення одного символу. Але не слід плутати символьний рядок зі строковими типами даних, що розглянемо в наступній лекції.
Приклад. Дано дві строкові константи “ДОН” і “СОН”. Чи рівні вони?
const
s1 = ‘ДОН’;
s2 = ‘СОН’;
var
k1 : integer; {порядковий номер символу “Д”}
k2 : integer; {порядковий номер символу “С”}
l : boolean;
begin
k1 := ord('Д'); k2 := ord('С');
l := s1 < s2; {допустимо, сон менше дон, тобто l=true}
writeln('Порядковий номер символу “Д=”, k1:4);
writeln(‘Порядковий номер символу “С=”, k2:4);
writeln(‘Стіл менше стільця? ‘, 1)
end.
Виконавши програму, переконаємося, що L у результаті порівняння s1<s2 прийме значення True, тобто рядок “ДОН” менше рядка “СОН”, тому що символ “C” більше символу “L”.
Приклад. Визначити порядковий номер введеного символу, а також попередній і наступний символи.
var
s1, s2, s3 : char;
n : integer;
begin
writeln('Введіть будь-який символ');
read(s1);
n := ord(s1);
s2 := pred(s1);
s3 := succ(s1);
writeln('Порядковий номер символу ', S1, '=', n:3);
writeln (‘Попередній символ -’, S2);
writeln (‘Попередній символ -’, S3);
end.
Упаковані масиви.
Один символ у пам'яті ЕОМ займає 2 байти, але для його збереження досить одного байту. Тому використовують поняття упакованого масиву.
Упакований масив символьних змінних можна описувати або в розділі Var:
var ім'я масиву: packed array[t1]of char;
або в розділі Type:
type ім'я типу = packed array[t1] of char;
var ім'я змінної : ім'я типу;
де Packed (упакований) – службове слово, що вказує на те, що масив даних є упакованим; t1 – тип індексу.
Наприклад, рядок символів:
“Ми – студенти електротехнічного коледжу”
будемо вважати масивом, що складається з 39 символів (лапки умовно не враховуємо). Назвемо цей масив ім'ям Stroka, тоді його опис буде наступним:
type str=packed array[1..39] of char;
var stroka : str;
тут Str – тип масиву; Stroka – змінна типу Str.
Один елемент масиву приймає значення одного символу:
Stroka[1] = 'М', Stroka[2] = 'и', Stroka[3] = ' ', ... , Stroka[39] = 'у'.
Символьні константи мають тип упакованих масивів.
Елементи символьних масивів можуть брати участь в операціях присвоювання і порівняння. Так, якщо символьний масив описаний
Type str = packed array[1..39] of char;
Var stroka : str;
то допустим оператор:
Stroka := ’Ми – студенти електротехнічного коледжу';
Введення елементів масиву виконується за допомогою процедури Read, що розташовують усередині циклу, наприклад:
i := 1;
while not eoln do
begin
read(stroka[i]);
i := i+1;
end;
де елементи масиву будуть приймати значення доти, поки не зустрінеться символ кінця рядка “Enter”; чи
for i := 1 to 39 do
read(stroka[i]);
де цикл виконується 39 разів. В обох випадках елементи приймуть наступні значення:
Stroka[1] = ’M’, Stroka[2] = ’и’, Stroka[3] = ’ ’, … Stroka[39] = ’у’.
Виведення масиву символьних елементів виконується за допомогою процедури Write.
Приклад. Дан рядок символів S1: “Я добре знаю Pascal”. Потрібно сформувати новий масив з ім'ям S2, що складається з рядка S1 з додаванням наприкінці знаку питання та знаку оклику.
type stroka = packed array[1..20] of char;
var s1,s2 : stroka; i, k: integer;
begin
writeln(‘Введіть рядок s1:’);
i := 0;
while not eoln do begin
i := i+1;
read(s1[i]);
end;
s2 := s1; s2[i+1] := ’?’; s2[i+2] := ’!’;
writeln(‘новий рядок s2: ’);
for k:=1 to i+2 do
write(s2[k]);
end.
Питання для контролю.
-
Які значення маже приймати символьний тип?
-
Що таке символьна константа і що є її ознакою ?
-
Як використовуються в програмі символьні константи і символьні змінні?
-
Скільки байт пам'яті займає символьний тип?
-
Скільки значень приймає символьна змінна?
-
Кодове представлення символу і коли його потрібно використовувати?
-
Які операції застосовуються до символьних даних?
-
Перелічте убудовані функції, застосовувані при обробці символьних даних?
-
Що таке символьний рядок? Його максимальна довжина.
-
Як у програмі використовується символьний рядок?
-
Які операції застосовні до символьних рядків?
-
Чи можна змінній привласнити символьний рядок?
-
Дано два символьні рядки: у якому випадку вони рівні; у якому не рівні?
-
Виведення елементів упакованого масиву.
-
Поняття упакованого масиву.
-
Опис упакованого масиву.
-
Операції над елементами упакованого масиву.
-
Введення елементів масиву.