Паскаль. Прикладне програмне забезпечення


Процедури, підпрограми та параметри

Розглянемо задачу: довільні значення трьох змінних A, B, C переставити за необхідності так, щоб вони були упорядковані за неспаданням, тобто щоб мали місце нерівності A b c. Алгоритм розв'язання цієї задачі простий:

Якщо ab, то обміняти значення змінних a і b;

{гарантовано, що a b}

Якщо bc, то обміняти значення змінних b і c;

{гарантовано, що b c і a c; але нерівність a b не гарантована, тому:}

Якщо ab, то обміняти значення змінних a і b.

Обмін значень двох змінних, наприклад, a і b, задається трьома операторами з допоміжною змінною: t:=a; a:=b; b:=t. Мовою Паскаль алгоритм записується так:

Program sort3input, output;

Var a, b, c, t: integer;

Begin

Writeln'задайте три цілих'; readlna, b, c;

If ab Then Begin t:=a; a:=b; b:=t End;

If bc Then Begin t:=b; b:=c; c:=t End;

If ab Then Begin t:=a; a:=b; b:=t End;

Writeln'упорядкування: ', a, ' ', b, ' ', c

End.

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

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

На відміну від функцій, при обміні відбувається не обчислення якогось одного значення, а змінюється стан пам'яті програми недарма обмін заданий складеним оператором. Тому такий опис оформляється й використовується інакше. Опис обміну задається Процедурою, а її Виклик являє собою окремий оператор.

Процедура має загальний вигляд

Procedure Ім'я Означення Параметрів;

Означення імен

Begin

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

End;

Процедура, як і функція, є означенням імені і записується серед означень програми.

На відміну від функції, в її заголовку немає імені типу для значень, породжуваних у результаті виклику, тому що ніякі значення не породжуються. За цією ж причиною В тілі процедури не може бути операторів присвоювання з її ім'ям у лівій частині. Виклик процедури складається з імені й аргументів у дужках і записується як окремий оператор, наприклад, readlnx, y.

Отже, напишемо інший варіант програми упорядкування трьох значень:

Program sort31input, output;

Var a, b, c: integer;

Procedure Swapxx, yy: integer;

Var T: integer;

Begin T:=xx; xx:=yy; yy:=t End;

Begin

Writeln'задайте три цілих:'; readlna, b, c;

If ab Then swapa, b;

If bc Then swapb, c;

If ab Then swapa, b;

Writeln'упорядкування: ', a, ' ', b, ' ', c

End.

КРАСИВО, АЛЕ НЕПРАВИЛЬНО!

Справа в тім, що при виконанні виклику, наприклад, swapa, b, змінні xx і yy одержать значення змінних a і b, потім ці значення поміняються місцями, виконання виклику закінчиться, а в змінних a і b залишаться ті ж самі значення, що були перед викликом. Наприклад, якщо змінним a, b, c присвоїти з зовнішнього світу значення відповідно 3, 1, 2, то буде надруковано Упорядкування: 3 1 2. Слушність цього напису дуже сумнівна.

Отже, при виконанні виклику процедури чи функції спочатку параметри одержують значення аргументів, а потім їх зміни ніяк не відбиваються на аргументах рис.3.3. Тому параметри, що дотепер розглядалися, називаються Параметрамизначеннями.

Мова Паскаль допускає в заголовках процедур і функцій означати параметри іншого виду. Вони називаються Параметрами Змінними і означаються зі словом Var попереду. Так, процедура swap набуває вигляду:

Procedure Swap Var xx, yy: integer;

Var T: integer;

Begin

T:=xx;

Xx:=yy;

Yy:=t

End;

Таке означення параметрів забезпечує, що при виконанні виклику процедури або функції Іменам параметрів ставляться у відповідність змінні, тобто ділянки пам'яті, уже зіставлені аргументам. При виконанні виклику зміна значення параметразмінної насправді є зміною значення аргументу рис.3.4.

Момент виконання програми

A

B

C

Перед першим викликом

3

2

1

Після першого виклику

2

3

1

Після другого виклику

2

1

3

Після третього виклику

1

2

3

Якщо в програмі sort31 означити параметри процедури як параметризмінні, то за виконання виклику swapa, b імені xx зіставляється та ж сама ділянка пам'яті, що й змінній a, а імені yy – та ж, що b. У результаті обмін місцями значень xx і yy є обміном a і b. Що й було потрібно. Таким чином, якщо в змінні a, b, c програми було прочитано значення 3, 2, 1 відповідно, то результати виконання викликів процедури swap можна подати станами пам'яті програми, як на рис.3.5.

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

Секція параметрівзначень – це список імен, за яким після двокрапки записано ім'я типу, наприклад, a1, a2: real. Секція параметрівзмінних починається словом Var, за яким записано список імен параметрів та ім'я типу, наприклад,

Var xx, yy: integer.

Секції розділяються;. За необхідності ми могли б написати, наприклад,

Procedure Qqx, y: integer; Var z, t: integer.

Як ми вже говорили, у викликах підпрограм вказуються аргументи – вирази, однотипні з параметрами. Але є суттєва відмінність між аргументами, що можуть відповідати параметрамзначенням і параметрамзмінним.

Аргументом для параметразначення може бути будьякий вираз, тип якого сумісний за присвоюванням із типом параметра.

Аргументом для параметразмінної може бути тільки ім'я змінної того ж типу, що й параметр.

У літературі часто параметри підпрограм називаються Формальними Параметрами, а аргументи у викликах – Фактичними.

Задачі

3.18. Як Ви гадаєте, процедури readln і writeln мають параметризначення або параметризмінні?

3.19. Як відомо, будьякі дві різні точки площини задають єдину пряму, що проходить через них. Рівняння прямої Ax+ By+ C=0 називається Нормалізованим, якщо b=1 або b=0 і a=1. Пряма може бути задана не єдиним рівнянням, але її нормалізоване рівняння єдине.

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

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

З використанням цих підпрограм написати програму читання координат точки і вершин трикутника і перевірки, чи лежить точка всередині його.

3.20. Прочитати координати двох пар точок, якими задано два відрізки, та визначити, чи мають вони хоча б одну спільну точку.

3.21. Прочитати координати точок A, B, C, D. Обчислити довжину найкоротшого шляху з точки A в точку B з урахуванням того, що відрізок CD перетинати не можна.

3.22. Прочитати координати точок A, B, C, D і визначити, чи є замкнена ламана ABCDA:

А чотирикутником; б неопуклим чотирикутником; в опуклим чотирикутником.