Смекни!
smekni.com

Паскаль область дії модулі структури (стр. 2 из 3)

Задачі

1.* Укажіть помилкове використання імен у програмі:

program AB(input, output);

function A : integer;

function B : integer;

function A : integer;

begin A:=1 end

begin A := 2; B := A end;

begin A := 3 end;

begin writeln(A); writeln(B) end.

2. Імітувати виконання програми:

program (input, output);

var a, b : integer;

procedure badswap(var a : integer; t : integer);

var d : integer;

begin

d := t; t := a; a := d

end;

begin

a := 1; b := 3;

badswap(a, b);

writeln(a, b)

end.

3.* Написати програму, за допомогою якої можна встановити, чи завжди обчислюються праві операнди бульових операцій and і or.

4.* Дописати необхідні означення до тіла програми, щоб при її виконанні було надруковано не "0", а "1":

begin

writeln(b*c-c*b)

end.

2. Модуль – збірник означень

Повернемося до задач 3.19–3.22. У програмах для їх розв'язання використовуються ті самі підпрограми обчислення коефіцієнтів рівняння прямої та перевірки, чи лежать точки по один бік прямої. Ці спільні підпрограми, а також інші означення, можна вилучити з програм і зібрати в спеціальному "збірнику означень". Цьому збірнику можна дати ім'я і вказувати його в програмах замість вилучених означень, помітно скорочуючи текст програм. Стандарт мови Паскаль, правда, такої можливості не дає, але всі системи програмування її забезпечують. Збірник означень називається модулем; конкретний його синтаксис залежить від системи програмування. Розглянемо модулі на прикладі діалекту Турбо Паскаль.

Приклад 7.3. Напишемо модуль з означеннями імен normcoef і oneside – імен підпрограм обчислення коефіцієнтів нормалізованого рівняння та перевірки, чи лежать дві точки по один бік прямої (див. відповідь до задачі 3.19).

Модуль має загальний вигляд:

Unitім'я-модуля;

Інтерфейсний розділ;

Розділ реалізації;

Розділ ініціалізації

end.

Інтерфейснийрозділ починається службовим словом Interface і містить означення імен, призначених для використання за межами модуля. Проте замість підпрограм тут записуються тільки їх заголовки. У нашому прикладі цей розділ виглядає так:

Interface

procedure normcoef(x1, y1, x2, y2 : real; var a, b, c : real);

function oneside(x1, y1, x2, y2, a, b, c : real) : boolean;

Слово "інтерфейс" перекочувало з англійської. Одне з його значень – точка з'єднання, взаємодії різноманітних систем. Інше – спосіб сприйняття і виразу даних, заданий програмою. Інтерфейспрограми можна розуміти як "зовнішній вигляд її виконання". Відповідно інтерфейс модуля – це "те, що в ньому видно ззовні". У даному прикладі це заголовки двох підпрограм.

Розділреалізації починається службовим словом Implementation і містить підпрограми, вказані в інтерфейсному розділі, але зі скороченими заголовками – за словом function або procedure записується тільки ім'я. У нашому випадку вигляд цього розділу такий:

Implementation {"втілення", "реалізація"}

procedure normcoef; {скорочений заголовок}

begin ... {повний блок; див. відповідь до задачі 3.21} end;

function oneside; {скорочений заголовок}

begin ... {повний блок; див. відповідь до задачі 3.19} end;

Якби в цих підпрограмах використовувалися підпрограми, не вказані в інтерфейсному розділі, то їх слід було б записати на початку розділу реалізації. У нас таких поки що немає.

Узагалі, імена, означені в розділі реалізації і не вказані в інтерфейсному розділі, називаються іменами, захованими в модулі. Вони призначені для використання всередині модуля, але не за його межами.

Відзначимо, що для модуля діють ті ж самі правила дії іменувань, що і для програм.

Розділініціалізації задає дії, що виконуються один разів на початку виконання програми, яка використовує означення модуля. Він має вигляд:

Begin послідовність операторів

У цих операторах, як правило, задається присвоювання початкових значень змінним, означеним у модулі (їх ініціалізація). У нашому прикладі ніякі початкові дії не задаються, і слово Begin з операторами відсутні.

Запис усього модуля з ім'ям PlaneGeo залишаємо як вправу.

Використання імен модуля в програмі або в іншому модулі називається успадкуванням, або використанняммодуля й у діалекті Турбо Паскаль указується відразу після заголовка програми або слова Interface у модулі в такому вигляді:

usesім'я-модуля;

Якщо програма або модуль використовує кілька інших модулів, то їх імена записуються через кому. Програма розв'язання задачі 3.21 із використанням модуля PlaneGeo стає істотно коротше:

program intriang(input, output);

uses PlaneGeo;

var x, y, {точка}

xt1, yt1, xt2, yt2, xt3, yt3, {вершини}

a1, b1, c1, a2, b2, c2,

a3, b3, c3 : real; {коефіцієнти прямих}

