Підпрограми (процедури і функції) h2>
При
вирішенні нових завдань можна спробувати скористатися раніше написаними
програмами. Алгоритм, розроблений раніше і цілком використовується в складі
інших алгоритмів, називається допоміжним. Застосування допоміжних
алгоритмів дозволяє розбити задачу на частини, структурувати її. p>
Вся
програма умовно може бути розділена на дві частини: основну і
допоміжну. В основній частині проводиться проста обробка інформації,
організується звернення до різних допоміжних модулів (підпрограм). p>
Допоміжний
алгоритм теж може викликати інші допоміжні, довжина такої ланцюжка
викликів теоретично не обмежена. Тут і далі наступні пари слів використовуються
як синоніми: алгоритм і програма, допоміжний алгоритм і підпрограма,
команда і оператор, програма і модуль. Допоміжними і основними алгоритми
є не самі по собі, а по відношенню один до одного. p>
При
використанні допоміжних алгоритмів необхідно враховувати спосіб передачі
значень вихідних даних для них і отримання результату від них. Аргументи
допоміжного алгоритму - це змінні, в яких повинні бути поміщені
вихідні дані для рішення відповідної підзадачі. Результати
допоміжного алгоритму - це також змінні, де міститися результати
вирішення цих подзадач, а також результатом може бути конкретна дія,
яка здійснює комп'ютер під дією підпрограми. p>
Підпрограми
можуть бути двох видів: підпрограма без параметрів і підпрограма з
параметрами. Звернення до підпрограмі може бути організовано з будь-якого місця
основної програми або іншої підпрограми скільки завгодно разів. p>
При
роботі з підпрограмами важливими є поняття формальних і фактичних
параметрів. Формальні параметри - це ідентифікатори вхідних даних для
підпрограми. Якщо формальні параметри отримують конкретні значення, то вони
називаються фактичними. Формальні параметри можуть отримати конкретні
значення тільки в тій програмі, де виробляється звернення до даного
модулю-підпрограмі. Тип і порядок запису фактичних параметрів повинні бути
такими ж, як і формальних параметрів. В іншому випадку результат роботи
програми буде непередбачуваним. З цього випливає, що фактичні параметри
використовуються при зверненні до підпрограмі з основної, а формальні параметри --
тільки в самому модулі. p>
Підпрограма
з параметрами використовується для запису багаторазово повторюваних дій при
різних вихідних даних. Підпрограми з параметрами можна розділити на два типи:
підпрограми-функції і просто підпрограми з параметрами (їх називають
процедурами). p>
При
складанні підпрограм з параметрами треба дотримуватися таких правил: p>
1)
кожна підпрограма має своє ім'я і список формальних параметрів; p>
2)
процедура з основної програми викликається командою виклику, яка за формою
нічим не відрізняється від виклику команди виконавця. Результат присвоюється
одній або декільком змінним, які знаходяться в списку формальних
параметрів. Але результатом може бути, звичайно, не тільки значення змінних,
але будь-яке дію, виконане ЕОМ. p>
Приклад
1. Використовуємо алгоритм знаходження найбільшого спільного дільника двох натуральних
чисел як допоміжний при вирішенні завдання: скласти програму віднімання
дробів (a, b, c, d - натуральні числа). Результат представити у вигляді
звичайної несократімой дробу. p>
Підпрограма. p>
1)
Ввести натуральні числа M, N. p>
2)
Якщо M = N, перейти до п. 5, інакше до наступного пункту. P>
3)
Якщо M> N, то M: = M-N, інакше N: = N-M. P>
4)
Перейти до п. 2. P>
5)
Надіслати значення M в основну програму. P>
6)
Кінець підпрограми. P>
Основна
програма. p>
1)
Ввести значення A, B, C, D. p>
2)
E: = A * D - B * C. p>
3)
F: = B * D. p>
4)
Якщо E = 0, вивести значення E і перейти до п. 9, інакше перейти до наступного
пункту. p>
5)
M: = | E |, N: = F, перейти до підпрограмі обчислення НОД. P>
6)
G: = M. p>
7)
E і F нацело розділити на G. p>
8)
Вивести значення E і F на друк. P>
9) Кінець програми. p>
Program Sub; p>
Var A, B, C, D, G, E, F: Integer; p>
Procedure Nod (M, N: Integer; Var K
: Integer); p>
Begin p>
While M N Do p>
If M> N Then M: = M - N Else N: = N - M; p>
K: = M p>
End; p>
Begin p>
Write ( 'Введіть чисельнику і знаменники
дробів :'); p>
ReadLn (A, B, C, D); p>
E: = A * D - B * C; p>
F: = B * D; p>
If E = 0 Then WriteLn (E) p>
Else p>
Begin p>
Nod (Abs (E), F, G); p>
E: = E Div G; p>
F: = F Div G; p>
WriteLn ( 'Відповідь:', E, '/', F) p>
End p>
End. p>
Як
видно з прикладу, оголошення і тіло підпрограм знаходиться в розділі описів. У
заголовку підпрограми міститься список формальних параметрів із зазначенням їх
типу, які умовно можна розділити на вхідні і вихідні (перед ними стоїть
службове Var). При зверненні до процедури вказується її ім'я і список
фактичних параметрів. Формальні і фактичні параметри повинні
відповідати по кількості і по типу. p>
Виклик
процедури здійснюється наступним чином: p>
(); p>
Наприклад, p>
Nod (Abs (E), F, G); p>
За
способу передачі фактичних значень в підпрограму в Turbo Pascal 7.0
виділяють параметри-змінні, параметри-значення, параметри-константи і
масиви відкритого типу, рядки відкритого типу, параметри-процедури,
параметри-функції (подробиці - в літературі). p>
Функція
(на відміну від процедури) завжди повертає єдине значення. p>
Покажемо,
як зміниться підпрограма з прикладу, якщо її записати у вигляді функції. p>
Function Nod (M, N: Integer):
Integer; p>
Begin p>
While M N Do p>
If M> N Then M: = M - N Else N: = N - M; p>
Nod: = M p>
End; p>
Отже,
після списку параметрів вказується тип значення функції, а в тілі функції хоча
б один раз зустрічається присвоювання змінної, ім'я якої збігається з ім'ям
функції, соотответствующего значення. p>
Виклик
функції буде наступним: p>
G: = Nod (Abs (E), F); p>
Взагалі,
виклик функції може бути присутнім у виразі, що стоїть: у правій частині
оператора присвоєння, у процедурі виводу, в якості фактичного параметра в
виклику іншої підпрограми і т.д. p>
При
вирішенні завдань доцільно проаналізувати умову, записати рішення в
великих блоках (що не є операторами Pascal), деталізувати кожен з
блоків (записав у вигляді блоків, можливо, як і раніше не операторів Pascal), і
т.д., продовжувати до тих пір, поки кожен з блоків не буде реалізований з
допомогою операторів мови. p>
Приклад
2. Дано натуральне число n. Переставити місцями першу і останню цифри цього
числа. p>
Program
Integ; p>
Var N: Integer; p>
Begin p>
Write ( 'Введіть натуральне число:'); p>
ReadLn (N); p>
If Impossible (N) p>
Then WriteLn ( 'Неможливо переставити цифри, виникне
переповнення ') p>
Else Begin p>
Change (N); p>
WriteLn ( 'Відповідь:', N) p>
End; p>
End. p>
Можна
помітити, що необхідно деталізувати логічну функцію Impossible, яка
діагностує, чи можлива перестановка, та процедуру Change, яка цю
перестановку (у випадку, якщо вона можлива) виконує. p>
Function Impossible (N: Integer):
Boolean; p>
Begin p>
If Number (N) <5 p>
Then Impossible: = False p>
Else Impossible: = (N Mod 10> 3) Or p>
(N Mod 10 = 3) And p>
(N Mod 10000 Div 10 * 10
+ N Div 10000> MaxInt Mod 10000) p>
End; p>
Тут
необхідно деталізувати функцію Number, повертає кількість цифр у записі
натурального числа (тому що функція Impossible містить її виклик, то в розділі
описів функція Number повинна передувати їй). p>
Function Number (N: Integer):
Integer; p>
Var Vsp: Integer; p>
Begin p>
Vsp: = 0; p>
While N> 0 Do p>
Begin p>
Vsp: = Vsp + 1; N: = N Div 10 p>
End; p>
Number: = Vsp p>
End; p>
Нарешті,
остання процедура. p>
Procedure Change (Var N: Integer); p>
Var Kol, P, S, R: Integer; p>
Begin p>
Kol: = Number (N); p>
P: = N Mod 10; (остання цифра) p>
If Kol> 1 Then p>
S: = N Div Round (Exp ((Kol - 1) * Ln (10 ))) p>
Else S: = 0; (перша цифра) p>
R: = N Mod Round (Exp ((Kol - 1) * Ln (10))) Div 10; p>
N: = P * Round (Exp ((Kol - 1) * Ln (10))) + R * 10 + S p>
End; p>
Можливі
також підпрограми, які викликають самі себе. Вони називаються рекурсивними.
Створення таких підпрограм є гарним прийомом програмування, але не
завжди доцільно через надмірне витрати пам'яті ЕОМ. p>
Приклад
3. Знайти максимальну цифру в запису даного натурального числа. P>
Program MaxDigit; p>
Type NaturLong = 1 .. (High (LongInt )); p>
Digit = 0 .. 9; p>
Var A: LongInt; p>
Function Maximum (N: LongInt):
Digit; p>
Begin p>
If N <10 p>
Then Maximum: = N p>
Else If N Mod 10> Maximum (N Div 10) p>
Then Maximum: = N mod 10 p>
Else Maximum: = Maximum (N Div 10) p>
End; p>
Begin p>
Write ( 'Введіть натуральне число:'); p>
ReadLn (A); p>
WriteLn ( 'Максимальна цифра дорівнює', Maximum (A)) p>
End. p>
При
створення функції Maximum було використане таке міркування: якщо число
складається з однієї цифри, то вона є максимальною, інакше якщо остання
цифра не є максимальною, то її слід шукати серед інших цифр числа.
При написанні рекурсивного алгоритму слід подбати про граничний умови,
коли ланцюжок рекурсивних викликів обривається і починається її зворотне
«Розкручування». У нашому прикладі ця умова N <10. P>
Більше
Детальніше про рекурсії йдеться у статті. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту
http://comp-science.narod.ru p>