begin

writeln('задайте дві координати точки : ');

readln(x, y);

writeln('задайте 3 пари координат вершин трикутника : ');

readln(xt1, yt1, xt2, yt2, xt3, yt3);

normcoef(xt3, yt3, xt2, yt2, a1, b1, c1);

normcoef(xt3, yt3, xt1, yt1, a2, b2, c2);

normcoef(xt1, yt1, xt2, yt2, a3, b3, c3);

if oneside(x, y, xt1, yt1, a1, b1, c1) and

oneside(x, y, xt2, yt2, a2, b2, c2) and

oneside(x, y, xt3, yt3, a3, b3, c3)

then writeln('Так, точка всередині трикутника ')

else writeln('Ні, точка за межами трикутника ')

end.

Як бачимо, імена normcoef і oneside у програмі не означені, але використовуються завдяки тому, що на початку програми вказано використання модуля uses.

Подібно до Паскаль-програм, "Паскаль-модулі" записуються у файли з розширенням .pas. При трансляції модуля його означення транслюються в машинну мову й записуються у файл із розширенням .tpu. Спочатку треба транслювати модуль, і тільки після цього можна транслювати програми й інші модулі, що використовують його. Так, якщо модуль із прикладу 7.3 записаний у файлі з ім'ям PlaneGeo.pas, то в результаті його трансляції з'являється файл PlaneGeo.tpu. Після цього можна транслювати програму Intriang. У процесі її трансляції означення з модуля, а точніше, із файла PlaneGeo.tpu, додаються в машинну програму завдяки вказівці

uses PlaneGeo.

Отже, використання модулів дозволяє не повторювати ті самі означення в різних програмах і цим істотно їх скорочувати.

Відзначимо, що всі стандартні підпрограми та інші означення в системах програмування збираються в кілька модулів. Серед них, як правило, є один "найголовніший", що використовується практично кожною програмою. Він містить, наприклад, процедури читання й запису та математичні функції (записані машинною мовою). Означення з нього, що використовуються програмою, при її трансляції додаються неявно, тобто без указання uses. Використання всіх інших модулів треба задавати явно.

Задача

5. Оформити модуль PlaneGeo і використати його в розв'язанні задач 3.20–3.22.

3. Структури, вони ж записи

У програмі Intriang і підпрограмах модуля PlaneGeo із прикладу 7.3 точки площини подано двома дійсними числами, а прямі – трьома. Ці пари та трійки дійсних значень по суті подають два нових види об'єктів – точки та прямі. У модулі було також означено специфічні операції над цими об'єктами, наприклад, побудова коефіцієнтів рівняння прямої за парою точок. Ще раніш було означено функцію обчислення відстані між двома точками.

Усе це дозволяє говорити про дві множини об'єктів і операції над ними, тобто про два нові типи. Елементами цих типів є точки площини та прямі на ній, або відповідно пари та трійки дійсних чисел. Для подання пар (трійок тощо) значень, типи яких уже означено (у тому числі базові типи), використовуються вирази вигляду

record

список означень імен полів

end.

Наприклад, тип точок площини, або пар дійсних, можна задати так:

type Point =

record

x : real; y : real

end;

Це означення задає ім'я типу Point для елементів, утворених парами дійсних значень. Змінна типу Point складається з двох компонентів – дійсних змінних, що називаються її полями та іменуються x і y.

Слово record означає "запис", і цей термін не зовсім удалий. Слово structure (структура), напевно, було б краще. Значення типу "запис", тобто пари, трійки тощо значень, а також змінні таких типів називаються записами, або структурами. Типи структур називаються структурними. На відміну від скалярних типів, їх елементи складені з частин, які ідентифікуються окремо.

Імена однотипних полів запису можна означити разом, подібно до імен однотипних змінних. Наприклад, в означенні типу Point можна було б написати x,y:real. Аналогічно, тип трійок дійсних коефіцієнтів рівнянь, якими задаються прямі на площині, можна означити так:

type Line = record

a, b, c: real

end

У загальному випадку вираз вигляду

record

ім'я1 : тип-1;

ім'я2 : тип-2;

...

ім'яN : тип-N

end

задає структурнийтип. Його носій – множина N-ок, у яких на першому місті стоїть значення типу-1, на другому – типу-2 тощо. Ця множина називається декартовимдобуткомносіїв типів, указаних у списку. Такий вираз можна використовувати в означеннях як типів, так і змінних. Наприклад,

var lin : record

a, b, c : real;

end;

Компоненти структур можуть мати довільні типи, у тому числі структурні. Наприклад, можна означити тип "відрізок на площині", що задається парою точок – його кінців:

type Segm = record

pe1, pe2 : Point

end;

Компонент змінної-структури, тобто поле, позначається його ім'ям, яке записується після імені змінної та відокремлюється крапкою. Наприклад, якщо змінна pn має тип Point, то її компоненти позначаються pn.x і pn.y.